API路由:带有路径的多个操作 [英] API Routes: Multiple operations with path

查看:95
本文介绍了API路由:带有路径的多个操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试配置我的API路由,但似乎无法解决Swagger的错误:

I am trying to configure my API routes, and I can't seem to get around this error from Swagger:

500:{"Message":发生错误.","ExceptionMessage":"Swagger 2.0不支持:路径'api/Doors/{OrganizationSys}'和方法'GET'的多项操作.

500 : {"Message":"An error has occurred.","ExceptionMessage":"Not supported by Swagger 2.0: Multiple operations with path 'api/Doors/{OrganizationSys}' and method 'GET'.

我知道为什么会收到错误,但不确定如何解决.以下是API端点:

I understand why I am getting the error, but I'm not sure how to fix it. Here are the API end points:

public IHttpActionResult Get(int organizationSys)
{
    ....
}

public IHttpActionResult Get(int organizationSys, int id)
{
    ....
}


public IHttpActionResult Post([FromBody]Doors door)
{
    ....
}

public IHttpActionResult Put([FromBody]Doors door)
{
    ....
}

public IHttpActionResult Delete(int organizationSys, int id)
{
    ....
}

这是我的路线,显然不正确:

And here are my routes, which are clearly not correct:

config.Routes.MapHttpRoute(
    name: "route1",
    routeTemplate: "api/{controller}/{organizationSys}"
);

config.Routes.MapHttpRoute(
    name: "route2",
    routeTemplate: "api/{controller}/{organizationSys}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}"
);

更新:

我现在有了这个,但是得到了同样的错误:

I now have this, but get the same error:

config.Routes.MapHttpRoute(
    name: "route1",
    routeTemplate: "api/{controller}/{organizationSys}/{id}"
);

config.Routes.MapHttpRoute(
    name: "route2",
    routeTemplate: "api/{controller}/{organizationSys}"
);

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}"
);

更新2:这就是我现在所拥有的....

UPDATE 2: This is what I have now....

我想靠近.

[Route("api/Doors/{organizaitonSys}")]
public IHttpActionResult Get(int organizationSys)
{
    ....
}

[Route("api/Doors/{organizaitonSys}/{id}")]
public IHttpActionResult Get(int organizationSys, int id)
{
    ....
}

[Route("api/Doors")]
public IHttpActionResult Post([FromBody]Doors door)
{
    ....
}

[Route("api/Doors")]
public IHttpActionResult Post([FromBody]Doors door)
{
    ....
}

[Route("api/Doors/{organizaitonSys}/{id}")]
public IHttpActionResult Delete(int organizationSys, int id)
{
    ....
}

然后是路线:

config.Routes.MapHttpRoute(
name: "route1",
routeTemplate: "api/{controller}/{organizationSys}/{id}"
);

config.Routes.MapHttpRoute(
name: "route2",
routeTemplate: "api/{controller}/{organizationSys}"
);

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}"
);

但是,当我尝试致电

GET: http://localhost:26307/api/Doors/1012

GET: http://localhost:26307/api/Doors/1012/23

DELETE: http://localhost:26307/api/Doors/1012/23

我收到404错误.现在在Swagger中,organizationSys参数在Try It部分中显示了两次:

I get 404 errors. And now in Swagger, the organizationSys parameter shows up twice in the Try It section:

推荐答案

route1route2具有相同的映射.删除可选参数,并将route2放在route1之前,因为route1更通用.

route1 and route2 have the same mapping because of the optional {id}. remove the optional parameter and put route2 before route1 as route1 is more general.

您还可以提供限制条件,以限制URI段如何匹配占位符:

You can also provide constraints, which restrict how a URI segment can match a placeholder:

constraints: new { id = @"\d+" }   // Only matches if "id" is one or more digits.

示例

config.Routes.MapHttpRoute(
    name: "route2",
    routeTemplate: "api/{controller}/{organizationSys}/{id}",
    constraints: new { id = @"\d+" }   // Only matches if "id" is one or more 
);

config.Routes.MapHttpRoute(
    name: "route1",
    routeTemplate: "api/{controller}/{organizationSys}"
);

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}"
);

映射到

public IHttpActionResult Get(int OrganizationSys, int DoorID) {
    ....
}

因为DoorID参数与路由模板的参数不匹配.将其重命名为id或更新模板以匹配.

because of the DoorID parameter, which does not match that of the route template. rename it to id or update the template to match.

public IHttpActionResult Get(int organizationSys, int id) {
    ....
}

如果使用属性路由,请确保在基于约定的路由之前将其启用

If using attribute routing then make sure it is enabled before convention-based routes

public static class WebApiConfig {
    public static void Register(HttpConfiguration config) {
        // Attribute routing.
        config.MapHttpAttributeRoutes();

        // Convention-based routing.

       //...code removed for brevity
    }
}

然后通过属性将路由应用于控制器.

Then apply the routes to the controller via attributes.

[RoutePrefix("api/Doors")]
public class DoorsController : ApiController {

    //matches GET api/doors/5
    [HttpGet]
    [Route("{organizationSys:int}")]
    public IHttpActionResult Get(int organizationSys) {
        //....
    }

    //matches GET api/doors/5/1
    [HttpGet]
    [Route("{organizationSys:int}/{id:int}")]
    public IHttpActionResult Get(int organizationSys, int id) {
        ....
    }    

    //matches POST api/doors
    [HttpPost]
    [Route("")]
    public IHttpActionResult Post([FromBody]Doors door) {
        //....
    }

    //matches PUT api/doors
    [HttpPut]
    [Route("")]    
    public IHttpActionResult Put([FromBody]Doors door) {
        //....
    }

    //matches DELETE api/doors/5/1
    [HttpDelete]
    [Route("{organizationSys:int}/{id:int}")]    
    public IHttpActionResult Delete(int organizationSys, int id) {
        //....
    }    
}

请注意,使用RoutePrefix属性可以减少重复的模板部分和路径约束.

Note the use of RoutePrefix attribute to reduce repeated template parts and route constraints.

参考 查看全文

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆