Tại sao Html.ActionLink kết xuất lại?


305

Tôi rất bối rối về lý do tại sao mã này

Html.ActionLink("About", "About", "Home", new { hidefocus = "hidefocus" })

kết quả trong liên kết này:

<a hidefocus="hidefocus" href="/Home/About?Length=4">About</a>

Một hidefocusphần là những gì tôi đã nhắm đến để đạt được, nhưng ?Length=4nguồn gốc từ đâu?


4
Hành vi này cũng xuất hiện với các phương thức Html.BeginForm ().
Jonathon Watney

Câu trả lời:


326

Độ dài = 4 đến từ một nỗ lực nối tiếp một đối tượng chuỗi. Mã của bạn đang chạy ActionLinkphương thức này :

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

Cái này lấy một stringđối tượng "Home" cho routeValues, mà hệ thống ống nước MVC tìm kiếm các thuộc tính công cộng biến chúng thành giá trị của tuyến. Trong trường hợp của một stringđối tượng, thuộc tính công cộng duy nhất là Lengthvà vì sẽ không có tuyến đường nào được xác định bằng tham số Độ dài, nó sẽ nối thêm tên và giá trị thuộc tính làm tham số chuỗi truy vấn. Bạn có thể sẽ thấy nếu bạn chạy cái này từ một trang không có trên HomeControllerđó sẽ đưa ra lỗi về một Aboutphương thức hành động bị thiếu . Hãy thử sử dụng như sau:

Html.ActionLink("About", "About", new { controller = "Home" }, new { hidefocus = "hidefocus" })

@Bmus_Blah những ngày này tôi hoàn toàn không sử dụng cái này, thích viết các thẻ <a> của riêng tôi và chỉ sử dụng Url.Action ("Hành động", "Trình điều khiển")
roryf

@roryf không phải lo lắng ... điều này đã được sử dụng trong đánh giá mã như một cách thực hành tốt nhất, họ đã không kiểm tra ngày. Thực sự nên có một cách để lọc
luồng

Câu trả lời chính xác. Chỉ cần thêm điều này cũng xảy ra trên Html.BeginRouteForm vì lý do tương tự. Html.BeginRouteForm ("Tuyến đường", "Hành động", FormMethod.Post)) phải là Html.BeginRouteForm ("Tuyến đường", {action = "AgentSignUp"}, FormMethod.Post) mới thoát khỏi điều kỳ lạ
radm4

Cũng xảy ra với Url.Action(). Thay đổi từ Url.Action("Action", "Controller", new { area = "" })để Url.Action("Action", new { controller = "Controller", area = "" })giữ cho thuộc tính Độ dài hiển thị.
John Washam

Để tránh những loại tình huống, bạn luôn có thể xác định những thông số bạn đang đi qua, như:Html.ActionLink("About", "About", "Home", routeValues: null, htmlAttributes: new { hidefocus = "hidefocus" })
Epiplon

195

Cách tôi giải quyết điều này là thêm null vào tham số thứ tư trước khi khai báo ẩn danh ( new {}) để nó sử dụng quá tải phương thức sau: (linkText, actionName, controlName, routeValues, htmlAttribution):

Html.ActionLink("About", "About", "Home", null, new { hidefocus = "hidefocus" })

Đây là câu trả lời tốt nhất nếu bạn không liên kết giữa các khu vực. Nếu bạn cần chỉ định khu vực cho liên kết, bạn sẽ cần chỉ định tuyếnValues ​​với controllerareađể giữ thuộc tính Độ dài hiển thị trong URL.
John Washam

@JohnWasham Trên thực tế, bạn không cần chỉ định bộ điều khiển trong routeValuesnhưng chỉ khu vực. Ví dụ:Html.ActionLink("About", "About", "Home", new {@area = "Admin"}, new { hidefocus = "hidefocus" })
Epiplon 13/03/2015

1
@epiplon, lý do tôi chỉ định bộ điều khiển như vậy là vì nếu bạn không bao gồm htmlAttribution làm đối số cuối cùng ActionLink, MVC sẽ bao gồm một Length=xtham số lạ ở cuối URL. Chẳng hạn, đặt cái này lên một trang, sau đó xem nguồn của trang của bạn và bạn sẽ thấy ý tôi là: @Html.ActionLink("About", "About", "Home", new { area = "Admin" }, new { hidefocus = "hidefocus" }) @Html.ActionLink("About", "About", "Home", new { area = "Admin" }) Nhưng nếu bạn đặt controllermục nhập vào routeValues, nó sẽ không bao giờ đặt Length=xURL.
John Washam

@epiplon, bạn cũng không cần phải sử dụng @trong @area = "Admin", chỉ để bạn biết.
John Washam

88

Bạn đã quên thêm parm HTMLAttribut.

Điều này sẽ hoạt động mà không có bất kỳ thay đổi:

Html.ActionLink("About", "About", "Home", new { hidefocus = "hidefocus" },null)

Tôi không biết, tại sao điều này không hiệu quả với tôi. Tôi đã thử với "new {hidef Focus =" "}", và điều này hiệu quả với tôi.
Naredla Nithesh Reddy

28

Các tham số cho ActionLink không chính xác, nó đang cố sử dụng giá trị "Trang chủ" làm giá trị tuyến đường, thay vì loại ẩn danh.

Tôi tin rằng bạn chỉ cần thêm new { }hoặc nulllà tham số cuối cùng.

EDIT: Chỉ cần đọc lại bài đăng và nhận ra bạn có thể muốn chỉ định null là tham số cuối cùng thứ hai, không phải cuối cùng.


1
BTW Họ nên xóa một phương thức vì không thể sử dụng nó!
Marc Climent

5
Html.ActionLink("About", "About", "Home", new { hidefocus = "hidefocus" }, new { })

Điều này sẽ làm quá tải: chuỗi linkText, chuỗi actionName, chuỗi controlName, Object routeValues, Object htmlAttribut


3

Vui lòng sử dụng phương pháp quá tải đúng với năm (5) tham số. Thí dụ:

@using (@Ajax.BeginForm("Register", "Account", null,
    new AjaxOptions
    {
        HttpMethod = "POST",
        OnSuccess = "OnSuccess",
        OnFailure = "OnFailure",
        OnBegin = "OnBegin",
        OnComplete = "OnComplete"
    }, new { @class = "form-login" }))

thêm null sau tên bộ điều khiển là hữu ích trong trường hợp của tôi.
Munam Yousuf

Đây thực sự là câu trả lời giống như câu trả lời của @ Jesse với phần thưởng bổ sung mà nó bao gồm phiên bản Ajax, đây không phải là những gì OP yêu cầu, nhưng nó có liên quan đến cùng một vấn đề.
gcoulby

2

Chỉ cần xóa "Trang chủ" (tên của bộ điều khiển) để mã sẽ là:

Html.ActionLink("About", "About", new { hidefocus = "hidefocus" })

1

Với tên thuộc tính:

 @Html.ActionLink(linkText: "SomeText", actionName: "SomeAction", controllerName: "SomeControllerName", routeValues: new { parameterName = parameterValue}, htmlAttributes: null)

0

Như Jonathon Watney đã chỉ ra trong một bình luận, điều này cũng đúng

Html.BeginForm ()

phương pháp. Trong trường hợp của tôi, tôi đã ở trong một Creat.cshtml nhắm mục tiêu yêu cầu bài đăng của bộ điều khiển tương ứng + Tạo hành động và đã

using (Html.BeginForm("Create")) {
  @Html.AntiForgeryToken()
  ...
}

đã thêm chuỗi truy vấn "? length = 6" vào hành động biểu mẫu khi được hiển thị. Được gợi ý bởi câu trả lời được phê duyệt của roryf và nhận ra độ dài chuỗi của "Tạo" là 6, cuối cùng tôi đã giải quyết điều này bằng cách xóa đặc tả hành động rõ ràng:

using (Html.BeginForm()) {
      @Html.AntiForgeryToken()
      ...
    }

0

Có lẽ những người khác có cùng một vấn đề và cần cung cấp một giá trị lớp thông qua parm HTMLAttribut . Đây là giải pháp của tôi:

@Html.ActionLink("About", "About", new { controller = "Home", area = "" }, new { hidefocus = "hidefocus", @class = "nav-item nav-link" })


0

Tìm kiếm câu trả lời cho câu hỏi của tôi đã đưa tôi đến đây, về cơ bản đó là lựa chọn quá tải chính xác trong @Html.ActionLink nhập mô tả hình ảnh ở đây đó có vấn đề.
Tôi đã chọn một tình trạng quá tải mà không tồn tại, ( mà không cần sự cuối cùng null ), và MVCkhông có tình trạng quá tải như vậy, kết quả là một cái gì đó URL sai như OP đề cập.

Lưu ý cá nhân : bạn có thể useloại ẩn danh không có nghĩa là bạn có thể sử dụng bất kỳ tình trạng quá tải nào - không tồn tại? - chắc chắn: phải được xác định!
- Đến đây trong thời gian của MVC 5.2

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.