c# - 如何在 ASP.NET Core 3.1 上运行的启用 OData 的 Web API 中添加 Swagger

标签 c# asp.net-core swagger odata swashbuckle

我想在我的 Web API 中同时使用 OData 和 Swagger。我正在运行 ASP.NET Core 3.1。
我找到了这些文章,一篇是启用 OData,另一篇是启用 SwaggerUI

  • 启用 OData: https://devblogs.microsoft.com/odata/enabling-endpoint-routing-in-odata/
  • 启用 Swagger: https://www.coderjony.com/blogs/adding-swagger-to-aspnet-core-31-web-api/

  • 但是,我似乎无法同时启用两者。看来我把它们混合错了。
    这是我目前拥有的代码:
    启动文件
    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 界面时,显示的是:
    enter image description here
    它什么都不显示!
    这是我的 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

  • 真的不行此时因为没有好ApiExplorer OData Controller /路由的实现。
    但是,我遇到了同样的问题,并且可以使用以下命令在 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 文档会很棒……
    资源:
  • https://github.com/OData/WebApi/issues/2024
  • https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/581#issuecomment-482747072
  • 关于c# - 如何在 ASP.NET Core 3.1 上运行的启用 OData 的 Web API 中添加 Swagger,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62404125/

    相关文章:

    asp.net-core - ASP.NET Core 日志记录机制中 EventId.Id 的安全范围

    c# - Swashbuckle 参数说明

    c# - 方法定义中的 operator + 有什么作用?

    c# - 将 key 发送到 C#/.NET 中的非事件应用程序

    c# - C# 中的正则表达式问题

    c# - ASP.NET Core 6 应用无法找到 UseWindowsService

    Azure Function - ILogger 不记录日志?

    c# - 在 .net 核心中设置全局时区

    java - Java Spring 应用程序可以利用 swagger 吗?

    rest - Swagger UI 将身份验证 token 传递给 header 中的 API 调用