HTML.ActionLink方法


249

假设我有一堂课

public class ItemController:Controller
{
    public ActionResult Login(int id)
    {
        return View("Hi", id);
    }
}

在不位于“项目”文件夹ItemController所在的页面上,我想创建该Login方法的链接。那么Html.ActionLink我应该使用哪种方法以及应该传递什么参数呢?

具体来说,我正在寻找方法的替代品

Html.ActionLink(article.Title,
    new { controller = "Articles", action = "Details",
          id = article.ArticleID })

在最近的ASP.NET MVC版本中已停用。



@Danny谢谢,我到这里来时一直在Google上寻找它。
宫阪丽

Answers:


491

我认为您想要的是:

ASP.NET MVC1

Html.ActionLink(article.Title, 
                "Login",  // <-- Controller Name.
                "Item",   // <-- ActionMethod
                new { id = article.ArticleID }, // <-- Route arguments.
                null  // <-- htmlArguments .. which are none. You need this value
                      //     otherwise you call the WRONG method ...
                      //     (refer to comments, below).
                )

这使用以下方法ActionLink签名:

public static string ActionLink(this HtmlHelper htmlHelper, 
                                string linkText,
                                string controllerName,
                                string actionName,
                                object values, 
                                object htmlAttributes)

ASP.NET MVC2

两个参数已经改变

Html.ActionLink(article.Title, 
                "Item",   // <-- ActionMethod
                "Login",  // <-- Controller Name.
                new { id = article.ArticleID }, // <-- Route arguments.
                null  // <-- htmlArguments .. which are none. You need this value
                      //     otherwise you call the WRONG method ...
                      //     (refer to comments, below).
                )

这使用以下方法ActionLink签名:

public static string ActionLink(this HtmlHelper htmlHelper, 
                                string linkText,
                                string actionName,
                                string controllerName,
                                object values, 
                                object htmlAttributes)

ASP.NET MVC3 +

参数与MVC2的顺序相同,但是不再需要id值:

Html.ActionLink(article.Title, 
                "Item",   // <-- ActionMethod
                "Login",  // <-- Controller Name.
                new { article.ArticleID }, // <-- Route arguments.
                null  // <-- htmlArguments .. which are none. You need this value
                      //     otherwise you call the WRONG method ...
                      //     (refer to comments, below).
                )

这样可以避免将任何路由逻辑硬编码到链接中。

 <a href="/Item/Login/5">Title</a> 

假定以下内容,这将为您提供以下html输出:

  1. article.Title = "Title"
  2. article.ArticleID = 5
  3. 您仍然定义了以下路线

。。

routes.MapRoute(
    "Default",     // Route name
    "{controller}/{action}/{id}",                           // URL with parameters
    new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
);

7
但是,这不给出类似/ Item / Login?id = 5的URL吗?
Adhip Gupta,

21
奇怪的是,如果您错过了最后一个参数,它会为我添加当前动作的长度吗?Length = 8
Chris S

32
@Chris S-我知道这是一篇旧文章,但是?Length = 8的原因是因为您需要, nullnew { ... }... 之后添加一个参数,因为如果您检查该方法的重载,它会认为您的参数是htmlArguments ...不路由参数。要使用正确的方法,您需要使用具有routeArguments, htmlArguments.. 的方法,因此只需为该last输入null即可htmlArgument。此回复中的第一段代码包含它。我更新了这篇文章,以便您可以轻松看到(即,它不会滚动)。
Pure.Krome

7
有人尝试过使用MVC 3吗?上面的示例中的ControllerName和ActionMethod行似乎被翻转了。还有其他人看到吗?
史蒂夫·杜伊斯曼

8
在MVC3中找不到id属性...应改用以下属性:@Html.ActionLink("Text","Action","Controller", new { item.ID }, null)
Gavin Coates

30

我想补充约瑟夫·金里的答案。他提供了解决方案,但起初我也无法使它正常工作,并且得到了与Adhip Gupta一样的结果。然后我意识到路由必须首先存在,并且参数必须与路由完全匹配。因此,我有一个ID,然后是我的路线的文本参数,该参数也需要包含在内。

Html.ActionLink(article.Title, "Login", "Item", new { id = article.ArticleID, title = article.Title }, null)

4
这正是我所需要的-我忘了添加最终的null参数。谢谢。
伊恩·奥克斯利

1
谢谢显示映射从路线参数名称,太(如新的{ID = ...,酒吧= ...}。
威廉·罗斯

17

您可能需要看一下这种RouteLink()方法,该方法可以让您通过字典指定所有内容(链接文本和路由名称除外)。


4
看到如何解决该问题的示例将非常高兴;MSDN页面上有很多重载,并且知道要查找的内容可能会造成混淆
Simon Martin

14

我认为约瑟夫推翻了控制器和行动。首先是动作,然后是控制器。这有点奇怪,但是签名的样子。

只是为了澄清一下,这是可行的版本(适应约瑟夫的例子):

Html.ActionLink(article.Title, 
    "Login",  // <-- ActionMethod
    "Item",   // <-- Controller Name
    new { id = article.ArticleID }, // <-- Route arguments.
    null  // <-- htmlArguments .. which are none
    )

11

那这个呢

<%=Html.ActionLink("Get Involved", 
                   "Show", 
                   "Home", 
                   new 
                       { 
                           id = "GetInvolved" 
                       }, 
                   new { 
                           @class = "menuitem", 
                           id = "menu_getinvolved" 
                       }
                   )%>

10
Html.ActionLink(article.Title, "Login/" + article.ArticleID, 'Item") 

确实应该将其标记为答案,因为它确实可以满足询问该问题的人的需求...但是,我会注意到标记的答案确实为用户提供了详细的信息,从而可以正确设置各种版本的路线MVC。
Indy-Jones

9

如果您想穿所有花式裤子,可以按照以下方法进行扩展:

@(Html.ActionLink<ArticlesController>(x => x.Details(), article.Title, new { id = article.ArticleID }))

您需要将其放在System.Web.Mvc名称空间中:

public static class MyProjectExtensions
{
    public static MvcHtmlString ActionLink<TController>(this HtmlHelper htmlHelper, Expression<Action<TController>> expression, string linkText)
    {
        var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection);

        var link = new TagBuilder("a");

        string actionName = ExpressionHelper.GetExpressionText(expression);
        string controllerName = typeof(TController).Name.Replace("Controller", "");

        link.MergeAttribute("href", urlHelper.Action(actionName, controllerName));
        link.SetInnerText(linkText);

        return new MvcHtmlString(link.ToString());
    }

    public static MvcHtmlString ActionLink<TController, TAction>(this HtmlHelper htmlHelper, Expression<Action<TController, TAction>> expression, string linkText, object routeValues)
    {
        var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection);

        var link = new TagBuilder("a");

        string actionName = ExpressionHelper.GetExpressionText(expression);
        string controllerName = typeof(TController).Name.Replace("Controller", "");

        link.MergeAttribute("href", urlHelper.Action(actionName, controllerName, routeValues));
        link.SetInnerText(linkText);

        return new MvcHtmlString(link.ToString());
    }

    public static MvcHtmlString ActionLink<TController>(this HtmlHelper htmlHelper, Expression<Action<TController>> expression, string linkText, object routeValues, object htmlAttributes) where TController : Controller
    {
        var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection);

        var attributes = AnonymousObjectToKeyValue(htmlAttributes);

        var link = new TagBuilder("a");

        string actionName = ExpressionHelper.GetExpressionText(expression);
        string controllerName = typeof(TController).Name.Replace("Controller", "");

        link.MergeAttribute("href", urlHelper.Action(actionName, controllerName, routeValues));
        link.MergeAttributes(attributes, true);
        link.SetInnerText(linkText);

        return new MvcHtmlString(link.ToString());
    }

    private static Dictionary<string, object> AnonymousObjectToKeyValue(object anonymousObject)
    {
        var dictionary = new Dictionary<string, object>();

        if (anonymousObject == null) return dictionary;

        foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(anonymousObject))
        {
            dictionary.Add(propertyDescriptor.Name, propertyDescriptor.GetValue(anonymousObject));
        }

        return dictionary;
    }
}

这包括两个覆盖的Route ValuesHTML Attributes也,你所有的观点都需要补充:@using YourProject.Controllers或者你可以把它添加到您的web.config <pages><namespaces>


1
我更惊讶不使用这种方法。在视图中全部使用字符串文字来表示控制器/动作似乎很危险。
Johnathon Sullinger 2014年

一生都在寻找
Worthy7 '16

尝试了一下,没有用。最后给我一个空白字符串-我想是因为我的函数中有参数。
Worthy7 2016年

您可以使用此代码发布github或其他地方,以便让我看看为什么它不适合您吗?
Serj Sagan

2
很好地使用fancypants一词。我们还不够。
gdbj

7

使用命名参数以提高可读性并避免混淆。

@Html.ActionLink(
            linkText: "Click Here",
            actionName: "Action",
            controllerName: "Home",
            routeValues: new { Identity = 2577 },
            htmlAttributes: null)

1

使用MVC5,我已经做到了,它是100%的工作代码...。

@Html.ActionLink(department.Name, "Index", "Employee", new { 
                            departmentId = department.DepartmentID }, null)

你们可以从中得到一个主意...


0

此类型使用:

@ Html.ActionLink(“ MainPage”,“ Index”,“ Home”)

MainPage:文本名称索引:Action View主页:HomeController

基本用途ActionLink

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>_Layout</title>
    <link href="@Url.Content("~/Content/bootsrap.min.css")" rel="stylesheet" type="text/css" />
</head>
<body>
    <div class="container">
        <div class="col-md-12">
            <button class="btn btn-default" type="submit">@Html.ActionLink("AnaSayfa","Index","Home")</button>
            <button class="btn btn-default" type="submit">@Html.ActionLink("Hakkımızda", "Hakkimizda", "Home")</button>
            <button class="btn btn-default" type="submit">@Html.ActionLink("Iletişim", "Iletisim", "Home")</button>
        </div> 
        @RenderBody()
        <div class="col-md-12" style="height:200px;background-image:url(/img/footer.jpg)">

        </div>
    </div>
</body>
</html>

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.