【问题标题】:web-api & swagger documentationweb-api & swagger 文档
【发布时间】:2014-07-16 11:05:37
【问题描述】:

我编写了一个 ASP web-api,并使用 this class 为 api 添加了版本控制。

我的路线如下所示:

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

config.Services.Replace(typeof(IHttpControllerSelector), new NamespaceHttpControllerSelector(config));

所以我可以访问https://localhost:44301/v1/test

我现在正在尝试添加 Swagger 以生成一些 api 文档(实际上我正在使用 Swashbuckle Nuget 包)

当我浏览到 /swagger 时,页面加载但出现所有控制器的错误:

Unable to read api 'TestController' from path https://localhost:44301/swagger/api-docs/TestController (server returned undefined)

如果我浏览到https://localhost:44301/swagger/api-docs/TestController,它会出现一个NullReferenceException,其堆栈跟踪为:

at Swashbuckle.Swagger.OperationGenerator.CreateParameter(ApiParameterDescription apiParamDesc, String apiPath)
   at Swashbuckle.Swagger.OperationGenerator.<>c__DisplayClass2.<ApiDescriptionToOperation>b__1(ApiParameterDescription paramDesc)
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Swashbuckle.Swagger.OperationGenerator.ApiDescriptionToOperation(ApiDescription apiDescription)
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.OrderedEnumerable`1.<GetEnumerator>d__0.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Swashbuckle.Swagger.ApiExplorerAdapter.CreateApi(IGrouping`2 apiDescriptionGroup, OperationGenerator operationGenerator)
   at Swashbuckle.Swagger.ApiExplorerAdapter.<>c__DisplayClassb.<GetDeclaration>b__7(IGrouping`2 apiDescGrp)
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.OrderedEnumerable`1.<GetEnumerator>d__0.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Swashbuckle.Swagger.ApiExplorerAdapter.GetDeclaration(String basePath, String version, String resourceName)
   at Swashbuckle.Application.CachingSwaggerProvider.<>c__DisplayClass4.<GetDeclaration>b__3(String k)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Swashbuckle.Application.CachingSwaggerProvider.GetDeclaration(String basePath, String version, String resourceName)
   at Swashbuckle.Application.SwaggerSpecHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.HttpMessageInvoker.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Web.Http.Dispatcher.HttpRoutingDispatcher.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Net.Http.DelegatingHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   at System.Web.Http.HttpServer.<>n__FabricatedMethod9(HttpRequestMessage , CancellationToken )
   at System.Web.Http.HttpServer.<SendAsync>d__0.MoveNext()

如果我将路线更改为:

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

然后 Swagger 页面可以工作,但实际的 api 不能!

所以问题是,如何让 Swagger 使用版本化的 api?

【问题讨论】:

  • 嗨!我的情况完全一样。你有没有解决过你的问题?
  • 看起来 Swashbuckle 无法处理 NamespaceHttpControllerSelector。我有类似的问题,目前没有解决方案。

标签: asp.net asp.net-web-api documentation swagger


【解决方案1】:

最后我使用了SDammann.WebApi.Versioning nuget 包和以下路线:

VersionedControllerSelector.VersionPrefix = "v";

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

我的控制器位于名为 v1 或 v2 等的命名空间中。

【讨论】:

  • 是的,我确实使用上述方法来进行版本控制
【解决方案2】:

试试这个

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

【讨论】:

    猜你喜欢
    • 2016-01-03
    • 1970-01-01
    • 2017-03-08
    • 2014-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-16
    • 1970-01-01
    相关资源
    最近更新 更多