尝试访问swagger端点时,将Nswag与Odata结合使用会产生错误

时间:2020-01-22 06:37:44

标签: c# swagger odata asp.net-core-2.2 nswag

我们试图在asp.net核心API项目中同时使用Nswag和Odata。我们可以使用Nswag来获取API文档,也可以使用Odata来简化查询。但是,当我们同时使用它们并尝试访问API swagger文档(https://localhost:5001/swagger/index.html)时,会生成此错误: Error in Nswag and Odata

这是我的启动文件:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;


using Microsoft.AspNet.OData.Extensions;
using System.Web.Http;
using Microsoft.OpenApi.Models;
using System.Reflection;
using Newtonsoft.Json;
using Microsoft.AspNet.OData.Builder;
using GL.Data.Models.EntityClass;
using Microsoft.Net.Http.Headers;
using Microsoft.AspNet.OData.Formatter;
using Newtonsoft.Json.Serialization;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal;
using Newtonsoft.Json.Converters;

namespace GL.service
{
    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.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
            .AddJsonOptions(options =>
            {
                // Use camel case properties in the serializer and the spec (optional)
                options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
                // Use string enums in the serializer and the spec (optional)
                options.SerializerSettings.Converters.Add(new StringEnumConverter());
            });

            // registers a Swagger v2.0 document with the name "v1" (default)
            services.AddSwaggerDocument(c => { 
            c.DocumentName = "V1";
                c.Title = "GL Controller";
            }); 
            services.AddOData();

        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();

            }
            else
            {

                app.UseHsts();
            }
            app.UseCors(b => b.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin().AllowCredentials());
            app.UseHttpsRedirection();
            app.UseAuthentication();

            app.UseOpenApi(); // Serves the registered OpenAPI/Swagger documents by default on 
            app.UseSwaggerUi3(); // Serves the Swagger UI 3 web ui to view the OpenAPI/Swagger 
            app.UseMvc(routeBuilder =>
            {
                routeBuilder.EnableDependencyInjection();
                routeBuilder.Expand().Select().Filter().Count().OrderBy();
            });
        }
    }
}

请帮助解决此问题。

2 个答案:

答案 0 :(得分:3)

这里是workaround,您可以在NSwag UI加载时解决API错误。但是Swashbuckle for AspNetCore不支持OData,并且在NSwag UI中都不会显示OData端点。

>
services.AddOData();

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"));
    }
});

请记住将services.AddOData();放在services.AddMvcCore()行之前。

请参阅https://github.com/OData/WebApi/issues/1177

答案 1 :(得分:0)

如果它仍然不起作用,您可能需要添加其他解决方法: .Net 5.0 和 Microsoft.AspNetCore.OData 8.0.0-preview3

    services.AddSwaggerGen(c =>
    {
        c.DocInclusionPredicate((docName, apiDesc) =>
        {
            // Filter out 3rd party controllers
            var assemblyName = ((ControllerActionDescriptor)apiDesc.ActionDescriptor).ControllerTypeInfo.Assembly.GetName().Name;
            var currentAssemblyName = GetType().Assembly.GetName().Name;
            return currentAssemblyName == assemblyName;
        });

        c.SwaggerDoc("v1", new OpenApiInfo { Title = ApplicationConstant.APP_NAME, Version = "v1" });
    });

第一个解决方法:

services.AddOData();

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"));
    }
});

不需要使用 AddMvcCore,您也可以将代码放在 AddControllers 中。