Swashbuckle set manualy operationId

时间:2016-09-09 13:44:13

标签: c# asp.net-web-api swagger asp.net-web-api-routing swashbuckle

我需要知道是否可以设置自定义操作ID或命名约定,我的意思是我知道操作过滤器可以覆盖如何生成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>();

现在这有助于改变招摇的描述,请查看以下内容:

enter image description here

一切都很好,现在我最终在一个更黑暗的地方,例如类似于可能的情况:在同一个控制器上我有两个端点

  • 发布:/ customer boddy:{email,location ....}
  • 发布:/ customer / search boddy:{a filter,whatever}

示例不太正确(最后一篇文章应该是get)但是仍然假设webapi无法更改(用于分离的新控制器)对于这个特定情况我将尝试找出一种方法来为每个生成operationId diffrent以某种方式行动,但我的问题是:

  

是否有可能以某种方式装饰与之类似的控制器动作   [JsonIgnore]或[Route(&#34; customer / delete&#34;)],明确 operationId

3 个答案:

答案 0 :(得分:21)

您可以使用Swashbuckle提供的SwaggerOperationAttribute

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

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

您可以使用该属性为您的操作添加标签和方案。看看source code

答案 1 :(得分:2)

对于swashbuckle 5.0,您可以使用Name属性

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

here

列出了其他一些选项

答案 2 :(得分:1)

UPDATE:在Visual Studio中导入功能性rest API而不需要进行大量重构(手动添加名称)

我已经更新了一下自定义操作过滤器,这个过滤器在99%的情况下会生成唯一ID。剩下的百分比来自不幸的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(x.schema?.@ref.Split('/').LastOrDefault()))
                {
                    refsSwaggerIds += x.schema?.@ref.Split('/').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 ...