C# mvc6中的路由
我有一个超级简单的控制器,有两种方法:C# mvc6中的路由,c#,asp.net-core,asp.net-core-mvc,asp.net-core-routing,C#,Asp.net Core,Asp.net Core Mvc,Asp.net Core Routing,我有一个超级简单的控制器,有两种方法: public IActionResult Users(long id) { return Json(new { name = "Example User" }); } public IActionResult Users() { return Json(new { list = new List<User>() }); } 我在startup.cs中设置了以下路由: app.UseMvc(routes =>
public IActionResult Users(long id)
{
return Json(new { name = "Example User" });
}
public IActionResult Users()
{
return Json(new { list = new List<User>() });
}
我在startup.cs中设置了以下路由:
app.UseMvc(routes =>
{
routes.MapRoute(name: "User_Default", template: "v1/{controller=Users}/{action=Users}/{id?}");
});
然而,这给了我一个模糊的usActionException:多个动作匹配。以下操作与路线数据匹配,并满足所有约束条件
我做错了什么?在原始webapi代码中,您使用的是添加webapi特定路由的
Routes.maphttprote
。这与MVC路由不同,MVC路由不考虑操作中的参数,例如,如果使用Routes.MapRoute
,MVC 5中也会出现同样的问题
MVC6代码中也发生了同样的情况,因为您正在使用routes.maprote
添加标准MVC路由。在这两种情况下,框架都会找到两个控制器动作,它们匹配相同的路线,并且没有附加约束。它需要一些帮助来选择这两个操作中的一个
消除api操作歧义的最简单方法是使用属性路由,而不是定义路由,如:
还有其他选项可以让您更改MVC6中MVC路由的行为。您可以创建自己的IActionConstraint
属性,以强制执行是否具有给定参数。这样一来,其中一个操作需要路由中的id参数,而另一个操作则不需要id参数(警告,未测试代码):
处理webapi 2样式控制器的更好选择是将约定添加到MVC管道中。这正是
Microsoft.AspNet.Mvc.WebApiCompatShim
帮助迁移webapi 2控制器所做的。您可以看到添加的约定。查看此软件包的快速概述。我猜您的控制器上有一个属性Route
,它存在于许多模板中。你能提供你的整个控制器吗?@MattDeKrey我不知道,因为我不认为如果我像webapi 2 routes那样简单地设置我的路由就需要它们。我已经将此标记为正确答案,但我也想知道为什么在startup.cs文件中指定路由不需要work@Gazeth,我已经在我的回复链接中添加了更多细节,并已更新。也在favor或IActionConstraint中摆脱了RouteConstraint属性
app.UseMvc(routes =>
{
routes.MapRoute(name: "User_Default", template: "v1/{controller=Users}/{action=Users}/{id?}");
});
[Route("v1/[controller]")]
public class UsersController : Controller
{
[HttpGet("{id:int}")]
public IActionResult Users(long id)
{
return Json(new { name = "Example User" });
}
public IActionResult Users()
{
return Json(new { list = new[] { "a", "b" } });
}
}
public class UsersController : Controller
{
[RouteParameterConstraint("id", ShouldAppear=true)]
public IActionResult Users(long id)
{
return Json(new { name = "Example User" });
}
[RouteParameterConstraint("id", ShouldNotAppear=true)]
public IActionResult Users()
{
return Json(new { list = new[] { "a", "b" } });
}
}
public class RouteParameterConstraintAttribute : Attribute, IActionConstraint
{
private routeParameterName;
public RouteParameterConstraintAttribute(string routeParameterName)
{
this.routerParamterName = routerParameterName;
}
public int Order => 0;
public bool ShouldAppear {get; set;}
public bool ShouldNotAppear {get; set;}
public bool Accept(ActionConstraintContext context)
{
if(ShouldAppear) return context.RouteContext.RouteData.Values["country"] != null;
if(ShouldNotAppear) return context.RouteContext.RouteData.Values["country"] == null;
return true;
}
}