C# 当 api 从另一个项目内部提供时,如何在 Swashbuckle/Swaggerwork 中创建 url 路径?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29995706/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I make url path in Swashbuckle/Swaggerwork when api is served from inside another project?
提问by Dmitriy
all. I am trying to document a WebApi 2 using Swashbuckle package.
全部。我正在尝试使用 Swashbuckle 包记录 WebApi 2。
All works great if the API is running by itself i.e. localhost/api/swaggerbrings me to ui and localhost/api/swagger/docs/v1to json.
如果 API 自己运行,一切都很好,即localhost/api/swagger将我带到 ui 并将localhost/api/swagger/docs/v1带到 json。
However the producation app initializes this same Webapi project by running webapiconfig method of this project from global.asax.cs in another - now web project (the main application one). So the api url looks like localhost/web/apiinstead of localhost/api.
然而,生产应用程序通过从 global.asax.cs 在另一个 - 现在的 web 项目(主应用程序)中运行该项目的 webapiconfig 方法来初始化这个相同的 Webapi 项目。所以 api url 看起来像localhost/web/api而不是 localhost/api。
Now swashbuckle doesn't work like that at all.
现在 swashbuckle 根本不是那样工作的。
- localhost/api/swagger generates error cannot load 'API.WebApiApplication', well of course
- localhost/web/swagger = 404
- localhost/web/api/swagger = 404
- localhost/api/swagger 生成错误无法加载 'API.WebApiApplication',当然好
- 本地主机/网络/招摇= 404
- 本地主机/网络/api/swagger = 404
I tried to look everywhere, but all I found is workaround.
我试图到处寻找,但我发现的只是解决方法。
c.RootUrl(req => req.RequestUri.GetLeftPart(UriPartial.Authority) + VirtualPathUtility.ToAbsolute("~/").TrimEnd('/'));
Unfortunately it doesn't work, now maybe it should and I just need to change something but I don't even know what exactly this property expects and what it should be set to.
不幸的是它不起作用,现在也许它应该并且我只需要改变一些东西,但我什至不知道这个属性究竟期望什么以及它应该设置为什么。
May be it's not even applicable - maybe setup we have requires something else or some swashbuckle code changes.
可能它甚至不适用 - 也许我们的设置需要其他东西或一些 swashbuckle 代码更改。
I will appreciate any help you can provide. I really starting to like swagger (and swashbuckle) for rest documentation.
我将不胜感激您能提供的任何帮助。我真的开始喜欢 swagger(和 swashbuckle)作为休息文档。
采纳答案by Anthony Neace
For Swashbuckle 5.x:
对于 Swashbuckle 5.x:
This appears to be set by an extension method of httpConfiguration called EnableSwagger. Swashbuckle 5.x migration readmenotes that this replaces SwaggerSpecConfig. SwaggerDocConfig RootUrl() specifically replaces ResolveBasePathUsing() from 4.x.
这似乎是由名为 EnableSwagger 的 httpConfiguration 扩展方法设置的。Swashbuckle 5.x迁移自述文件指出这取代了 SwaggerSpecConfig。SwaggerDocConfig RootUrl() 专门替换了 4.x 中的 ResolveBasePathUsing()。
This practically works the same as it did before, looks like the biggest change was that it was renamed and moved into SwaggerDocConfig:
这实际上和以前一样工作,看起来最大的变化是它被重命名并移动到SwaggerDocConfig:
public void RootUrl(Func<HttpRequestMessage, string> rootUrlResolver)
An example from the readme, tweaked for brevity:
readme 中的一个示例,为简洁起见进行了调整:
string myCustomBasePath = @"http://mycustombasepath.com";
httpConfiguration
.EnableSwagger(c =>
{
c.RootUrl(req => myCustomBasePath);
// The rest of your additional metadata goes here
});
For Swashbuckle 4.x:
对于 Swashbuckle 4.x:
Use SwaggerSpecConfig ResolveBasePathUsing and have your lambda read your known endpoint.
使用 SwaggerSpecConfig ResolveBasePathUsing 并让您的 lambda 读取您的已知端点。
ResolveBasePathUsing:
ResolveBasePathUsing:
public SwaggerSpecConfig ResolveBasePathUsing(Func<HttpRequestMessage, string> basePathResolver);
My API is behind a load balancer and this was a helpful workaround to providing a base address. Here's a dumb example to use ResolveBasePathUsing to resolve the path with a known base path.
我的 API 位于负载平衡器之后,这是提供基地址的有用解决方法。这是一个使用 ResolveBasePathUsing 解析具有已知基本路径的路径的愚蠢示例。
string myCustomBasePath = @"http://mycustombasepath.com";
SwaggerSpecConfig.Customize(c =>
{
c.ResolveBasePathUsing((req) => myCustomBasePath);
}
I hardcoded the endpoint for clarity, but you can define it anywhere. You can even use the request object to attempt to cleanup your request urito point to /web/api instead of /api.
为了清楚起见,我对端点进行了硬编码,但您可以在任何地方定义它。您甚至可以使用请求对象来尝试清理您的请求 uri以指向 /web/api 而不是 /api。
The developer commented on this workaroundon GitHub last year:
开发者去年在 GitHub 上评论了这个解决方法:
The lambda takes the current HttpRequest (i.e. the request for a given Swagger ApiDeclaration) and should return a string to be used as the baseUrl for your Api. For load-balanced apps, this should return the load-balancer path.
The default implementation is as follows:
(req) => req.RequestUri.GetLeftPart(UriPartial.Authority) + req.GetConfiguration().VirtualPathRoot.TrimEnd('/');...
Re relative paths, the Swagger spec requires absolute paths because the URL at which the Swagger is being served need not be the URL of the actual API.
...
The lambda is passed a HttpRequestMessage instance ... you should be able to use this to get at the RequestUri etc. Another option, you could just place the host name in your web.config and have the lambda just read it from there.
lambda 接受当前的 HttpRequest(即对给定 Swagger ApiDeclaration 的请求),并应返回一个字符串以用作 Api 的 baseUrl。对于负载平衡的应用程序,这应该返回负载平衡器路径。
默认实现如下:
(req) => req.RequestUri.GetLeftPart(UriPartial.Authority) + req.GetConfiguration().VirtualPathRoot.TrimEnd('/');...
对于相对路径,Swagger 规范需要绝对路径,因为提供 Swagger 的 URL 不必是实际 API 的 URL。
...
lambda 被传递一个 HttpRequestMessage 实例......你应该能够使用它来获取 RequestUri 等。另一种选择,你可以将主机名放在你的 web.config 中,让 lambda 从那里读取它。

