Phương pháp HTML.ActionLink


249

Hãy nói rằng tôi có một lớp học

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

Trên một trang không nằm trong thư mục Item, nơi ItemControllercư trú, tôi muốn tạo một liên kết đến Loginphương thức. Vậy Html.ActionLinktôi nên sử dụng phương pháp nào và những thông số nào cần vượt qua?

Cụ thể, tôi đang tìm kiếm sự thay thế của phương pháp

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

đã được nghỉ hưu trong phiên bản ASP.NET MVC gần đây.


17
Tài liệu, cho bất cứ ai tìm kiếm nó: msdn.microsoft.com/en-us/library/...
BlueRaja - Danny Pflughoeft

@Danny Cảm ơn, đã tìm kiếm nó trên Google khi tôi kết thúc ở đây.
Rei Miyasaka

Câu trả lời:


491

Tôi nghĩ những gì bạn muốn là đây:

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

Điều này sử dụng phương pháp chữ ký ActionLink sau đây:

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

ASP.NET MVC2

hai đối số đã được chuyển đổi xung quanh

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

Điều này sử dụng phương pháp chữ ký ActionLink sau đây:

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

ASP.NET MVC3 +

các đối số theo cùng thứ tự với MVC2, tuy nhiên giá trị id không còn bắt buộc:

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

Điều này tránh mã hóa cứng bất kỳ logic định tuyến vào liên kết.

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

Điều này sẽ cung cấp cho bạn đầu ra html sau, giả sử:

  1. article.Title = "Title"
  2. article.ArticleID = 5
  3. bạn vẫn có tuyến đường sau được xác định

. .

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

7
Nhưng, điều này không đưa ra một URL như / Mục / Đăng nhập? Id = 5?
Adhip Gupta

21
Điều kỳ lạ là nếu bạn bỏ lỡ tham số cuối cùng, nó sẽ bổ sung cho tôi? Độ dài = 8 cho hành động hiện tại
Chris S

32
@Chris S - Tôi biết đây là một bài viết cũ, nhưng lý do cho? Độ dài = 8 là vì bạn cần phải có một , nulltham số SAU new { ... }... bởi vì nếu bạn kiểm tra sự quá tải của phương thức đó, nó nghĩ rằng các thông số của bạn là htmlArgument ... không phải là đối số tuyến đường. Để sử dụng phương thức đúng , bạn cần sử dụng phương thức có routeArguments, htmlArguments.. vì vậy chỉ cần truyền vào null cho lần cuối htmlArgument. Đoạn mã đầu tiên trong bài trả lời này có nó. Tôi đã cập nhật bài đăng này để bạn có thể thấy nó dễ dàng (ví dụ: nó không cuộn).
Pure.Krom

7
Có ai đã thử điều này với MVC 3 chưa? Có vẻ như các dòng ControllerName và ActionMethod trong mẫu ở trên được lật. Bất cứ ai khác nhìn thấy điều đó?
Steve Duitsman

8
Trong MVC3, không tìm thấy thuộc tính id ... thay vào đó nên sử dụng các mục sau:@Html.ActionLink("Text","Action","Controller", new { item.ID }, null)
Gavin Coates

30

Tôi muốn thêm vào câu trả lời của Joseph Kingry . Anh ấy đã cung cấp giải pháp nhưng ban đầu tôi cũng không thể làm cho nó hoạt động được và có kết quả giống như Adhip Gupta. Và sau đó tôi nhận ra rằng tuyến đường phải tồn tại ở vị trí đầu tiên và các tham số cần khớp chính xác với tuyến đường. Vì vậy, tôi đã có một id và sau đó là một tham số văn bản cho tuyến đường của tôi cũng cần được đưa vào.

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

4
Đây chỉ là những gì tôi cần - tôi đã quên thêm đối số null cuối cùng . Cảm ơn.
Ian Oxley

1
Cảm ơn vì đã hiển thị ánh xạ từ tên tham số tuyến đường (ví dụ: {id = ..., bar = ...}.
William Rose

17

Bạn có thể muốn xem phương thức RouteLink(). Điều đó cho phép bạn chỉ định mọi thứ (ngoại trừ văn bản liên kết và tên tuyến đường) thông qua một từ điển.


4
Sẽ thật tuyệt khi thấy một ví dụ về cách giải quyết vấn đề đó; trang MSDN có quá nhiều tình trạng quá tải và biết những gì cần tìm có thể gây nhầm lẫn
Simon Martin

14

Tôi nghĩ rằng Joseph lật điều khiển và hành động. Đầu tiên là hành động sau đó là bộ điều khiển. Điều này hơi lạ, nhưng cách chữ ký trông.

Chỉ cần làm rõ mọi thứ, đây là phiên bản hoạt động (thích ứng với ví dụ của Joseph):

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

11

cái này thì sao

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

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

Đây thực sự nên được đánh dấu là câu trả lời vì nó thực hiện chính xác những gì người hỏi đang tìm kiếm ... tuy nhiên tôi sẽ lưu ý rằng câu trả lời được đánh dấu đã đi sâu vào một chi tiết tuyệt vời cho người dùng trong việc thiết lập chính xác các tuyến đường trong các phiên bản khác nhau của MVC.
Indy-Jones

9

Nếu bạn muốn đi tất cả các loại quần ưa thích, đây là cách bạn có thể mở rộng nó để có thể làm điều này:

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

Bạn sẽ cần đặt cái này trong System.Web.Mvckhông gian tên:

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

Điều này bao gồm hai phần ghi đè cho Route ValuesHTML Attributes, đồng thời, tất cả các chế độ xem của bạn sẽ cần thêm: @using YourProject.Controllershoặc bạn có thể thêm nó vàoweb.config <pages><namespaces>


1
Tôi ngạc nhiên hơn không sử dụng phương pháp này. Có vẻ rất nguy hiểm khi sử dụng chuỗi ký tự trên toàn bộ trong chế độ xem của bạn để thể hiện bộ điều khiển / hành động.
Johnathon Sullinger

Đã tìm kiếm điều này cả đời tôi
Worthy7

Đã thử điều này, đã không làm việc. Đã cho tôi một chuỗi trống cuối cùng - Tôi giả sử vì tôi có các tham số trong các chức năng của mình.
Worthy7

Bạn có thể đăng một github hoặc địa điểm khác với mã này để tôi có thể xem và xem tại sao nó không hoạt động cho bạn?
Serj Sagan

2
Sử dụng tốt đẹp của từ Fancypants. Chúng tôi không thấy đủ.
gdbj

7

Sử dụng các tham số được đặt tên để dễ đọc và để tránh nhầm lẫn.

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

1

Với MVC5 tôi đã làm nó như thế này và nó là mã làm việc 100% ....

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

Các bạn có thể có một ý tưởng từ ...


0

Loại này sử dụng:

@ Html.ActionLink ("MainPage", "Chỉ mục", "Trang chủ")

MainPage: Tên của văn bản Chỉ mục: Action View Home: HomeContoder

Cơ sở sử dụng 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>

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.