Nid*_*nar 5 asp.net-web-api swagger swashbuckle
我在WebApi项目中使用.Net框架4.6.1和Swashbuckle版本5.3.2。Swagger UI没有提供将输入作为请求正文发送到使用自定义模型活页夹的POST Api的选项。
-使用型号:
[ModelBinder(typeof(FieldValueModelBinder))]
public class Employee
{
public int EmployeeID { get; set; }
public string EmployeeName { get; set; }
public string City { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
-使用的API Post方法:
[HttpPost]
// POST: api/Employee
public HttpResponseMessage Post([ModelBinder(typeof(FieldValueModelBinder))]Employee emp)
{
if (!ModelState.IsValid)
return Request.CreateResponse(HttpStatusCode.BadRequest, "Please provide valid input");
else
//Add Employee logic here
return Request.CreateResponse(HttpStatusCode.OK, "Employee added sucessfully");
}
Run Code Online (Sandbox Code Playgroud)
-所用的粘合剂型号:
public class FieldValueModelBinder : System.Web.Http.ModelBinding.IModelBinder
{
/// <summary>
/// Store received data in API in KeyValuePair
/// </summary>
private List<KeyValuePair<string, string>> kvps;
/// <summary>
/// Storing error while binding data in Model class
/// </summary>
private Dictionary<string, string> dictionaryErrors = new Dictionary<string, string>();
/// <summary>
/// Implementing Base method and binding received data in API to its respected property in Model class
/// </summary>
/// <param name="actionContext">Http Action Context</param>
/// <param name="bindingContext">Model Binding Context</param>
/// <returns>True if no error while binding. False if any error occurs during model binding</returns>
public bool BindModel(HttpActionContext actionContext, System.Web.Http.ModelBinding.ModelBindingContext bindingContext)
{
try
{
var bodyString = actionContext.Request.Content.ReadAsStringAsync().Result;
if (actionContext.Request.Method.Method.ToUpper().Equals("GET"))
{
var uriContext = HttpUtility.ParseQueryString(actionContext.Request.RequestUri.Query);
if (uriContext.HasKeys())
{
this.kvps = uriContext.AllKeys.ToDictionary(k => k, k => uriContext[k]).ToList<KeyValuePair<string, string>>();
}
}
else if (!string.IsNullOrEmpty(bodyString))
{
this.kvps = this.ConvertToKvps(bodyString);
}
else
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Please provide valid input data.");
return false;
}
}
catch (Exception ex)
{
bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Please provide data in a valid format.");
return false;
}
// Initiate primary object
var obj = Activator.CreateInstance(bindingContext.ModelType);
try
{
this.SetPropertyValues(obj);
}
catch (Exception ex)
{
if (this.dictionaryErrors.Any())
{
foreach (KeyValuePair<string, string> keyValuePair in this.dictionaryErrors)
{
bindingContext.ModelState.AddModelError(keyValuePair.Key, keyValuePair.Value);
}
}
else
{
bindingContext.ModelState.AddModelError("Internal Error", ex.Message);
}
this.dictionaryErrors.Clear();
return false;
}
// Assign completed Mapped object to Model
bindingContext.Model = obj;
return true;
}
Run Code Online (Sandbox Code Playgroud)
我面临以下问题:
当我们在post方法中使用'ModelBinder'时,Swagger UI将显示此屏幕,在该屏幕上,输入参数被发布在查询字符串中,并且调用CustomModelBinder并尝试读取请求主体以执行模型绑定和验证,并且在这种情况下为null。
公共HttpResponseMessage Post([ModelBinder(typeof(FieldValueModelBinder))]雇员emp)
当我们在post方法中使用'FromBody'时,Swagger UI将显示此
屏幕,我们可以在其中将输入发送到请求正文中,但是在这种
情况下,不会调用CustomModelBinder,并且我们无法执行模型绑定和验证。
公共HttpResponseMessage Post([FromBody] Employee emp)
当我们尝试同时使用'modelbinder'和'frombody'时,Swagger UI将输入作为查询,并且得到以下响应:
经过与Postman的尝试,该API可以正常工作,并且我们能够在请求正文中传递输入并获得正确的输出。在模型状态无效的情况下,自定义模型绑定也可以工作并填充错误消息,然后我们可以使用这些消息发送响应。
在将输入数据发布到请求正文中的API时,需要进行哪些更改才能从Swagger UI调用自定义模型绑定程序。请提出建议。
您可以使用以下代码来做到这一点IDocumentFilter:
private class ApplyDocumentVendorExtensions : IDocumentFilter
{
public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry s, IApiExplorer a)
{
if (swaggerDoc != null)
{
foreach (var path in swaggerDoc.paths)
{
if (path.Value.post != null && path.Value.post.parameters != null )
{
var parameters = path.Value.post.parameters;
if (parameters.Count == 3 && parameters[0].name.StartsWith("emp"))
{
path.Value.post.parameters = EmployeeBodyParam;
}
}
}
}
}
private IList<Parameter> EmployeeBodyParam
{
get
{
return new List<Parameter>
{
new Parameter {
name = "emp",
@in = "body",
required = true,
schema = new Schema {
@ref = "#/definitions/Employee"
}
}
};
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1142 次 |
| 最近记录: |