繁体   English   中英

如何在启用 OData 的 Web API 中添加 Swagger 在 Z9E0DA8438E1E38A1C30F4B816Core 上运行

[英]How to add Swagger in OData-enabled Web API running on ASP.NET Core 3.1

我想在我的 Web API 中同时使用 OData 和 Swagger。 我正在运行 ASP.NET Core 3.1。

我找到了这些文章,一篇启用 OData,另一篇启用 SwaggerUI

但是,我似乎无法同时启用两者。 看来我把它们混合错了。

这是我目前拥有的代码:

启动.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/"),
                }
            });
        });
    }
}

当我从 go 到 https://localhost:44363/odata/weatherforecast 但是当我尝试加载 Swagger 界面时,它可以工作

在此处输入图像描述

它什么也没显示!

这是我的 controller:

Controller

[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();
    }
}

我的理解是:

  • ASP.NET 内核 3.1
  • 端点路由
  • OData(甚至 7.4+)
  • Swagger

目前并没有真正起作用因为 OData 控制器/路由没有好的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"));
    }
});

但是,这适用于某些操作,但我认为这不是一个好的解决方法,因为它会强制您在任何地方使用非 OData API 路由元数据([Route] + HTTP 动词属性)重现 OData 约定路由。 这是无稽之谈 !

如果能够使用 EDM 和 OData 约定从整个 API 自动生成 OpenAPI 文档,那就太好了……

资源:

我在下面使用了 nuget package,这个问题得到了解决。 安装包 OData.Swagger

参考: https://github.com/KishorNaik/Sol_OData_Swagger_Support

进行此更改。

c.SwaggerEndpoint("../swagger/v1/swagger.json", "Foo API V1");

基本上它无法读取您的swagger.json文件。

app.UseSwaggerUI(c =>
  {
      c.SwaggerEndpoint("/swagger/v1/swagger.json", "Swagger Demo Project");
  });

更多详情: https://findandsolve.com/articles/how-to-implemenation-swagger-in-asp-net-core

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM