【问题标题】:Asp.NET Core 3.1 and Swashbuckle.AspNetCore.SwaggerAsp.NET Core 3.1 和 Swashbuckle.AspNetCore.Swagger
【发布时间】:2020-01-30 18:58:17
【问题描述】:

我将我的 asp.net 核心应用程序更新到 v3.1 并将我的 Swagger 表单 v5.04 rc 更新到 v5.0,一切都停止工作了。 API 正在运行,但我无法生成 swagger 文件,但我能够。

这是我的招摇配置。

public static class SwaggerConfig
    {
        [Obsolete]
        public static void ConfigureSWAGGER(this IServiceCollection serviceColletion)
        {
            if (serviceColletion == null)
            {
                throw new ArgumentNullException(nameof(serviceColletion));
            }

            // Use http://localhost:5000/swagger/ui/index to inspect API docs
            serviceColletion.AddSwaggerGen(x =>
            {
                x.SwaggerDoc(Constatns.BackofficeSwaggerGroup, new OpenApiInfo { Title = "Portal Nekretnine - Backoffice", Version = Constatns.BackofficeSwaggerGroup });
                x.SwaggerDoc(Constatns.PublicSwaggerGroup, new OpenApiInfo { Title = "Portal Nekretnine - Public", Version = Constatns.PublicSwaggerGroup });

                // This code allow you to use XML-comments
                string xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
                string xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
                if (File.Exists(xmlPath))
                {
                    x.IncludeXmlComments(xmlPath);
                }

                x.AddSecurityDefinition
                (
                    "Bearer",
                    new OpenApiSecurityScheme
                    {
                        In = ParameterLocation.Header,
                        Description = "Please enter token into the field",
                        Name = "Authorization",
                        Type = SecuritySchemeType.ApiKey
                    }
                );
            });
        }

        public static void UseSWAGGER(this IApplicationBuilder applicationBuilder)
        {
            // Enable middleware to serve generated Swagger as a JSON endpoint.
            applicationBuilder.UseSwagger();

            // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
            // specifying the Swagger JSON endpoint.
            applicationBuilder.UseSwaggerUI(x =>
            {
                x.SwaggerEndpoint($"/swagger/{Constatns.BackofficeSwaggerGroup}/swagger.json", "Portal Nekretnine - Backoffice");
                x.SwaggerEndpoint($"/swagger/{Constatns.PublicSwaggerGroup}/swagger.json", "Portal Nekretnine - Public");
            });
        }
    }

这是我的 startup.cs

public partial class Startup
    {
        public IConfiguration Configuration { get; }

        public Startup(IConfiguration configuration, IWebHostEnvironment env)
        {
            Configuration = configuration;

            if (env.IsDevelopment())
            {
                IConfigurationBuilder builder = new ConfigurationBuilder()
                                                                        .SetBasePath(env.ContentRootPath)
                                                                        .AddJsonFile($"appsettings.development.json", optional: true)
                                                                        .AddEnvironmentVariables();

                Configuration = builder.Build();
            }
            else
            {
                IConfigurationBuilder builder = new ConfigurationBuilder()
                                                                        .AddJsonFile($"appsettings.production.json", optional: true)
                                                                        .AddEnvironmentVariables();

                Configuration = builder.Build();
            }
        }

        // This method gets called by the runtime. Use this method to add services to the container.
        [System.Obsolete]
        public void ConfigureServices(IServiceCollection services)
        {
            SetServices(services);

            services.ConfigureCOMPRESSION();

            //disable built in model validator
            services.Configure<ApiBehaviorOptions>(options =>
            {
                options.SuppressModelStateInvalidFilter = true;
            });

            services.AddMvcCore(options =>
                            {
                                //Validate model
                                options.Filters.Add(typeof(ValidateModelAttribute));

                                // Add "Cache-Control" header
                                options.Filters.Add(typeof(CacheControlFilter));

                                // Add custom binder provider for mapping json object form multipart/form-data
                                options.ModelBinderProviders.Insert(0, new JsonModelBinderProvider());
                            })
                            .SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
                            .AddApiExplorer();

            services.AddControllers()
                            .AddNewtonsoftJson(options =>
                            {
                                options.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver();
                                options.SerializerSettings.Converters.Add(new JsonDateConverter());
                                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                                options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
#if DEBUG
                                options.SerializerSettings.Formatting = Formatting.Indented;
#else
                                options.SerializerSettings.Formatting = Formatting.None;
#endif
                            });

            services.Configure<ForwardedHeadersOptions>(options =>
            {
                options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
            });

            services.ConfigureCookieAuthentication();
            services.ConfigureAUTH(Configuration);

            services.ConfigureCORS();

            services.ConfigureSWAGGER();
            services.AddSwaggerGenNewtonsoftSupport(); // explicit opt-in - needs to be placed after AddSwaggerGen()
        }

        // 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();
            }
            else
            {
                app.UseHsts();
            }

            app.UseRouting();

            app.UseCOMPRESSION();

            app.UseAUTH();
            app.UseAuthorization();

            app.UseCORS();
            app.UseSWAGGER();

            app.UseHttpStatusCodeExceptionMiddleware();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }

以及我的控制器示例:

[ApiController]
public class SecurityController : ControllerBase
{

        [ApiExplorerSettings(GroupName = Constatns.PublicSwaggerGroup)]
        [SwaggerOperation(OperationId = "registerVisitor")]
        [HttpPost("api/register/visitor")]
        [ValidateModel]
        [AllowAnonymous]
        [ProducesResponseType((int)HttpResponseType.OK, Type = typeof(TokenResponse))]
        [ProducesResponseType((int)HttpResponseType.BadRequest)]
        [Produces("application/json")]
        public async Task<TokenResponse> RegisterVisitor([FromBody] RegisterVisitorRequest data)
        {}
}

我得到的错误是:

失败:Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1] 执行请求时发生未处理的异常。 System.MissingMethodException:找不到方法:'无效 Microsoft.OpenApi.Writers.OpenApiJsonWriter..ctor(System.IO.TextWriter)'。 在 Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.RespondWithSwaggerJson(HttpResponse 响应,OpenApiDocument 招摇) 在 System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine&stateMachine) 在 Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.RespondWithSwaggerJson(HttpResponse 响应,OpenApiDocument 招摇) 在 Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext,ISwaggerProvider swaggerProvider) 在 Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext 上下文) 在 Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext 上下文) 在 Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.g__Awaited|6_0(ExceptionHandlerMiddleware 中间件,HttpContext 上下文,任务任务)

thnx

【问题讨论】:

    标签: swagger swashbuckle asp.net-core-3.1


    【解决方案1】:

    我可以通过以下方式回复:

    首先,

    1-Install-Package Swashbuckle.AspNetCore
    

    第二, 在 Startup.cs 中,插入这个方法:

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

    第三, 在 ConfigureServies 方法中调用 ConfigureSwagger 方法如下:

    ConfigureSwagger(services)

    第四, 在配置方法中插入这些代码,

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

    最后, 在您的 API 项目中右键单击,在 debug 选项中, 在浏览器启动选项前,删除文本框的内容并 在文本框中写 swagger

    运行项目

    锁好。

    enter code here

    【讨论】:

      【解决方案2】:

      经过数小时的挖掘,我发现 Microsoft.OpenApi 1.2.0-preview 无法与 .net core 3.1 和 swagger v5 兼容,请使用 Microsoft OpenApi 的 v1.1.4

      【讨论】:

      • 你好?您能否提供更多有关修复的信息?
      • @SacredGeometry 您需要什么帮助?
      • 不仅仅是预览。最终发布的 1.2 不起作用。我降级到 v1.1.4 并且我的 Swagger 页面已备份。感谢您将数小时的工作变成 3 分钟的 Google 搜索!给我点赞。
      • 谢谢,尝试了 V1.2.0 版本,也遇到了同样的问题。降级到 V1.1.4 也为我解决了这个问题。
      • V1.2.0 版本不工作。不得不降级到 V1.1.4
      【解决方案3】:

      使用 Swashbuckle.AspNetCore 而不是 Swashbuckle.AspNetCore.Swagger 为我解决了这个问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-01-22
        • 2021-12-25
        • 1970-01-01
        • 2020-07-19
        • 2020-06-21
        • 2021-07-16
        • 2021-03-06
        相关资源
        最近更新 更多