近い見方をした後、操作フィルタを使用すると簡単にできます。
これの行に沿って何かが動作するはずです(テストされていない、コンパイルエラーがないことを確認しただけです)。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc.Controllers;
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace MyCompany.Common.Web.Swagger.OperationFilters
{
public class GenericOperationFilter : IOperationFilter
{
public void Apply(Operation operation, OperationFilterContext context)
{
if (context.ApiDescription.ActionDescriptor is ControllerActionDescriptor controllerDescriptor)
{
var baseType = controllerDescriptor.ControllerTypeInfo.BaseType?.GetTypeInfo();
// Get type and see if its a generic controller with a single type parameter
if (baseType == null || (!baseType.IsGenericType && baseType.GenericTypeParameters.Length == 1))
return;
if (context.ApiDescription.HttpMethod == "GET" && !operation.Responses.ContainsKey("200"))
{
var typeParam = baseType.GenericTypeParameters[0];
// Get the schema of the generic type. In case it's not there, you will have to create a schema for that model
// yourself, because Swagger may not have added it, because the type was not declared on any of the models
string typeParamFriendlyId = typeParam.FriendlyId();
if (!context.SchemaRegistry.Definitions.TryGetValue(typeParamFriendlyId, out Schema typeParamSchema))
{
// Schema doesn't exist, you need to create it yourself, i.e. add properties for each property of your model.
// See OpenAPI/Swagger Specifications
typeParamSchema = context.SchemaRegistry.GetOrRegister(typeParam);
// add properties here, without it you won't have a model description for this type
}
// for any get operation for which no 200 response exist yet in the document
operation.Responses.Add("200", new Response
{
Description = "Success",
Schema = new Schema { Ref = typeParamFriendlyId }
});
}
}
}
}
}
それは何? IOperationFilter
は、操作(Get、Post、Putなど)ごとに呼び出されます。その中にControllerActionDescriptor
かどうかをチェックし、そうならコントローラのタイプをチェックします。
必要に応じて、特定の種類に絞り込むことができます。私はちょうど別のクラスから継承するすべてのコントローラーを取ってきました。ベースタイプはの1つのジェネリックパラメーターで一般的です。
最後に、「取得」操作(ポスト、プット、削除は通常モデルを返さず、ステータスコード/エラー応答のみ)をチェックし、タイプが既にSwagger/OpenAPIにあるかどうかを確認しますスキーマ定義。モデルがあれば、そのスキーマを読んでレスポンスで参照してください。
モデルがスキーマレジストリに登録されていない場合、モデルはより複雑になります。リフレクションを使用してスキーマファイルをビルドし、それをリポジトリに追加してください(既にcontext.SchemaRegistry.GetOrRegister(typeParam)
呼び出し中に発生しています)。
これは、モデルが他のコントローラの応答パラメータまたはアクションパラメータとして使用されていない場合に発生します。
OpenAPI 2.0仕様について詳しくは、こちらをご覧ください。
属性を使用することはできません。しかし、自分自身の 'ISchemaFilter'や' IDocumentFilter'を書くことで、公開されているAPIドキュメントをjsonにシリアル化する直前に変更することができます – Tseng
@Tsengこのサンプルはありますか? – Jude