C# .Net核心Api无法在模型验证失败时访问原始值
我无法访问未通过模型验证的原始值。我怀疑ModelStateEntry中的AttemptedValue和/或RawValue包含原始值,但是这两个属性都null 为了澄清,我编写了一个简约的api来展示这个问题 要验证的模型:C# .Net核心Api无法在模型验证失败时访问原始值,c#,asp.net,asp.net-core,asp.net-core-webapi,C#,Asp.net,Asp.net Core,Asp.net Core Webapi,我无法访问未通过模型验证的原始值。我怀疑ModelStateEntry中的AttemptedValue和/或RawValue包含原始值,但是这两个属性都null 为了澄清,我编写了一个简约的api来展示这个问题 要验证的模型: 公共类用户 { [电邮地址] 公共字符串电子邮件{get;set;} } 控制员: [ApiController] [路线(“测试”)] 公共类TestController:ControllerBase { [HttpPost] [ValidationFilter()]
公共类用户
{
[电邮地址]
公共字符串电子邮件{get;set;}
}
控制员:
[ApiController]
[路线(“测试”)]
公共类TestController:ControllerBase
{
[HttpPost]
[ValidationFilter()]
公共字符串测试([FromBody]用户)
{
返回用户邮箱;
}
}
验证筛选器:
public类ValidationFilterAttribute:ActionFilterAttribute,IOrderedFilter
{
公共整数顺序{get;}=int.MinValue;
重写ActionExecuting(ActionExecutingContext上下文)上的公共void
{
如果(!context.ModelState.IsValid)
{
ModelStateEntry=context.ModelState.ElementAt(0).Value;
var attemptedVal=entry.AttemptedValue;
var rawVal=entry.RawValue;
context.Result=新的OkObjectResult(rawVal);
}
}
}
当我使用此模型调用测试方法时:
{
“电子邮件”:“此处无电子邮件;)”
}
ValidationFilterAttribute代码按预期调用,但是ModelStateEntry不包含原始值。AttemptedValue和RawValue都是null:
据我所知,对于模型绑定,过滤器将调用context.ModelState.SetModelValue来设置RawValue和AttemptedValue的值 但是SystemTextJsonInputFormatter没有设置它来解决这个问题,我建议您可以尝试构建自定义扩展方法,然后重试 更多详细信息,请参考以下代码: 创建新的ModelStateJsonInputFormatter类:
public class ModelStateJsonInputFormatter : SystemTextJsonInputFormatter
{
public ModelStateJsonInputFormatter(ILogger<ModelStateJsonInputFormatter> logger, JsonOptions options) :
base(options ,logger)
{
}
public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context)
{
var result = await base.ReadRequestBodyAsync(context);
foreach (var property in context.ModelType.GetProperties())
{
var propValue = property.GetValue(result.Model, null);
var propAttemptValue = property.GetValue(result.Model, null)?.ToString();
context.ModelState.SetModelValue(property.Name, propValue, propAttemptValue);
}
return result;
}
}
公共类ModelStateJsonInputFormatter:SystemTextJsonInputFormatter
{
公共模型状态JSONInputFormatter(ILogger记录器、JsonOptions选项):
基本(选项、记录器)
{
}
公共重写异步任务ReadRequestBodyAsync(InputFormatterContext上下文)
{
var result=await base.ReadRequestBodyAsync(上下文);
foreach(context.ModelType.GetProperties()中的var属性)
{
var propValue=property.GetValue(result.Model,null);
var propAttemptValue=property.GetValue(result.Model,null)?.ToString();
context.ModelState.SetModelValue(property.Name、propValue、propAttemptValue);
}
返回结果;
}
}
在startup.cs中重新启动它:
services.AddControllersWithViews(options => {
var serviceProvider = services.BuildServiceProvider();
var modelStateJsonInputFormatter = new ModelStateJsonInputFormatter(
serviceProvider.GetRequiredService<ILoggerFactory>().CreateLogger<ModelStateJsonInputFormatter>(),
serviceProvider.GetRequiredService<IOptions<JsonOptions>>().Value);
options.InputFormatters.Insert(0, modelStateJsonInputFormatter);
});
services.addcontrollerswithview(选项=>{
var serviceProvider=services.BuildServiceProvider();
var modelStateJsonInputFormatter=新modelStateJsonInputFormatter(
serviceProvider.GetRequiredService().CreateLogger(),
serviceProvider.GetRequiredService().Value);
options.InputFormatters.Insert(0,modelStateJsonInputFormatter);
});
结果: