首页 > 解决方案 > 带有 ODataQueryOptions 的 Odata Controller 会在 swagger 中生成错误:“undefined /swagger/v1/swagger.json”

问题描述

我正在使用网络核心 3.1。我的项目包含在启动时使用 UseEndpoints + swagger + odata 配置的 api 控制器(ODataController),

这一切都很好,直到我将 ODataQueryOptions 添加到控制器中的方法之一。之后,swagger 显示以下错误:“undefined /swagger/v1/swagger.json”

这些是我的启动定义:

 public void ConfigureServices(IServiceCollection services)
    {
        services.AddOData();
        services.AddControllers();

        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
        });

        SetOutputFormatters(services);
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseHttpsRedirection();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.EnableDependencyInjection();
            endpoints.Select().Filter().Expand().MaxTop(10);
            endpoints.MapODataRoute("odata", "odata", GetEdmModel());
        });

        app.UseSwagger();

        app.UseSwaggerUI(c =>
        {
            c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
        });
    }

支持 OData 查询的端点。

    [HttpGet]
    [EnableQuery]
    public IEnumerable<WeatherForecast> Get()

    [HttpGet]
    [ODataRoute]
    [EnableQuery(HandleNullPropagation = HandleNullPropagationOption.False, MaxTop = 100, AllowedQueryOptions = AllowedQueryOptions.Select |AllowedQueryOptions.Count)]
    public IEnumerable<WeatherForecast> Getlist(ODataQueryOptions options)

标签: asp.net-core.net-core

解决方案


这是我的工作演示,您可以参考:

启动.cs

public void ConfigureServices(IServiceCollection services)
    {
        services.AddOData();
        services.AddControllers();

        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
        });

        services.AddMvcCore(options =>
        {
            foreach (var outputFormatter in options.OutputFormatters.OfType<ODataOutputFormatter>().Where(_ => _.SupportedMediaTypes.Count == 0))
            {
                outputFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/prs.odatatestxx-odata"));
            }
            foreach (var inputFormatter in options.InputFormatters.OfType<ODataInputFormatter>().Where(_ => _.SupportedMediaTypes.Count == 0))
            {
                inputFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/prs.odatatestxx-odata"));
            }
        });
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseHttpsRedirection();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
            endpoints.EnableDependencyInjection();
            endpoints.Select().Filter().Expand().MaxTop(10);
            endpoints.MapODataRoute("odata", "odata", GetEdmModel());
        });

        app.UseSwagger();

        app.UseSwaggerUI(c =>
        {
            c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
        });
    }

    IEdmModel GetEdmModel()
    {
        var builder = new ODataConventionModelBuilder();
        builder.EntitySet<WeatherForecast>("WeatherForecast");
        return builder.GetEdmModel();
    }

控制器

[ApiController]
[Route("odata/[controller]/[action]")]
public class WeatherForecastController : ControllerBase
{
    private static readonly string[] Summaries = new[]
    {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

    private readonly ILogger<WeatherForecastController> _logger;

    public WeatherForecastController(ILogger<WeatherForecastController> logger)
    {
        _logger = logger;
    }

    [HttpGet]
    [EnableQuery]
    public IEnumerable<WeatherForecast> Get()
    {
        var rng = new Random();
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = rng.Next(-20, 55),
            Summary = Summaries[rng.Next(Summaries.Length)]
        })
        .ToArray();
    }


    [HttpGet]
    [ODataRoute]
    [EnableQuery(HandleNullPropagation = HandleNullPropagationOption.False, MaxTop = 100, AllowedQueryOptions = AllowedQueryOptions.Select | AllowedQueryOptions.Count)]
    public IEnumerable<WeatherForecast> Getlist(ODataQueryOptions options)
    { }
}

推荐阅读