Swashbuckle(Swagger)中的默认模型示例

时间:2015-03-07 03:22:18

标签: asp.net-web-api asp.net-web-api2 swagger swagger-ui

我正在运行ASP WebAPI 2并成功安装了Swashbuckle。我想弄清楚如何定义默认架构值是什么?

例如,在Swagger现场演示网站上,他们将宠物的默认值更改为" doggie"。他们还定义了状态的允许值。 (Live Demo

Example 1 Example 2

6 个答案:

答案 0 :(得分:12)

我设法通过关注此链接上的内容来实现这一目标:

https://github.com/domaindrivendev/Swashbuckle/issues/69#issuecomment-53953785

简而言之,这是需要做的事情:

  1. 按照链接中的描述创建SwaggerDefaultValue和AddDefaultValues类。我做了一些改变:

    public class SwaggerDefaultValue : Attribute
    {
        public string Name { get; set; }
        public string Value { get; set; }
    
        public SwaggerDefaultValue(string value)
        {
            this.Value = value;
        }
    
        public SwaggerDefaultValue(string name, string value) : this(value)
        {
            this.Name = name;
        }
    }
    
    public class AddDefaultValues : IOperationFilter
    {
        public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
        {
            IDictionary<string, object> parameterValuePairs =
            GetParameterValuePairs(apiDescription.ActionDescriptor);
    
            foreach (var param in operation.parameters)
            {
                var parameterValuePair = parameterValuePairs.FirstOrDefault(p => p.Key.IndexOf(param.name, StringComparison.InvariantCultureIgnoreCase) >= 0);
                param.@default = parameterValuePair.Value;
            }
        }
    
        private IDictionary<string, object> GetParameterValuePairs(HttpActionDescriptor actionDescriptor)
        {
            IDictionary<string, object> parameterValuePairs = new Dictionary<string, object>();
    
            foreach (SwaggerDefaultValue defaultValue in actionDescriptor.GetCustomAttributes<SwaggerDefaultValue>())
            {
                parameterValuePairs.Add(defaultValue.Name, defaultValue.Value);
            }
    
            foreach (var parameter in actionDescriptor.GetParameters())
            {
                if (!parameter.ParameterType.IsPrimitive)
                {
                    foreach (PropertyInfo property in parameter.ParameterType.GetProperties())
                    {
                        var defaultValue = GetDefaultValue(property);
    
                        if (defaultValue != null)
                        {
                             parameterValuePairs.Add(property.Name, defaultValue);
                        }
                    }
                }
            }
    
            return parameterValuePairs;
        }
    
        private static object GetDefaultValue(PropertyInfo property)
        {
            var customAttribute = property.GetCustomAttributes<SwaggerDefaultValue>().FirstOrDefault();
    
            if (customAttribute != null)
            {
                return customAttribute.Value;
            }
    
            return null;
        }
    }
    
    1. 编辑SwaggerConfig并将AddDefaultValues类添加到OperationFilters:

      GlobalConfiguration.Configuration
          .EnableSwagger(c => {
                ...
                c.OperationFilter<AddDefaultValues>()
                ...
           });
      
    2. 现在,对于我想要默认值的参数,我只需添加以下内容:

      public IHttpActionResult Put([FromBody]Pet pet)
      {
         ...
         return Ok();
      }
      
      public class Pet {
          [SwaggerDefaultValue("doggie")]
          public string Name { get; set; }
      
          [SwaggerDefaultValue("available")]
          public string Status;
      
          ...
      }
      

答案 1 :(得分:10)

vgaspar.trivix的代码对我来说不起作用,没有为架构设置默认值。我也得到了AsyncAppender。我通过编辑NullPointerException方法并按照以下方式操作schemaRegistry,设法让它按预期工作:

Apply

答案 2 :(得分:7)

可以通过实现ISchemaFilter并使用以下内容注册来定义示例模型:

httpConfig 
    .EnableSwagger(c =>
         {
             c.SchemaFilter<AddSchemaExamples>()
         });

此处提供了一个示例实现:

public class AddSchemaExamples : ISchemaFilter
{
    public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type)
    {
        if (type == typeof(Product))
        {
            schema.example = new Product
                {
                    Id = 123,
                    Type = ProductType.Book,
                    Description = "Treasure Island",
                    UnitPrice = 10.0M
                };
        }
    }
}

Source: https://github.com/domaindrivendev/Swashbuckle/issues/162

答案 3 :(得分:1)

我知道这个帖子已经很老了,但我想分享我的解决方案,它为Swagger示例模式创建了一个自定义构造函数。

在我的模特中:

/// <summary>
/// Supply a custom constructor for Swagger where you can apply defaults to control the example schema.  
/// The constructor must have one parameter of type System.Reflection.ParameterInfo[].
/// Note: Setting a property to null will prevent it from showing in the Swagger example.
/// </summary>System.Reflection.ParameterInfo[].
/// </summary>
public class SwaggerConstructor : Attribute { }

在SwaggerConfig.cs中:

c.SchemaFilter<ApplySchemaVendorExtensions>();

架构扩展:

    public class ApplySchemaVendorExtensions : ISchemaFilter
{
    public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type)
    {
        ConstructorInfo constructor = type.GetConstructors().FirstOrDefault(c => c.GetCustomAttribute<SwaggerConstructor>() != null);
        if (constructor != null)
        {
            schema.example = constructor.Invoke(new object[] { constructor.GetParameters() });
        }
    }
}

用法:

    [SwaggerConstructor]
    public MyClass(System.Reflection.ParameterInfo[] decoy) : base()
    {
        MyProperty = false;
    }

答案 4 :(得分:1)

偶然发现这一点,您还可以在XML文档中设置标签,在我的一个模型中,我已经定义了

    /// <summary>
    /// Note content
    /// </summary>
    /// <example>Any text for a note.</example>
    public string Note { get; set; }

当选择“立即尝试”时,最终变成了招摇的文档中的

enter image description here

希望对某人有帮助!

答案 5 :(得分:0)

将 .NET 5 与 Swashbuckle.AspNetCore 5.6.3 一起使用,我能让它有效工作的唯一方法是:

public class ExampleDocFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        string ToCamelCase(string name) => char.ToLowerInvariant(name[0]) + name.Substring(1);
        if (schema.Properties == null) return;

        var setProperties = context.Type.GetProperties().ToList().Where(f => f.GetCustomAttribute<DefaultValueAttribute>() != null).Where(f => schema.Properties.Any(n => n.Key.Equals(ToCamelCase(f.Name)))).ToDictionary(f => f, f => f.GetCustomAttribute<DefaultValueAttribute>());
        foreach (var prop in setProperties) schema.Properties[ToCamelCase(prop.Key.Name)].Example = OpenApiAnyFactory.CreateFor(schema.Properties[ToCamelCase(prop.Key.Name)], prop.Value.Value);

    }
}

要使用它 - 在您的 startup.cs 中:

services.AddSwaggerGen(swagger => {
  ...
  swagger.SchemaFilter<ExampleDocFilter>(); 
});