【问题标题】:HTML.ActionLink methodHTML.ActionLink 方法
【发布时间】:2008-10-14 09:16:58
【问题描述】:

假设我有一堂课

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

在不位于 ItemController 所在的 Item 文件夹的页面上,我想创建指向 Login 方法的链接。那么我应该使用哪个Html.ActionLink方法,应该传递哪些参数呢?

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

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

在最近的 ASP.NET MVC 化身中已停用。

【问题讨论】:

标签: c# .net asp.net-mvc html-helper actionlink


【解决方案1】:

我想你想要的是这样的:

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
);

【讨论】:

  • 但是,这不是给出像 /Item/Login?id=5 这样的 URL 吗?
  • 奇怪的是,如果你错过了最后一个参数,它会为我附加 ?Length=8 到当前操作
  • @Chris S - 我知道这是一篇旧帖子,但 ?Length=8 的原因是因为你需要在 new { ... } 之后有一个 , null 参数...因为如果您检查该方法的重载,它认为您的参数是 htmlArguments ...不是路由参数。要使用 正确 方法,您需要使用具有routeArguments, htmlArguments 的方法。所以只需为最后一个htmlArgument 传递null。此回复中的第一段代码有它。我已经更新了这篇文章,所以你可以很容易地看到(即它不会滚动)。
  • 有人用 MVC 3 试过这个吗?上面示例中的 ControllerName 和 ActionMethod 行似乎颠倒了。其他人看到了吗?
  • 在 MVC3 中找不到 id 属性...应该改用以下内容:@Html.ActionLink("Text","Action","Controller", new { item.ID }, null)
【解决方案2】:

我想添加到Joseph Kingry's answer。他提供了解决方案,但起初我也无法让它发挥作用,得到的结果就像 Adhip Gupta 一样。然后我意识到路线必须首先存在,并且参数需要与路线完全匹配。所以我有一个 id,然后是我的路由的文本参数,也需要包含在内。

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

【讨论】:

  • 这正是我所需要的——我忘记添加最后的 null 参数。谢谢。
  • 感谢您显示路由参数名称的映射(例如 new { id = ..., bar = ... }。
  • 检查这个:codingfusion.com/Post/…
【解决方案3】:

您可能想查看RouteLink() 方法。该方法可让您通过字典指定所有内容(链接文本和路由名称除外)。

【讨论】:

  • 很高兴看到如何解决问题的示例; MSDN 页面有很多重载,知道要查找的内容可能会令人困惑
【解决方案4】:

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

澄清一下,这是有效的版本(改编自约瑟夫的示例):

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

【讨论】:

    【解决方案5】:

    这个呢

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

    【讨论】:

      【解决方案6】:
      Html.ActionLink(article.Title, "Login/" + article.ArticleID, 'Item") 
      

      【讨论】:

      • 这确实应该被标记为答案,因为它完全符合提出问题的人正在寻找的内容......但是我会注意到标记的答案确实为用户提供了非常详细的信息在不同版本的 MVC 中正确设置路由。
      【解决方案7】:

      如果您想穿上所有花哨的裤子,可以通过以下方式扩展它以使其能够做到这一点:

      @(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 &lt;pages&gt;&lt;namespaces&gt;

      【讨论】:

      • 我很惊讶不要使用这种方法。在视图中使用字符串文字来表示控制器/动作似乎真的很危险。
      • 这辈子都在找这个
      • 试过了,没用。最后给了我一个空白字符串 - 我假设因为我的函数中有参数。
      • 您能否在 github 或其他地方发布此代码,以便我看看为什么它不适合您?
      • fancypants 这个词很好用。我们看到的还不够。
      【解决方案8】:

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

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

      【讨论】:

        【解决方案9】:

        使用 MVC5 我已经这样做了,它是 100% 工作代码....

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

        你们可以从中得到一个想法......

        【讨论】:

          【解决方案10】:

          这种类型使用:

          @Html.ActionLink("MainPage","Index","Home")

          MainPage : 文本名称 索引 : 动作视图 主页 : 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>

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多