其他分享
首页 > 其他分享> > CodeGo.net>有没有办法告诉路由我的默认动作名称等于HTTP动作动词?

CodeGo.net>有没有办法告诉路由我的默认动作名称等于HTTP动作动词?

作者:互联网

我已经在MSDN上浏览了this document,但无法给出答案.

考虑到我有这样定义的路由:

    config.Routes.MapHttpRoute(
        name: "DefaultWithActionAndID",
        routeTemplate: "v{version}/{controller}/{action}/{id}",
        defaults: null,
        constraints: new {
            action = @"[a-zA-Z]+",
            id = @"\d+"
        }
    );

    config.Routes.MapHttpRoute(
        name: "DefaultWithID",
        routeTemplate: "v{version}/{controller}/{id}",
        defaults: null,
        constraints: new {
            id = @"\d+"
        }
    );

    config.Routes.MapHttpRoute(
        name: "DefaultWithoutActionOrId",
        routeTemplate: "v{version}/{controller}",
        defaults: null,
    );

现在,我有两个看起来像这样的控制器:

public class ItemController:ApiController{
    [HttpGet]
    public Item Get(int id){}

    [HttpGet]
    public Item GetSomething(int id){}

    [HttpPut]
    public Item Put(Item newItem){}
}

public class AnotherController:ApiController{
    [HttpPut]
    public HttpResponseMessage Put(Something item){}
}

我希望能够像这样调用所有这些端点:

GET /api/Item/344
GET /api/Item?id=344
GET /api/Item/Something/2334
GET /api/Item/Something?id=2334
PUT /api/Item     body={newItem}
PUT /api/Another  body={newSomething}

这将起作用,但前提是我添加“ Get”作为默认操作名称.如果我未在路线中指定默认操作名称,则它将抱怨多个匹配的操作名称.如果我确实添加了默认操作名称,那么我将不会在没有错误的情况下调用PUT到Put()方法,因为操作名称与默认名称不匹配并且找不到.

    // Will work in some cases, but not all
    config.Routes.MapHttpRoute(
        name: "DefaultWithID",
        routeTemplate: "v{version}/{controller}/{id}",
        defaults: new {
            action="Get",
            id=RouteParameters.Optional
        },
        constraints: new {
            id = @"\d+"
        }
    );

    // Works
GET /api/Item/344
GET /api/Item?id=344
GET /api/Item/Something/2334
GET /api/Item/Something?id=2334

// Doesn't work
PUT /api/Item     body={newItem}
PUT /api/Another  body={newSomething}

如果尝试使用之前,如何告诉路由使用与HTTP动词匹配的名称的操作

解决方法:

如果您按以下方式定义路线:

    config.Routes.MapHttpRoute(
            name: "DefaultWithActionAndID",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional },
            constraints: new {action = @"[a-zA-Z]+", id = @"\d*" }
            );

    config.Routes.MapHttpRoute(
        name: "DefaultWithID",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { action = "GET", id = RouteParameter.Optional },
        constraints: new { id = @"\d*", httpMethod = new HttpMethodConstraint(new string[] { "GET" }) }
        );

    config.Routes.MapHttpRoute(
        name: "DefaultWithoutActionOrId",
        routeTemplate: "api/{controller}",
        defaults: new { action = "PUT" },
        constraints: new { httpMethod = new HttpMethodConstraint(new string[] { "PUT" }) }
        );

然后将ActionName属性放置在您的GetSomething方法上,如下所示:

[ActionName("Something")]
public Item GetSomething(int id){}

然后,您应该能够击中上述所有端点.

标签:asp-net-web-api,asp-net-web-api-routing,asp-net-mvc-routing,c
来源: https://codeday.me/bug/20191123/2066979.html