My Environment: Asp.NET WebAPI、NET Framework 4.5.2、Swashbuckle.Core 5.6.0
For some reason, My controller must Inherit the previous same Controller, like this
public class User100Controller : ApiController
{
[HttpGet]
[AllowAnonymous]
public virtual string Get()
{
return "1.0.0";
}
}
public class User101Controller : User100Controller
{
[HttpGet]
[AllowAnonymous]
public override string Get()
{
return "1.0.1";
}
}
Run directly, and swagger ui page show correctly
sample picture, pls right click
But if I add a Post Action with params, swagger ui do not recongnize Request Model
UserModel and UserModelSex
/// <summary>
/// UserModel
/// </summary>
public class UserModel
{
/// <summary>
/// Name
/// </summary>
public string name { get; set; } = string.Empty;
/// <summary>
/// Age
/// </summary>
public int age { get; set; } = 0;
}
/// <summary>
/// UserModelSex
/// </summary>
public class UserModelSex : UserModel
{
/// <summary>
/// Sex
/// </summary>
public int sex { get; set; } = -1;
}
User100Controller
[HttpPost]
[SwaggerResponse(200, "success", typeof(UserModel))]
public virtual IHttpActionResult SaveUser([FromBody] UserModel model)
{
if (string.IsNullOrEmpty(model.name) || model.age == 0)
{
return Ok("error");
}
//...
return Ok("success");
}
sample picture, pls right click
This is correct effect, Now if I override this SaveUser Action in User101ontroller, and pass the new request model UserModelSex, I got an error, Because of Override Method must have the same param List with the parent Method, So I change it like this
public class User100Controller : ApiController
{
[HttpPost]
[SwaggerResponse(200, "success", typeof(UserModel))]
public virtual IHttpActionResult SaveUser([FromBody] JObject json)
{
var model = json.ToObject<UserModel>();
if (string.IsNullOrEmpty(model.name) || model.age == 0)
{
return Ok("error");
}
//...
return Ok("success");
}
}
public class User101Controller : User100Controller
{
[HttpPost]
[SwaggerResponse(200, "success", typeof(UserModelSex))]
public override IHttpActionResult SaveUser([FromBody] JObject json)
{
var model = json.ToObject<UserModelSex>();
if (string.IsNullOrEmpty(model.name) || model.age == 0 || model.sex == -1)
{
return Ok("error");
}
//...
return Ok("success");
}
}
swagger ui do not recongnize JObject
sample picture, pls right click
how to show UserModel and UserModeSex in request model, like pic 2
Finally, I solve it by myself
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class SwaggerRequestModelAttribute : Attribute
{
public Type RequestModel { get; private set; }
public string ModelName { get; private set; }
public SwaggerRequestModelAttribute(Type requestModel)
{
RequestModel = requestModel;
ModelName = requestModel.Name;
}
}
[HttpPost]
[SwaggerRequestModel(typeof(UserModel))]
public virtual IHttpActionResult SaveUser([FromBody] JObject json)
{
var model = json.ToObject<UserModel>();
if (string.IsNullOrEmpty(model.name) || model.age == 0)
{
return Ok("error");
}
//...
return Ok("success");
}
public class ModelInBodyOperationFilter : IOperationFilter
{
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
{
if (operation.parameters == null) operation.parameters = new List<Parameter>();
var attribute = apiDescription.GetControllerAndActionAttributes<SwaggerRequestModelAttribute>();
if (attribute.Any())
{
if (operation.parameters.Count > 0 && operation.parameters[0].schema.type == "object")
{
if (!schemaRegistry.Definitions.ContainsKey(attribute.First().ModelName))
schemaRegistry.GetOrRegister(attribute.First().RequestModel);
operation.parameters.RemoveAt(0);
operation.parameters.Add(new Parameter
{
name = "-",
@in = "body",
required = true,
schema = new Schema { @ref = $"#/definitions/{attribute.First().RequestModel.Namespace}.{attribute.First().ModelName}" }
});
}
}
}
}
c.UseFullTypeNameInSchemaIds();
c.OperationFilter<ModelInBodyOperationFilter>();