我的环境:Asp。. NET WebAPI, . NET Framework 4.5.2, Swashbuckle。核心5.6.0
由于某些原因,我的控制器必须继承之前相同的控制器,像这样
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";
}
}
直接运行,并确保ui页面显示正确
样图,请右键单击
但是如果我用参数添加Post Action, swagger ui不识别请求模型
UserModel和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");
}
样图,请右键单击
这是正确的效果,现在如果我覆盖这个SaveUser操作,并传递新的请求模型UserModelSex,我得到了一个错误,因为重写方法必须有相同的参数列表与父方法,所以我改变它像这样
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不识别jobobject
样图,请右键单击
如何显示UserModel和UserModeSex在请求模型中,如PIC 2
最后,我自己解决了。
- 添加SwaggerRequestModelAttribute.cs
[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;
}
}
- 然后,将[SwaggerRequestModel]标记到控制器
[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");
}
- 添加ModelInBodyOperationFilter.cs
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}" }
});
}
}
}
}
- 也在SwaggerConfig.Register() 中
c.UseFullTypeNameInSchemaIds();
c.OperationFilter<ModelInBodyOperationFilter>();
- 最后,运行应用程序并预览
样图,请右键单击