首页 文章

Swashbuckle / Swagger没有从配置中获取路由

提问于
浏览
2

我正在使用Swashbuckle(swagger的.NET包装器) .

当我生成我的swagger文档时,它会从控制器名称/参数中生成文档中的URI,而不是在应用程序启动时在config中定义的已定义路由 .

所以我有一个控制器:

namespace Pat.PostingService.Api.Version1
{
    public class DeliveryStatusController : ApiController
    {
         [ResponseType(typeof(DeliveryStatusDto))]
         public dynamic Get(string deliveryType, Guid? orderId = null)
         {
             ...
         }
    }
{

在RouteConfig.cs文件中,我重新定义了路由:

public void Configuration(IAppBuilder appBuilder)
{
    var config = new HttpConfiguration();

    ...

    config.Routes.MapHttpRoute(
         name: "DeliveryStatusService",
         routeTemplate: "SpecialDeliveryServiceStatus/{deliveryType}/{orderId}",
         defaults: new {
             controller = "DeliveryStatus",
             orderId = RouteParameter.Optional
         }
    );

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

在调用API时,我现在无法使用 /DeliveryStatus endpoints ,我必须使用 /SpecialDeliveryServiceStatus endpoints .

但是,Swagger文档声明 endpoints 是 /DeliveryStatus .

与我的同事一起,我们认为 _apiExplorer.ApiDescriptions (来自Swashbuckle.Core中SwaggerGenerator.cs使用的System.Web.Http.Description.IApiExplorer)正在向我们返回错误的路由,尽管我们可能错了 .

我们错过了什么?有什么东西可以用来确保Swagger使用配置中使用的路由而不是默认路由吗?


编辑:

我们还使用SDammann进行版本控制(想象一个版本2文件夹中的第二个RouteConfig.cs文件),它不支持[AttributeRouting],因此我们需要从启动路由配置中获取路由 .


编辑2:

action = "Get" 置于路由的默认值中也不能解决问题 .

1 回答

  • 2

    当第一场比赛获胜时,您在路线表中注册/映射路线的顺序起着重要作用 . 您的示例显示了如何注册相关路线,但不显示其相对于其他路线的注册位置 .

    例如,如果您在相关路线之前注册默认路线

    public void Configuration(IAppBuilder appBuilder)
    {
        var config = new HttpConfiguration();
    
        ...
    
        config.Routes.MapHttpRoute(
             name: "Default",
             routeTemplate: "{controller}/{id}",
             defaults: new { id = RouteParameter.Optional }
        );
    
        config.Routes.MapHttpRoute(
             name: "DeliveryStatusService",
             routeTemplate: "SpecialDeliveryServiceStatus/{deliveryType}/{orderId}",
             defaults: new {
                 controller = "DeliveryStatus",
                 orderId = RouteParameter.Optional
             }
        );
    }
    

    ...然后 GET /DeliveryStatus 将按惯例匹配

    public dynamic Get(string deliveryType, Guid? orderId = null) { ... }
    

    特别是如果 id 占位符是可选的 .

    因此,请检查以确保路由映射的顺序正确 . 默认路由通常最后映射为回退路由 .

    public void Configuration(IAppBuilder appBuilder)
    {
        var config = new HttpConfiguration();
    
        ...
    
        config.Routes.MapHttpRoute(
             name: "DeliveryStatusService",
             routeTemplate: "SpecialDeliveryServiceStatus/{deliveryType}/{orderId}",
             defaults: new {
                 controller = "DeliveryStatus",
                 orderId = RouteParameter.Optional
             }
        );
    
        config.Routes.MapHttpRoute(
             name: "Default",
             routeTemplate: "{controller}/{id}",
             defaults: new { id = RouteParameter.Optional }
        );
    }
    

    如果你不喜欢使用attribute routing in web api 2,你可以改为......

    namespace Pat.PostingService.Api.Version1
    {
        [RoutePrefix("SpecialDeliveryServiceStatus")]
        public class DeliveryStatusController : ApiController
        {
             //GET SpecialDeliveryServiceStatus/{deliveryType}/{orderId}
             [HttpGet]
             [Route("{deliveryType}/{orderId?}")]
             [ResponseType(typeof(DeliveryStatusDto))]
             public dynamic Get(string deliveryType, Guid? orderId = null) { ... }
        }
    }
    

    在RouteConfig.cs文件中,配置属性路由:

    public void Configuration(IAppBuilder appBuilder)
    {
        var config = new HttpConfiguration();
    
        config.MapHttpAttributeRoutes();
        ...
    
    }
    

    再次映射顺序很重要,这就是为什么通常在其他映射之前配置它 .

    更新:

    请尝试以下方法:

    config.Routes.MapHttpRoute(
         name: "DeliveryStatusService",
         routeTemplate: "SpecialDeliveryServiceStatus/{deliveryType}/{orderId}",
         defaults: new {
             controller = "DeliveryStatus",
             action = "Get"
             orderId = RouteParameter.Optional
         }
    );
    

    并在控制器中:

    [HttpGet]
    [ResponseType(typeof(DeliveryStatusDto))]
    public dynamic Get(string deliveryType, Guid? orderId = null) { ... }
    

    确保路由表没有关于动作映射到哪个路由的猜测 .

相关问题