代码之家  ›  专栏  ›  技术社区  ›  SuperJMN

如何在ASP上运行的OData-enabled Web API中添加Swagger。NET核心3.1

  •  0
  • SuperJMN  · 技术社区  · 4 年前

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

    我找到了这些文章,一篇支持OData,另一篇支持SwaggerUI

    然而,我似乎无法同时启用这两个功能。看来我把它们混错了。

    这是我目前拥有的代码:

    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界面时,显示如下:

    enter image description here

    它什么都没显示!

    这是我的控制器:

    控制器

    [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();
        }
    }
    
    1 回复  |  直到 4 年前
        1
  •  5
  •   Aloene    4 年前

    我的理解是:

    • ASP。NET核心3.1
    • 端点路由
    • OData(甚至7.4+)
    • 斯瓦格

    真的不起作用 此时 因为没有好东西 ApiExplorer OData控制器/路由的实现。 然而,我遇到了同样的问题,我能够使用以下命令在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文档,那将是非常棒的。。。

    资源:

        2
  •  3
  •   paresh    4 年前

    我使用了下面的nuget包,这个问题得到了解决。 安装OData包。斯瓦格

    裁判: https://github.com/KishorNaik/Sol_OData_Swagger_Support

        3
  •  1
  •   Vivek Nuna Chetan sabhaya    4 年前

    进行此更改。

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

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

        4
  •  -1
  •   Adrian Mole Chris    4 年前
    app.UseSwaggerUI(c =>
      {
          c.SwaggerEndpoint("/swagger/v1/swagger.json", "Swagger Demo Project");
      });
    

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