【问题标题】:Fetch error Not Found /swagger/WaterMasterDataOpenApiSpecification/swagger.json for .NET Core 3.1 API using Swagger使用 Swagger 为 .NET Core 3.1 API 获取错误未找到 /swagger/WaterMasterDataOpenApiSpecification/swagger.json
【发布时间】:2020-11-27 23:26:35
【问题描述】:

我如何帮助 Swagger 找到它的文档?我已经阅读了多篇关于 Swagger 文档的文章。基本上,我的问题是我可以让 Swagger 在本地主机上工作,但是一旦我们的 API 部署到我们的服务器,我就无法让 Swagger 工作,当我尝试让 Swagger 在开发、测试和生产服务器上工作时,我在本地主机上破解它。

当 Swagger 在本地主机上工作时,这是我的 Startup.cs 中的代码。

    public void ConfigureServices(IServiceCollection services)
    {
        
        services
            .AddCors()
            .AddDbContext<OurDbContext1>(options =>
                options.UseSqlServer(Configuration["ConnectionStrings:OurDatabase1"]))
            .AddDbContext<OurDbContext2>(options =>
                options.UseSqlServer(Configuration["ConnectionStrings:OurDatabase2"]))
            .AddRazorPages()
            .ConfigureApiBehaviorOptions(setupAction =>
            {
                setupAction.InvalidModelStateResponseFactory = context =>
                {
                    var problemDetails = new ValidationProblemDetails(context.ModelState)
                    {
                        Title = "One or more model validation errors occurred",
                        Status = StatusCodes.Status422UnprocessableEntity,
                        Detail = "See the errors property for details",
                        Instance = context.HttpContext.Request.Path
                    };

                    problemDetails.Extensions.Add("traceId", context.HttpContext.TraceIdentifier);

                    return new UnprocessableEntityObjectResult(problemDetails)
                    {
                        ContentTypes = { "application/problem+json" }
                    };
                };
            });

        services
            .AddMvc(options => options.EnableEndpointRouting = false)
            .AddNewtonsoftJson(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());

        services
            .AddControllersWithViews();

        services
            .AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());

        services
            .AddSwaggerGen(setupAction =>
            {
                setupAction.SwaggerDoc("OurApiSpecification", new OpenApiInfo()
                {
                    Title = "Our API",
                    Version = "1"
                });
                setupAction.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
            });

        services
            .AddScoped<IRepository1, Repository1>()
            .AddScoped<IRepository2, Repository2>()
            .AddTransient<IPropertyMappingService, PropertyMappingService>()
            .AddTransient<IPropertyCheckingService, PropertyCheckingService>();

        services
            .AddAuthentication(NegotiateDefaults.AuthenticationScheme)
            .AddNegotiate();

        if (_env.IsDevelopment())
        {
            services.AddSingleton<IPolicyEvaluator, DisableAuthenticationPolicyEvaluator>();
        }
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        string[] allowedOrigins = Configuration.GetSection("CorsSettings:AllowedOrigins").Get<string[]>();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseHsts();

        app.UseCors(
                options => options
                    .WithOrigins(
                        allowedOrigins
                    )
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .AllowCredentials()
            );

        if (!env.IsDevelopment())
        {
            app.UseAuthentication();
        }

        app.UseAuthorization();

        app.UseSwagger();

        app.UseSwaggerUI(setupAction =>
        {
            setupAction.SwaggerEndpoint(
                "/swagger/OurApiSpecification/swagger.json", 
                "Our API");
        });

        app.UseMvc();
    }

但是,当我将 API 部署到服务器并尝试通过我们的 URL 访问它时,我看到 Fetch 错误 Not Found /swagger/OurApiSpecification/swagger.json,这是有道理的,因为服务器上的 API 存在于与本地不同的主机名和路径。

JSON 文档存在于 serverhostname/apifolder/ourapi/swagger/OurApiSpecification/swagger.json 的服务器上,但错误告诉我在 Startup.cs 中指定的位置找不到它,这又使感觉,因为文档不在 /swagger/OurApiSpecification/swagger.json,而是在 /apifolder/ourapi/swagger/OurApiSpecification/swagger.json。

因此,经过广泛的研究,我更改了 Startup.Configure() 以尝试在服务器上的位置引用 Swagger JSON 文档,并且,在 Startup.ConfigureServices() 中,我投入了 SwaggerGen Newtonsoft支持,但现在 Swagger 将无法在 localhost 上运行!

现在,当 Swagger 在 localhost 上不起作用时,这是我的 Startup.cs 中的代码。

public void ConfigureServices(IServiceCollection services)
    {
        services
            .AddCors()
            .AddDbContext<OurDbContext1>(options =>
                options.UseSqlServer(Configuration["ConnectionStrings:OurDatabase1"]))
            .AddDbContext<OurDbContext2>(options =>
                options.UseSqlServer(Configuration["ConnectionStrings:OurDatabase2"]))
            .AddRazorPages()
            .ConfigureApiBehaviorOptions(setupAction =>
            {
                setupAction.InvalidModelStateResponseFactory = context =>
                {
                    var problemDetails = new ValidationProblemDetails(context.ModelState)
                    {
                        Title = "One or more model validation errors occurred",
                        Status = StatusCodes.Status422UnprocessableEntity,
                        Detail = "See the errors property for details",
                        Instance = context.HttpContext.Request.Path
                    };

                    problemDetails.Extensions.Add("traceId", context.HttpContext.TraceIdentifier);

                    return new UnprocessableEntityObjectResult(problemDetails)
                    {
                        ContentTypes = { "application/problem+json" }
                    };
                };
            });

        services
            .AddMvc(options => options.EnableEndpointRouting = false)
            .AddNewtonsoftJson(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());

        services
            .AddControllersWithViews();

        services
            .AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());

        services
            .AddSwaggerGen(setupAction =>
            {
                setupAction.SwaggerDoc("OurApiSpecification", new OpenApiInfo()
                {
                    Title = "Our API",
                    Version = "1"
                });
                setupAction.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
            });

        services
            .AddSwaggerGenNewtonsoftSupport();

        services
            .AddScoped<IRepository1, Repository1>()
            .AddScoped<IRepository2, Repository2>()
            .AddTransient<IPropertyMappingService, PropertyMappingService>()
            .AddTransient<IPropertyCheckingService, PropertyCheckingService>();

        services
            .AddAuthentication(NegotiateDefaults.AuthenticationScheme)
            .AddNegotiate();

        if (_env.IsDevelopment())
        {
            services.AddSingleton<IPolicyEvaluator, DisableAuthenticationPolicyEvaluator>();
        }
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        string[] allowedOrigins = Configuration.GetSection("CorsSettings:AllowedOrigins").Get<string[]>();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseHsts();
        
        app.UseCors(
                options => options
                    .WithOrigins(
                        allowedOrigins
                    )
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .AllowCredentials()
            );

        if (!env.IsDevelopment())
        {
            app.UseAuthentication();
        }

        app.UseAuthorization();
        
        app.UseSwagger(setupAction =>
        {
            setupAction.RouteTemplate =
                "apifolder/ourapi/swagger/OurApiSpecification/swagger.json";
        });

        app.UseSwaggerUI(setupAction =>
        {
            setupAction.SwaggerEndpoint(
              "/apifolder/ourapi/swagger/OurApiSpecification/swagger.json",
                "Our API");
            setupAction.RoutePrefix = "apifolder/ourapi/swagger";
        });

        app.UseMvc();
    }

同样,找不到 JSON 文档似乎是有道理的,因为在本地,该文档不在 localhost/apifolder/ourapi/swagger/OurApiSpecification/swagger.json 中。我验证了这一点,但我不知道为什么它不在 /apifolder/ourapi/swagger/OurApiSpecification/swagger.json,因为它应该在那里......对吗?

有什么建议吗?

【问题讨论】:

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


    【解决方案1】:

    所以,我正在回答我自己的问题。我尝试了多种方法在我们的 API 中实现 Swagger。我尝试的第一个公式在这里,https://docs.microsoft.com/en-us/aspnet/core/tutorials/getting-started-with-swashbuckle?view=aspnetcore-5.0&tabs=visual-studio。由于某种原因,这种方法第一次不起作用,Swagger 在本地工作,但在我们部署到我们的服务器并在服务器主机名和路径处启动我们的 API 后就不起作用了。

    但是,这种方法现在有效,所以我发布了我的 Startup.cs,就像 Swagger 在 localhost 和我们所有服务器上工作时一样。

    public void ConfigureServices(IServiceCollection services)
        {
            services
                .AddCors()
                .AddDbContext<OurDbContext1>(options =>
                    options.UseSqlServer(Configuration["ConnectionStrings:OurDatabase1"]))
                .AddDbContext<OurDbContext2>(options =>
                    options.UseSqlServer(Configuration["ConnectionStrings:OurDatabase2"]))
                .AddRazorPages()
                .ConfigureApiBehaviorOptions(setupAction =>
                {
                    setupAction.InvalidModelStateResponseFactory = context =>
                    {
                        var problemDetails = new ValidationProblemDetails(context.ModelState)
                        {
                            Title = "One or more model validation errors occurred",
                            Status = StatusCodes.Status422UnprocessableEntity,
                            Detail = "See the errors property for details",
                            Instance = context.HttpContext.Request.Path
                        };
    
                        problemDetails.Extensions.Add("traceId", context.HttpContext.TraceIdentifier);
    
                        return new UnprocessableEntityObjectResult(problemDetails)
                        {
                            ContentTypes = { "application/problem+json" }
                        };
                    };
                });
            services
                .AddMvc(options => options.EnableEndpointRouting = false)
                .AddNewtonsoftJson(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());
            services
                .AddControllersWithViews();
            services
                .AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
            services
                .AddSwaggerGen(setupAction =>
                {
                    setupAction.SwaggerDoc("OurApiSpecification", new OpenApiInfo()
                    {
                        Title = "Our API",
                        Version = "1"
                    });
                    setupAction.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
                });
            services
                .AddSwaggerGenNewtonsoftSupport();
            services
                .AddScoped<IRepository1, Repository1>()
                .AddScoped<IRepository2, Repository2>()
                .AddTransient<IPropertyMappingService, PropertyMappingService>()
                .AddTransient<IPropertyCheckingService, PropertyCheckingService>();
            services
                .AddAuthentication(NegotiateDefaults.AuthenticationScheme)
                .AddNegotiate();
            if (_env.IsDevelopment())
            {
                services.AddSingleton<IPolicyEvaluator, DisableAuthenticationPolicyEvaluator>();
            }
        }
    
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            string[] allowedOrigins = Configuration.GetSection("CorsSettings:AllowedOrigins").Get<string[]>();
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseHsts();
            app.UseCors(
                    options => options
                        .WithOrigins(
                            allowedOrigins
                        )
                        .AllowAnyMethod()
                        .AllowAnyHeader()
                        .AllowCredentials()
                );
    
            if (!env.IsDevelopment())
            {
                app.UseAuthentication();
            }
            app.UseAuthorization();
            app.UseSwagger();
            app.UseSwaggerUI(setupAction =>
            {
                setupAction.SwaggerEndpoint(
                    "./swagger/OurApiSpecification/swagger.json",
                    "Our API");
                setupAction.RoutePrefix = string.Empty;
            });
            app.UseMvc();
        }
    

    我不知道为什么上面 Startup.cs 中的 Swagger 代码在我第一次尝试时不起作用,但是自从我们回到第 1 格并再次尝试这种方法后,Startup.cs 发生了一些变化。

    【讨论】:

      猜你喜欢
      • 2021-05-31
      • 2022-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-06
      • 2015-10-01
      • 2021-06-03
      • 1970-01-01
      相关资源
      最近更新 更多