如何在 ASP.NET Core 3.1 上的支持 OData 的 Web API 运行 中添加 Swagger
How to add Swagger in OData-enabled Web API running on ASP.NET Core 3.1
我想在我的 Web 中同时使用 OData 和 Swagger API。我是 运行 ASP.NET Core 3.1.
我找到了这些文章,一篇启用 OData,另一篇启用 SwaggerUI
- 启用 OData: https://devblogs.microsoft.com/odata/enabling-endpoint-routing-in-odata/
- 启用招摇: https://www.coderjony.com/blogs/adding-swagger-to-aspnet-core-31-web-api/
但是,我似乎无法同时启用两者。看来我混错了。
这是我目前拥有的代码:
Startup.cs
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddOData();
AddSwagger(services);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Foo API V1");
});
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.Select().Filter().OrderBy().Count().MaxTop(10);
endpoints.MapODataRoute("odata", "odata", GetEdmModel());
});
}
private IEdmModel GetEdmModel()
{
var odataBuilder = new ODataConventionModelBuilder();
odataBuilder.EntitySet<WeatherForecast>("WeatherForecast");
return odataBuilder.GetEdmModel();
}
private void AddSwagger(IServiceCollection services)
{
services.AddSwaggerGen(options =>
{
var groupName = "v1";
options.SwaggerDoc(groupName, new OpenApiInfo
{
Title = $"Foo {groupName}",
Version = groupName,
Description = "Foo API",
Contact = new OpenApiContact
{
Name = "Foo Company",
Email = string.Empty,
Url = new Uri("https://example.com/"),
}
});
});
}
}
当我访问 https://localhost:44363/odata/weatherforecast 时它起作用了
但是当我尝试加载 Swagger 界面时,显示的是:
没有显示任何内容!
这是我的控制器:
控制器
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
[EnableQuery]
public IEnumerable<WeatherForecast> Get()
{
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Id = Guid.NewGuid(),
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
}
进行此更改。
c.SwaggerEndpoint("../swagger/v1/swagger.json", "Foo API V1");
基本上它无法读取您的 swagger.json
文件。
我的理解是:
的组合
- ASP.NET 核心 3.1
- 端点路由
- OData(甚至 7.4+)
- 招摇
目前并没有真正工作,因为 OData controllers/routing 没有好的 ApiExplorer 实现。
但是,我遇到了同样的问题,并且我能够使用以下命令使操作出现在 Swagger/UI 中:
[ApiExplorerSettings(IgnoreApi = false)]
[Route("Data")]
[HttpGet]
public async Task<IEnumerable<Data>> GetData()
{
// ...
}
并在启动代码中应用它(改编自This):
services.AddControllers(options =>
{
IEnumerable<ODataOutputFormatter> outputFormatters =
options.OutputFormatters.OfType<ODataOutputFormatter>()
.Where(formatter => !formatter.SupportedMediaTypes.Any());
foreach (var outputFormatter in outputFormatters)
{
outputFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/odata"));
}
IEnumerable<ODataInputFormatter> inputFormatters =
options.InputFormatters.OfType<ODataInputFormatter>()
.Where(formatter => !formatter.SupportedMediaTypes.Any());
foreach (var inputFormatter in inputFormatters)
{
inputFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/odata"));
}
});
但是,这适用于某些操作,但我认为这不是一个好的解决方案,因为它会强制您使用 non-OData API 路由元数据([Route] + HTTP)重现 OData 约定路由动词属性)无处不在。这是 non-sense !
如果能够使用 EDM 和 OData 约定从整个 API 自动生成一个 OpenAPI 文档就好了...
资源:
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Swagger Demo Project");
});
更多详情:https://findandsolve.com/articles/how-to-implemenation-swagger-in-asp-net-core
我使用了下面的 nuget 包,这个问题得到了解决。
Install-PackageOData.Swagger
我想在我的 Web 中同时使用 OData 和 Swagger API。我是 运行 ASP.NET Core 3.1.
我找到了这些文章,一篇启用 OData,另一篇启用 SwaggerUI
- 启用 OData: https://devblogs.microsoft.com/odata/enabling-endpoint-routing-in-odata/
- 启用招摇: https://www.coderjony.com/blogs/adding-swagger-to-aspnet-core-31-web-api/
但是,我似乎无法同时启用两者。看来我混错了。
这是我目前拥有的代码:
Startup.cs
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddOData();
AddSwagger(services);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Foo API V1");
});
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.Select().Filter().OrderBy().Count().MaxTop(10);
endpoints.MapODataRoute("odata", "odata", GetEdmModel());
});
}
private IEdmModel GetEdmModel()
{
var odataBuilder = new ODataConventionModelBuilder();
odataBuilder.EntitySet<WeatherForecast>("WeatherForecast");
return odataBuilder.GetEdmModel();
}
private void AddSwagger(IServiceCollection services)
{
services.AddSwaggerGen(options =>
{
var groupName = "v1";
options.SwaggerDoc(groupName, new OpenApiInfo
{
Title = $"Foo {groupName}",
Version = groupName,
Description = "Foo API",
Contact = new OpenApiContact
{
Name = "Foo Company",
Email = string.Empty,
Url = new Uri("https://example.com/"),
}
});
});
}
}
当我访问 https://localhost:44363/odata/weatherforecast 时它起作用了 但是当我尝试加载 Swagger 界面时,显示的是:
没有显示任何内容!
这是我的控制器:
控制器
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
[EnableQuery]
public IEnumerable<WeatherForecast> Get()
{
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Id = Guid.NewGuid(),
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
}
进行此更改。
c.SwaggerEndpoint("../swagger/v1/swagger.json", "Foo API V1");
基本上它无法读取您的 swagger.json
文件。
我的理解是:
的组合- ASP.NET 核心 3.1
- 端点路由
- OData(甚至 7.4+)
- 招摇
目前并没有真正工作,因为 OData controllers/routing 没有好的 ApiExplorer 实现。 但是,我遇到了同样的问题,并且我能够使用以下命令使操作出现在 Swagger/UI 中:
[ApiExplorerSettings(IgnoreApi = false)]
[Route("Data")]
[HttpGet]
public async Task<IEnumerable<Data>> GetData()
{
// ...
}
并在启动代码中应用它(改编自This):
services.AddControllers(options =>
{
IEnumerable<ODataOutputFormatter> outputFormatters =
options.OutputFormatters.OfType<ODataOutputFormatter>()
.Where(formatter => !formatter.SupportedMediaTypes.Any());
foreach (var outputFormatter in outputFormatters)
{
outputFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/odata"));
}
IEnumerable<ODataInputFormatter> inputFormatters =
options.InputFormatters.OfType<ODataInputFormatter>()
.Where(formatter => !formatter.SupportedMediaTypes.Any());
foreach (var inputFormatter in inputFormatters)
{
inputFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/odata"));
}
});
但是,这适用于某些操作,但我认为这不是一个好的解决方案,因为它会强制您使用 non-OData API 路由元数据([Route] + HTTP)重现 OData 约定路由动词属性)无处不在。这是 non-sense !
如果能够使用 EDM 和 OData 约定从整个 API 自动生成一个 OpenAPI 文档就好了...
资源:
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Swagger Demo Project");
});
更多详情:https://findandsolve.com/articles/how-to-implemenation-swagger-in-asp-net-core
我使用了下面的 nuget 包,这个问题得到了解决。 Install-PackageOData.Swagger