[英].Net Core Api cannot access original value on model validation failures
我無法訪問未通過 model 驗證的原始值。 我懷疑ModelStateEntry中的AttemptedValue和/或RawValue包含原始值,但是這兩個屬性都是null 。
為了澄清,我寫了一個簡約的 api 來展示這個問題。
model 驗證:
public class User
{
[EmailAddress]
public string Email { get; set; }
}
controller:
[ApiController]
[Route("test")]
public class TestController : ControllerBase
{
[HttpPost]
[ValidationFilter()]
public string Test([FromBody] User user)
{
return user.Email;
}
}
驗證過濾器:
public class ValidationFilterAttribute : ActionFilterAttribute, IOrderedFilter
{
public int Order { get; } = int.MinValue;
override public void OnActionExecuting(ActionExecutingContext context)
{
if (!context.ModelState.IsValid)
{
ModelStateEntry entry = context.ModelState.ElementAt(0).Value;
var attemptedVal = entry.AttemptedValue;
var rawVal = entry.RawValue;
context.Result = new OkObjectResult(rawVal);
}
}
}
當我用這個 model 調用測試方法時:
{
"email": "No email here ;)"
}
ValidationFilterAttribute 代碼按預期調用,但ModelStateEntry不包含原始值。 AttemptedValue和RawValue都是null :
據我所知,對於 model 綁定,過濾器將調用 context.ModelState.SetModelValue 來設置 RawValue 和 AttemptedValue 的值。
但是 SystemTextJsonInputFormatter 並沒有設置它來解決這個問題,我建議你可以嘗試構建自定義擴展方法並重試。
更多細節,您可以參考以下代碼:
創建一個新的 ModelStateJsonInputFormatter class:
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;
}
}
在 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);
});
結果:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.