API路由:带路径的多个操作

Cas*_*ton 3 c# asp.net asp.net-web-api swagger asp.net-web-api-routing

我正在尝试配置我的API路由,我似乎无法绕过Swagger的这个错误:

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

我明白为什么我得到错误,但我不知道如何解决它.以下是API端点:

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)
{
    ....
}
Run Code Online (Sandbox Code Playgroud)

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

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}"
);
Run Code Online (Sandbox Code Playgroud)

更新:

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

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}"
);
Run Code Online (Sandbox Code Playgroud)

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

我想,越来越近了.

[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)
{
    ....
}
Run Code Online (Sandbox Code Playgroud)

然后是路线:

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}"
);
Run Code Online (Sandbox Code Playgroud)

但是,当我试着打电话的时候

GET: http://localhost:26307/api/Doors/1012
Run Code Online (Sandbox Code Playgroud)

要么

GET: http://localhost:26307/api/Doors/1012/23
Run Code Online (Sandbox Code Playgroud)

要么

DELETE: http://localhost:26307/api/Doors/1012/23
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

Nko*_*osi 5

route1并且route2因为可选而具有相同的映射{id}.删除可选参数并放在route2之前,route1因为route1更一般.

您还可以提供约束,这些约束限制URI段与占位符匹配的方式:

constraints: new { id = @"\d+" }   // Only matches if "id" is one or more digits.
Run Code Online (Sandbox Code Playgroud)

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}"
);
Run Code Online (Sandbox Code Playgroud)

还有一个问题映射到

public IHttpActionResult Get(int OrganizationSys, int DoorID) {
    ....
}
Run Code Online (Sandbox Code Playgroud)

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

public IHttpActionResult Get(int organizationSys, int id) {
    ....
}
Run Code Online (Sandbox Code Playgroud)

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

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

        // Convention-based routing.

       //...code removed for brevity
    }
}
Run Code Online (Sandbox Code Playgroud)

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

[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) {
        //....
    }    
}
Run Code Online (Sandbox Code Playgroud)

请注意使用RoutePrefix属性来减少重复的模板部件和路径约束.

ASP.NET Web API 2中的引用属性路由