在 Application_BeginRequest() 中使用 UrlHelper

Using UrlHelper in Application_BeginRequest()

我需要在 Application_BeginRequest() 中调用 UrlHelper 以在应用程序的其他位置设置一些 URL 值。但是当我这样称呼它时:

var urlHelper = new UrlHelper();
urlHelper.Action(MVC.Bands.Index())

(我正在使用 T4MVC,所以这就是 MVC.Bands.Index() 部分的来源,最终 returns 一个 ActionResult)。我收到以下异常:

'urlHelper.Action(MVC.Sur.Maintenance.Index())' threw an exception of type 'System.ArgumentNullException'
    Data: {System.Collections.ListDictionaryInternal}
    HResult: -2147467261
    HelpLink: null
    InnerException: null
    Message: "Value cannot be null.\r\nParameter name: routeCollection"
    ParamName: "routeCollection"
    Source: "System.Web.Mvc"
    StackTrace: "   at System.Web.Mvc.UrlHelper.GenerateUrl(String routeName, String actionName, String controllerName, RouteValueDictionary routeValues, RouteCollection routeCollection, RequestContext requestContext, Boolean includeImplicitMvcValues)\r\n   at System.Web.Mvc.UrlHelper.GenerateUrl(String routeName, String actionName, String controllerName, String protocol, String hostName, String fragment, RouteValueDictionary routeValues, RouteCollection routeCollection, RequestContext requestContext, Boolean includeImplicitMvcValues)\r\n   at System.Web.Mvc.UrlHelper.RouteUrl(String routeName, RouteValueDictionary routeValues, String protocol, String hostName)\r\n   at System.Web.Mvc.T4Extensions.Action(UrlHelper urlHelper, ActionResult result, String protocol, String hostName)\r\n   at System.Web.Mvc.T4Extensions.Action(UrlHelper urlHelper, ActionResult result)"
    TargetSite: {System.String GenerateUrl(System.String, System.String, System.String, System.Web.Routing.RouteValueDictionary, System.Web.Routing.RouteCollection, System.Web.Routing.RequestContext, Boolean)}

为什么 routeCollection 为 NULL?我本以为它在我们处理请求时已经启动了。

Application_BeginRequest 是遗产 ASP.NET API。虽然有时有用,但通常没有必要在 MVC 中使用。由于它不是 MVC API,期望任何 MVC 功能在那里工作是不合理的。 MVC 建立在 ASP.NET 之上,而不是相反。

MVC 提供了一种以更易于维护的方式执行 cross-cutting 关注点的方法 - global filters。如果您坚持使用 MVC APIs 而不是总是求助于遗留 ASP.NET APIs,您会发现完成这样的任务要容易得多。

public class MyActionFilter : IActionFilter
{
    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
    }

    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var urlHelper = new UrlHelper(filterContext.RequestContext, System.Web.Routing.RouteTable.Routes);
        string result = urlHelper.Action(MVC.Bands.Index())
    }
}

用法

全局注册过滤器确保它在 每个 请求之前是 运行。

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new MyActionFilter());
        filters.Add(new HandleErrorAttribute());
    }
}

您可以选择实现一个 Custom Attribute,它可以放在动作方法 and/or 控制器上,以 run/not 运行 特定动作。