您可以使用Custom Model Binding。众所周知,传入的请求数据和应用模型之间的映射是由模型绑定器处理的,通过使用自定义模型绑定,我们可以在将输入绑定到应用模型之前对其进行转换,我们还可以验证值。
在您的场景中,您可以创建一个自定义活页夹,如下所示:
//required using Microsoft.AspNetCore.Mvc.ModelBinding;
//required using Newtonsoft.Json.Linq;
//required using System.Threading.Tasks;
//required using WebApplication.Models; //The MyDto class is in the Models folder.
public class MyDtoEntityBinder : IModelBinder
{
public Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
string valueFromBody = string.Empty;
//get value from request body.
//if you want to get value from the form, try to get the value from the ValueProvider, code like this: bindingContext.ValueProvider.GetValue("FirstProp");
using (var sr = new StreamReader(bindingContext.HttpContext.Request.Body))
{
valueFromBody = sr.ReadToEnd();
}
if (string.IsNullOrEmpty(valueFromBody))
{
return Task.CompletedTask;
}
int firstProp = 0, secondProp =0;
if(JObject.Parse(valueFromBody).ContainsKey("FirstProp"))
firstProp = Convert.ToInt32(((JValue)JObject.Parse(valueFromBody)["FirstProp"]).Value);
if(JObject.Parse(valueFromBody).ContainsKey("SecondProp"))
secondProp = Convert.ToInt32(((JValue)JObject.Parse(valueFromBody)["SecondProp"]).Value);
//create a new object.
var result = new MyDto()
{
FirstProp = firstProp,
SecondProp = secondProp,
ThirdProp = firstProp + secondProp
};
bindingContext.Result = ModelBindingResult.Success(result);
return Task.CompletedTask;
}
}
然后,在模型上应用 ModelBinder 属性:
[ModelBinder(BinderType = typeof(MyDtoEntityBinder))]
public class MyDto
{
public int FirstProp { get; set; }
public int SecondProp { get; set; }
// Make it optional
// On request set its value equal to the sum of FirstProp and SecondProp
public int ThirdProp { get; set; }
}
API 控制器:
// POST api/<MyController>
[HttpPost]
public IActionResult Post([FromBody]MyDto myDto)
{
return Ok(myDto);
}
结果如下:
【注意】在调试上述示例代码时,如果遇到Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true错误。尝试在 Startup.cs 中允许同步 IO:
public void ConfigureServices(IServiceCollection services)
{
// If using Kestrel:
services.Configure<KestrelServerOptions>(options =>
{
options.AllowSynchronousIO = true;
});
// If using IIS:
services.Configure<IISServerOptions>(options =>
{
options.AllowSynchronousIO = true;
});
}
有关使用自定义模型绑定的更多详细信息,请参阅以下文章:
Custom model binder sample
Custom Model Binding In ASP.NET Core MVC