最近、プロジェクトを.NET Core 2.0
から.NET Core 2.1
に移行しました。その結果、Swaggerドキュメントサイトが機能しなくなりました。引き続きアクセスできます。カスタマイズされたタイトルとバージョンは表示できますが、APIドキュメントはなく、No operations defined in spec!
というメッセージのみがあります。
古いソリューションを試しました 。NET Core 2.0の場合 ですが、助けにはなりませんでした。次の2つの記事に基づいて 12 コントローラーメソッドからSwagger属性を削除し、コントローラークラスの上に[ApiController]
属性を追加しようとしましたが、どちらかを助けます。誰でもこの問題を解決するのに役立ちますか?
。csproj
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<RootNamespace>Company.Administration.Api</RootNamespace>
<AssemblyName>Company.Administration.Api</AssemblyName>
<PackageId>Company.Administration.Api</PackageId>
<Authors></Authors>
<Company>Company, Inc</Company>
<Product>Foo</Product>
<ApplicationInsightsResourceId>/subscriptions/dfa7ef88-f5b4-45a8-9b6c-2fb145290eb4/resourcegroups/Foo/providers/Microsoft.insights/components/foo</ApplicationInsightsResourceId>
<ApplicationInsightsAnnotationResourceId>/subscriptions/dfa7ef88-f5b4-45a8-9b6c-2fb145290eb4/resourceGroups/Foo/providers/Microsoft.insights/components/foo</ApplicationInsightsAnnotationResourceId>
<UserSecretsId>bf821b77-3f23-47e8-834e-7f72e2ab00c5</UserSecretsId>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DocumentationFile>bin\Debug\netcoreapp2.1\Administration.Api.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup>
<!-- Try to set version using environment variables set by GitVersion. -->
<Version Condition=" '$(Version)' == '' And '$(GitVersion_AssemblySemVer)' != '' ">$(GitVersion_AssemblySemVer)</Version>
<InformationalVersion Condition=" '$(InformationalVersion)' == '' And '$(GitVersion_InformationalVersion)' != '' ">$(GitVersion_InformationalVersion)</InformationalVersion>
<!-- If we don't have environment variables set by GitVersion, use default version. -->
<Version Condition=" '$(Version)' == '' ">0.0.1</Version>
<InformationalVersion Condition=" '$(InformationalVersion)' == '' ">0.0.1-local</InformationalVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DocumentationFile>bin\Release\netcoreapp2.1\Administration.Api.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup>
<MvcRazorCompileOnPublish>false</MvcRazorCompileOnPublish>
<PreserveCompilationContext>false</PreserveCompilationContext>
</PropertyGroup>
<ItemGroup>
<Folder Include="wwwroot\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="IdentityModel" Version="3.7.0-preview1" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="2.6.0" />
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.3.0" />
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.6" />
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.1.0" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.1.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="2.4.0" />
<PackageReference Include="Swashbuckle.AspNetCore.ReDoc" Version="2.4.0" />
</ItemGroup>
<ItemGroup>
<WCFMetadata Include="Connected Services" />
</ItemGroup>
</Project>
Startup.cs
using Company.Administration.Api.Controllers;
using Company.Administration.Api.Security;
using Company.Administration.Api.Services;
using Company.Administration.Api.Swagger;
using Company.Administration.Api.Swagger.Examples;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.PlatformAbstractions;
using Newtonsoft.Json.Converters;
using Swashbuckle.AspNetCore.Swagger;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.IO;
using System.Net.Http;
namespace Company.Administration.Api
{
public class Startup
{
public Startup(IConfiguration configuration, ILogger<Startup> logger, IHostingEnvironment hostingEnvironment)
{
Configuration = configuration;
Logger = logger;
HostingEnvironment = hostingEnvironment;
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
}
public IHostingEnvironment HostingEnvironment { get; }
public IConfiguration Configuration { get; }
public ILogger Logger { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<HttpClient>();
services.AddTransient<AuthService>();
services.AddTransient<FooAdministrationService>();
services.AddMvc()
.AddJsonOptions(options =>
{
options.SerializerSettings.Converters.Add(new StringEnumConverter());
});
services.AddFooAuthentication(Configuration);
services.AddFooAuthorization();
services.AddCors();
services
.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info { Title = "Administration", Version = "v1" });
var basePath = PlatformServices.Default.Application.ApplicationBasePath;
var xmlPath = Path.Combine(basePath, "Administration.Api.xml");
if (File.Exists(xmlPath))
{
c.IncludeXmlComments(xmlPath);
}
else
{
Logger.LogWarning($@"File does not exist: ""{xmlPath}""");
}
string authorityOption = Configuration["IdentityServerAuthentication:Url"] ?? throw new Exception("Failed to load authentication URL from configuration.");
string authority = $"{authorityOption}{(authorityOption.EndsWith("/") ? "" : "/")}";
var scopes = new Dictionary<string, string>
{
{ "api", "Allow calls to the Foo administration API." }
};
c.AddSecurityDefinition("OpenId Connect", new OAuth2Scheme
{
Type = "oauth2",
Flow = "implicit",
AuthorizationUrl = $"{authority}connect/authorize",
TokenUrl = $"{authority}connect/token",
Scopes = scopes
});
c.DescribeAllEnumsAsStrings();
c.OperationFilter<ExamplesOperationFilter>(services.BuildServiceProvider());
})
.ConfigureSwaggerGen(options =>
{
options.CustomSchemaIds(t => t.FullName);
options.OperationFilter<SecurityRequirementsOperationFilter>();
});
}
// 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();
}
app.UseCors(builder => builder
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
.WithExposedHeaders(AdministrationControllerBase.ExposedHeaders));
app.UseAuthentication();
app.UseMvc()
.UseSwagger(x => x.RouteTemplate = "api-docs/{documentName}/swagger.json")
.UseSwaggerUI(c =>
{
c.OAuthClientId("foo-administration.swagger");
c.RoutePrefix = "api-docs";
c.SwaggerEndpoint("v1/swagger.json", "Foo Administration API");
});
app.UseReDoc(options =>
{
options.RoutePrefix = "api-docs-redoc";
options.SpecUrl = "../api-docs/v1/swagger.json";
});
}
}
}
同じソリューションを行ごとに再作成しようとしました。 Swaggerは、<PreserveCompilationContext>false</PreserveCompilationContext>
を.csproj
ファイルに追加するまで機能しました。この属性を削除すると、Swagger UIが再表示されました。
C#.Netコアでは、デコレータ[HttpPost]または[HttpGet]でいくつかのメソッドを使用する場合、すべてのPOST =またはGETメソッド。
ローカルで正常に動作しているが、IISホスティング後に問題が発生している場合、swagger.json
相対パス。
次にConfigureServices
内でこれを試してください:
app.UseSwaggerUI(c =>
{
string swaggerJsonBasePath = string.IsNullOrWhiteSpace(c.RoutePrefix) ? "." : "..";
c.SwaggerEndpoint($"{swaggerJsonBasePath}/swagger/v1/swagger.json", "My API");
});
私はこれがすでに答えられていることを知っています、しかし、私はこれに出くわし、まだ答えを探している人のためにチャイムだと思っただけです。 jsonファイルに直接アクセスしようとすると、動作しない理由がわかります。
例:
アドレスバーで: https:// localhost:44300/swagger/v1/swagger.json
返されるエラーメッセージ:
{"パス": "/ swagger/v1/swagger.json"、 "Started":false、 "State": "Internal Server Error"、 "Msg": "アクションのあいまいなHTTPメソッド-Controllers.ChatMessageController.ListFriends(Project .API)。アクションにはSwagger 2.0の明示的なHttpMethodバインディングが必要です}
私には、コントローラーv1で[ApiVersionNeutral]属性を使用し、コントローラーv2で[ApiVersion( "2.0")]を使用しようとしたため、このエラーが表示されました。とにかく、出力または診断ツール([イベント]タブ)で完全なエラーメッセージを取得できます。そして、私はこのメッセージを受け取りました:
System.NotSupportedException:HTTPメソッド「GET」およびアクションによってオーバーロードされたパス「api/Employees」-Api.V2.Controllers.EmployeesController.Get、Api.V1.Controllers.EmployeesController.Get.
アクションにはSwagger 2.0の一意のメソッド/パスの組み合わせが必要です。回避策としてConflictingActionsResolverを使用してください
このエラーは、APIの他の問題によって引き起こされる場合もあります。私の場合、swaggerには、コントローラーの1つで2つのGetアクションを使用したオーバーロードの理解に問題がありました。うまくいったのは、次のようにOpen API仕様をロードすることで発生した例外を最初に調査することでした。
{https:// {Host}:{port}/swagger/{SwaggerSpecName} /swagger.json}
その後、OpenAPI仕様の読み込みを妨げるエラーが表示されました。後で、この仕様をswager genメソッドに適用することで、エラー(上記のgetアクションのオーバーロード)を解決しました。
services.AddSwaggerGen(c =>
{
other configs...;
c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
});
ここ は私を答えに導く投稿です