Tạo URL trong trình trợ giúp HTML


168

Thông thường trong chế độ xem ASP.NET, người ta có thể sử dụng chức năng sau để lấy URL (không phải là <a>):

Url.Action("Action", "Controller");

Tuy nhiên, tôi không thể tìm thấy cách thực hiện từ trình trợ giúp HTML tùy chỉnh. Tôi có

public class MyCustomHelper
{
   public static string ExtensionMethod(this HtmlHelper helper)
   {
   }
}

Biến của trình trợ giúp có các phương thức Action và GenerateLink, nhưng chúng tạo ra <a>. Tôi đã thực hiện một số hoạt động đào mã nguồn ASP.NET MVC, nhưng tôi không thể tìm thấy một cách đơn giản.

Vấn đề là Url ở trên là một thành viên của lớp khung nhìn và để khởi tạo nó, nó cần một số bối cảnh và bản đồ tuyến đường (mà tôi không muốn xử lý và dù sao tôi cũng không nên làm vậy). Ngoài ra, thể hiện của lớp HtmlHelper cũng có một số bối cảnh mà tôi giả sử là siêu tập hợp thông tin ngữ cảnh của cá thể Url (nhưng một lần nữa tôi không muốn xử lý nó).

Tóm lại, tôi nghĩ là có thể nhưng vì tất cả các cách tôi có thể nhìn thấy, liên quan đến một số thao tác với một số công cụ ASP.NET nội bộ ít nhiều, tôi tự hỏi liệu có cách nào tốt hơn không.

Chỉnh sửa: Chẳng hạn, một khả năng tôi thấy sẽ là:

public class MyCustomHelper
{
    public static string ExtensionMethod(this HtmlHelper helper)
    {
        UrlHelper urlHelper = new UrlHelper(helper.ViewContext.RequestContext);
        urlHelper.Action("Action", "Controller");
    }
}

Nhưng nó có vẻ không đúng. Tôi không muốn tự mình xử lý các trường hợp của UrlHelper. Nó phải là một con đường dễ dàng hơn.


3
Tôi nhận ra đây là một ví dụ đơn giản, nhưng với ví dụ được hiển thị, tôi sẽ mở rộng UrlHelper thay vì HtmlHelper. Mã thực sự của bạn có thể cần cả hai, mặc dù.
Craig Stuntz

Xin lỗi, tôi nên nói rõ hơn: Tôi muốn thực hiện một số kết xuất HTML trong phương thức tiện ích mở rộng và tôi cần tạo URL cho nó.
Jan Zich

Câu trả lời:


217

Bạn có thể tạo trình trợ giúp url như thế này bên trong phương thức mở rộng trình trợ giúp html:

var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
var url = urlHelper.Action("Home", "Index")

2
Tôi nghĩ rằng sẽ tốt hơn nếu nhà xây dựng cũng khởi tạo RouteCollectionnew UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection)
kpull1

22

Bạn cũng có thể nhận được các liên kết bằng cách sử dụng UrlHelperlớp công khai và tĩnh:

UrlHelper.GenerateUrl(null, actionName, controllerName, null, null, null, routeValues, htmlHelper.RouteCollection, htmlHelper.ViewContext.RequestContext, true)

Trong ví dụ này, bạn không phải tạo lớp UrlHelper mới, đây có thể là một lợi thế nhỏ.


Tôi thích câu trả lời này hơn vì đặt RouteCollection.
kpull1

10

Đây là phương pháp extenstion nhỏ của tôi để lấy UrlHelpermột HtmlHelperthể hiện:

  public static partial class UrlHelperExtensions
    {
        /// <summary>
        /// Gets UrlHelper for the HtmlHelper.
        /// </summary>
        /// <param name="htmlHelper">The HTML helper.</param>
        /// <returns></returns>
        public static UrlHelper UrlHelper(this HtmlHelper htmlHelper)
        {
            if (htmlHelper.ViewContext.Controller is Controller)
                return ((Controller)htmlHelper.ViewContext.Controller).Url;

            const string itemKey = "HtmlHelper_UrlHelper";

            if (htmlHelper.ViewContext.HttpContext.Items[itemKey] == null)
                htmlHelper.ViewContext.HttpContext.Items[itemKey] = new UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection);

            return (UrlHelper)htmlHelper.ViewContext.HttpContext.Items[itemKey];
        }
    }

Sử dụng nó như:

public static MvcHtmlString RenderManagePrintLink(this HtmlHelper helper, )
{    
    var url = htmlHelper.UrlHelper().RouteUrl('routeName');
    //...
}

(Tôi đang đăng bài này chỉ để tham khảo)


Cách tiếp cận tuyệt vời vì nó sử dụng lại một đối tượng hiện có thay vì tạo một đối tượng mới.
Mike

Chúng tôi đang sử dụng ASP.NET 4.5 và đã gặp phải sự cố nhập lại. Chúng tôi không tin rằng UrlHelper có thể tái sử dụng trên các yêu cầu http. Xin hãy chú ý.
Carl trong 't Veld
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.