在HTML帮助器中生成URL


168

通常,在ASP.NET视图中,可以使用以下函数来获取URL(而不是<a>):

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

但是,我无法从自定义HTML帮助程序中找到方法。我有

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

helper变量具有Action和GenerateLink方法,但是它们生成<a>的。我在ASP.NET MVC源代码中做了一些挖掘,但是找不到直接的方法。

问题在于上面的Url是视图类的成员,并且对于其实例化,它需要一些上下文和路由映射(我不想处理它们,无论如何也不应这样做)。另外,HtmlHelper类的实例还具有一些上下文,我认为它们是Url实例的上下文信息的子集的晚餐(但我不想再处理它)。

总而言之,我认为这是有可能的,但是由于我能看到的所有方式都涉及对内部ASP.NET或多或少的某些操作,因此我想知道是否有更好的方法。

编辑:例如,我看到的一种可能性是:

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

但这似乎不对。我不想自己处理UrlHelper的实例。必须有一个更简单的方法。


3
我意识到这是一个简化的示例,但是对于所示示例,我将扩展UrlHelper而不是HtmlHelper。但是,您的实际代码可能同时需要两者。
Craig Stuntz 09年

抱歉,我应该更加清楚:我想在扩展方法中进行一些HTML渲染,并且需要为其生成URL。
1

Answers:


217

您可以在html helper扩展方法中创建如下的url helper:

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

2
我认为如果构造函数还初始化RouteCollection会更好new UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection)
kpull1

22

您还可以使用UrlHelperpublic和static类获取链接:

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

在此示例中,您不必创建新的UrlHelper类,这可能会有一点优势。


我更喜欢此答案,因为设置了RouteCollection。
kpull1

10

这里是让我的小extenstion方法UrlHelper一的HtmlHelper实例:

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

用作:

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

(我将其发布为仅供参考)


出色的方法,因为它可以重用现有对象而不是创建新对象。
Mike

我们正在使用ASP.NET 4.5,并且遇到了重新输入问题。我们认为UrlHelper在所有HTTP请求中均不可重用。请注意。
卡尔在't Veld '18年
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.