.net 未能将路由与正确的操作匹配
我有一个运行在旧ASP.NET MVC上的应用程序,我正在尝试将其移植到ASP.NET Core 3.1。旧版本运行良好,但在.NET核心版本中,我在将相同URL与等效操作匹配时遇到问题。我使用的是禁用EndpointRouting的MVC(AddMvc/UseMvc)。以下是所有配置(无显式路由):.net 未能将路由与正确的操作匹配,.net,asp.net-mvc,asp.net-core,.net-core,asp.net-core-3.1,.net,Asp.net Mvc,Asp.net Core,.net Core,Asp.net Core 3.1,我有一个运行在旧ASP.NET MVC上的应用程序,我正在尝试将其移植到ASP.NET Core 3.1。旧版本运行良好,但在.NET核心版本中,我在将相同URL与等效操作匹配时遇到问题。我使用的是禁用EndpointRouting的MVC(AddMvc/UseMvc)。以下是所有配置(无显式路由): 公共类启动 { public void配置服务(IServiceCollection服务) { services.AddMvc(o=> { o、 EnableEndpointRouting=fal
公共类启动
{
public void配置服务(IServiceCollection服务)
{
services.AddMvc(o=>
{
o、 EnableEndpointRouting=false;
});
}
public void配置(IApplicationBuilder应用程序、IWebHostEnvironment环境)
{
app.UseMvc();
}
}
控制器操作如下所示:
[ApiController]
[路线(“[控制器]”)]
公共类控制器:ControllerBase
{
[HttpPost]
公共行动结果剂量测定(布尔真实)
{
返回内容(“完成的事情”);
}
[HttpPost]
公共行动结果DoSomethingElse(bool unreal)
{
返回内容(“做了其他事情”);
}
}
URL(同样在.NET MVC中工作)是这样的:/Some?real=true
这解决了.NETMVC中的DoSomething
操作,没有问题。在ASP.NET Core上,它引发异常:
Microsoft.AspNetCore.Mvc.Infrastructure.AmbiguousActionException: Multiple actions matched. The following actions matched route data and had all constraints satisfied:
netcore.Controllers.SomeController.DoSomething (netcore)
netcore.Controllers.SomeController.DoSomethingElse (netcore)
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionSelector.SelectBestCandidate(RouteContext context, IReadOnlyList`1 candidates)
at Microsoft.AspNetCore.Mvc.Routing.MvcAttributeRouteHandler.RouteAsync(RouteContext context)
at Microsoft.AspNetCore.Routing.Tree.TreeRouter.RouteAsync(RouteContext context)
at Microsoft.AspNetCore.Routing.RouteCollection.RouteAsync(RouteContext context)
at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
但是为什么呢?这怎么会模棱两可呢?布尔变量的命名明显不同,不应该有任何混淆。我知道我可以通过更改路由或方法名称来修复它,但我需要在不更改任何底层功能/路由/等的情况下移植应用程序
更新:简化了操作方法,使其具有一个布尔变量(具有不同的变量名),并且仍然会发生歧义异常
但是为什么呢?这怎么会模棱两可呢?布尔变量的命名明显不同,不应该有任何混淆
在中,您会发现:
在Asp.Net内核中,控制器和ApiController类被统一到一个控制器类中。微软决定不再提供一种机制来尝试根据查询字符串找到正确的方法
要实现ASP.NET Core中的要求,您可以尝试实现自定义的ActionMethodSelectorAttribute
,并将其应用于您的操作,如下所示
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class CheckQueryStingAttribute : ActionMethodSelectorAttribute
{
public string QueryStingName { get; set; }
public bool CanPass { get; set; }
public CheckQueryStingAttribute(string qname, bool canpass)
{
QueryStingName = qname;
CanPass = canpass;
}
public override bool IsValidForRequest(RouteContext routeContext, ActionDescriptor action)
{
StringValues value;
routeContext.HttpContext.Request.Query.TryGetValue(QueryStingName, out value);
if (CanPass)
{
return !StringValues.IsNullOrEmpty(value);
}
return StringValues.IsNullOrEmpty(value);
}
}
适用于行动
测试结果
但是为什么呢?这怎么会模棱两可呢?布尔变量的命名明显不同,不应该有任何混淆
在中,您会发现:
在Asp.Net内核中,控制器和ApiController类被统一到一个控制器类中。微软决定不再提供一种机制来尝试根据查询字符串找到正确的方法
要实现ASP.NET Core中的要求,您可以尝试实现自定义的ActionMethodSelectorAttribute
,并将其应用于您的操作,如下所示
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class CheckQueryStingAttribute : ActionMethodSelectorAttribute
{
public string QueryStingName { get; set; }
public bool CanPass { get; set; }
public CheckQueryStingAttribute(string qname, bool canpass)
{
QueryStingName = qname;
CanPass = canpass;
}
public override bool IsValidForRequest(RouteContext routeContext, ActionDescriptor action)
{
StringValues value;
routeContext.HttpContext.Request.Query.TryGetValue(QueryStingName, out value);
if (CanPass)
{
return !StringValues.IsNullOrEmpty(value);
}
return StringValues.IsNullOrEmpty(value);
}
}
适用于行动
测试结果
IIRC,除非在Core中显式映射路由,否则不会考虑操作方法变量名。IIRC,除非在Core中显式映射路由,否则不会考虑操作方法变量名。谢谢!我通读了所有MS文档,但找不到任何提示。你的解决方案挽救了这一天!非常感谢。我通读了所有MS文档,但找不到任何提示。你的解决方案挽救了这一天!