Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# mvc6中的路由_C#_Asp.net Core_Asp.net Core Mvc_Asp.net Core Routing - Fatal编程技术网

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