我需要重写ASP.NET Core 2.2项目中的UrlHelper实现。
我创建了一个名为MyUrlHelper
的类,像这样覆盖了UrlHelper
类
public class MyUrlHelper : UrlHelper
{
public MyUrlHelper(actionContext actionContext)
: base(actionContext)
{
}
public override string Content(string contentPath)
{
// do something new...
return base.Content(contentPath);
}
}
然后,我创建了一个名为MyUrlHelperFactory
的类,该类实现了IUrlHelperFactory
接口,
public class MyUrlHelperFactory : IUrlHelperFactory
{
public IUrlHelper GetUrlHelper(actionContext context)
{
return new MyUrlHelper(context);
}
}
最后,我尝试通过在Startup.ConfigureServices()
行之后的services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
方法中添加以下行来替换DI容器中的实现。
但这会引发以下错误
处理请求时发生未处理的异常。 ArgumentOutOfRangeException:索引超出范围。必须为非负数,并且小于集合的大小。
这是堆栈跟踪
ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index
System.Collections.Generic.List<T>.get_Item(int index)
microsoft.AspNetCore.Mvc.Routing.UrlHelper.get_Router()
microsoft.AspNetCore.Mvc.Routing.UrlHelper.GetVirtualPathData(string routeName,RouteValueDictionary values)
microsoft.AspNetCore.Mvc.Routing.UrlHelper.action(UrlactionContext actionContext)
microsoft.AspNetCore.Mvc.UrlHelperExtensions.action(IUrlHelper helper,string action,string controller,object values,string protocol,string host,string fragment)
microsoft.AspNetCore.Mvc.ViewFeatures.DefaultHtmlGenerator.GenerateactionLink(ViewContext viewContext,string linkText,string actionName,string controllerName,string hostname,string fragment,object routeValues,object htmlAttributes)
microsoft.AspNetCore.Mvc.TagHelpers.AnchorTagHelper.Process(TagHelperContext context,TagHelperOutput output)
microsoft.AspNetCore.Razor.TagHelpers.TagHelper.ProcessAsync(TagHelperContext context,TagHelperOutput output)
microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner.RunAsync(TagHelperExecutionContext executionContext)
AspNetCore.Views_Shared__Layout.<ExecuteAsync>b__44_1()
microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext.SetOutputContentAsync()
AspNetCore.Views_Shared__Layout.ExecuteAsync()
microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage page,ViewContext context)
microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage page,ViewContext context,bool invokeViewStarts)
microsoft.AspNetCore.Mvc.Razor.RazorView.RenderLayoutAsync(ViewContext context,ViewBufferTextWriter bodyWriter)
microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context)
microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext,string contentType,Nullable<int> statusCode)
microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(actionContext actionContext,IView view,ViewDataDictionary viewData,ITempDataDictionary tempData,Nullable<int> statusCode)
microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor.ExecuteAsync(actionContext context,ViewResult result)
microsoft.AspNetCore.Mvc.ViewResult.ExecuteResultAsync(actionContext context)
microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeResultAsync(IactionResult result)
microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResultFilterAsync<TFilter,TFilterAsync>()
microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResultExecutedContext context)
microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.ResultNext<TFilter,TFilterAsync>(ref State next,ref Scope scope,ref object state,ref bool isCompleted)
microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeResultFilters()
microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(ref State next,ref bool isCompleted)
microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext)
microsoft.AspNetCore.Staticfiles.StaticfileMiddleware.Invoke(HttpContext context)
microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
但是,如果禁用框架中的“端点路由”功能,则不会出现任何错误。但是,我想使用端点路由。如何在不禁用端点路由的情况下正确覆盖UrlHelper的实现?
这是我禁用端点路由的方式
services.AddMvc(options =>
{
options.EnableEndpointRouting = false;
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);