web-dev-qa-db-ja.com

スワッシュバックルが手動で設定されたoperationId、同じ動詞の複数の操作

カスタムoperationidまたは命名規則を設定できるかどうかを知る必要があります。つまり、operationIdの生成方法で操作フィルターを上書きできることを知っています。

https://Azure.Microsoft.com/en-us/documentation/articles/app-service-api-dotnet-swashbuckle-customize/

using Swashbuckle.Swagger;
using System.Web.Http.Description;

namespace Something
{
    public class MultipleOperationsWithSameVerbFilter : IOperationFilter
    {
        public void Apply(
            Operation operation,
            SchemaRegistry schemaRegistry,
            ApiDescription apiDescription)
        {
            if (operation.parameters != null)
            {
                operation.operationId += "By";
                foreach (var parm in operation.parameters)
                {
                    operation.operationId += string.Format("{0}",parm.name);
                }
            }
        }
    }
}

swaggerConfig.cs

 c.OperationFilter<MultipleOperationsWithSameVerbFilter>();

これはswaggerの説明を変換するのに役立ちます。以下を確認してください:

enter image description here

すべて順調です。今度は別の問題が発生します。5月の場合と同様の例:同じコントローラ上に2つのエンドポイントがあります。

  • 投稿:/ customer boddy:{メール、場所...}
  • 投稿:/ customer/search boddy:{フィルター、何でも}

この例は完全に正しくはありませんが(最後の投稿はgetである必要があります)、この特定のケースではwebapiを変更できない(分離用の新しいコントローラー)と仮定します。しかし私の質問はこれです:

[JsonIgnore]または[Route( "customer/delete")]と同様のコントローラーアクションを何らかの方法で装飾して、operationId

16
SilentTremor

[〜#〜] edit [〜#〜]この回答は、Swashbuckle 5.6と.NET Frameworkに関連しています。スワッシュバックルと.NET Coreについては mwilsonの回答 をお読みください

そのためにSwashbuckleが提供するSwaggerOperationAttributeを使用できます。

[SwaggerOperation("get")]
public IEnumerable<Contact> Get()
{
    ....
}

[SwaggerOperation("getById")]
public IEnumerable<Contact> Get(string id)
{
    ...
}

ところで、この属性を使用して、操作にタグやスキームを追加することもできます。 ソースコード を見てください

25
venerik

Swashbuckle 5.0の場合、Name属性を使用できます

[HttpGet("{id}", Name = "GetProductById")]
public IActionResult Get(int id) // operationId = "GetProductById"'

リストされている他のいくつかのオプションがあります ここ

5
mwilson

PDATE:多くのリファクタリングなしでVisual Studioに機能的な残りのAPIをインポートする(手動での操作名の追加)

カスタム操作フィルターを少し更新しました。これにより、99%のケースで一意のIDが生成されます。残りの1パーセントは、残念なAPI実装によるものです。

  public class MultipleOperationsWithSameVerbFilter : IOperationFilter
    {
        public void Apply(
            Operation operation,
            SchemaRegistry schemaRegistry,
            ApiDescription apiDescription)
        {
            string refsSwaggerIds = string.Empty;
            operation.parameters?.ForEach(x =>
            {
                if (!string.IsNullOrEmpty(x.schema?.@ref) &&
                    !string.IsNullOrEmpty([email protected]('/').LastOrDefault()))
                {
                    refsSwaggerIds += [email protected]('/').LastOrDefault();
                }
                else
                {
                    refsSwaggerIds += x.name;
                }
            });
            operation.operationId += !string.IsNullOrEmpty(refsSwaggerIds)
                ? refsSwaggerIds
                : apiDescription.RelativePath?.Replace("/", "_").Replace("{", "").Replace("}", "");
        }
    }


 public class HandleComplexTypesFromUri : IOperationFilter
    {
        public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
        {
            //this is incorect form swager helper pov, but for rest api import in visual studio is the only way for GET with complex type to be imported
            if (operation.parameters == null || apiDescription.HttpMethod.Method != "GET")
                return;
            var models = schemaRegistry.Definitions;
            var apiParams = apiDescription.ParameterDescriptions;

            if (apiParams.Count == operation.parameters.Count) return;
            foreach (var apiParameterDescription in apiParams)
            {
                if (!models.ContainsKey(apiParameterDescription.ParameterDescriptor.ParameterType.Name))
                    continue;
                operation.parameters =
                    operation.parameters.Where(
                        x =>
                            x.@in != "query" ||
                            (x.@in == "query" && !x.name.StartsWith(apiParameterDescription.Name + "."))).ToList();
                if (operation.parameters.Count(x => x.name == apiParameterDescription.Name) == 0)
                {
                    //var t = Type.GetType(apiParameterDescription.ParameterDescriptor.ParameterType.Name);
                    operation.parameters.Add(new Parameter
                    {
                        name = apiParameterDescription.Name.ToLowerInvariant(),
                        //type = apiParameterDescription.ParameterDescriptor.ParameterType.Name,
                        @in = "query",
                        required = true,
                        schema = schemaRegistry.GetOrRegister(apiParameterDescription.ParameterDescriptor.ParameterType)
                        //schema = models[apiParameterDescription.ParameterDescriptor.ParameterType.Name]
                    });
                }
            }
        }

Swagger構成で使用

GlobalConfiguration.Configuration 
                .EnableSwagger(c =>
                   // at some point
                 c.OperationFilter<HandleComplexTypesFromUri>();
                 c.OperationFilter<MultipleOperationsWithSameVerbFilter>();
})// the rest ...
1
SilentTremor