我已经使用ModelBindingMessageProvider.SetValueIsInvalidAccessor
和其他ModelBindingMessageProvider值覆盖了所有带有转换的模型绑定消息,以返回我的自定义资源字符串。
然后我发现了可悲的事实。如果我的API控制器以JSON形式接收数据,则不会使用ModelBindingMessageProvider验证消息。取而代之的是,Json.Net介入了,我得到了如下响应:
"errors": {
"countryId": [
"Input string '111a' is not a valid number. Path 'countryId', line 3, position 23."
]
},
我查看了Json.Net的GitHub来源-实际上,它似乎具有用行号等定义的确切错误消息。
因此,ModelState设法将它们拉入而不是使用自己的ModelBindingMessageProvider消息。
我试图禁用Json.Net错误处理:
.AddJsonOptions(options =>
{
...
options.SerializerSettings.Error = delegate (object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args)
{
// ignore them all
args.ErrorContext.Handled = true;
};
})
但这没什么区别。
是否可以捕获这些Json反序列化错误并将其重定向到ModelBindingMessageProvider,以便我的本地化消息正常工作?
答案 0 :(得分:1)
是否有任何方法可以捕获这些Json反序列化错误,并且 将它们重定向到ModelBindingMessageProvider,以便我本地化 消息会起作用吗?
否,模型绑定和json输入不同,模型绑定器用于$
,而JsonInputFormatter用于FromForm
。他们遵循不同的方式。您无法自定义FromBody
中的错误消息。
对于ModelBindingMessageProvider
,您可以实现自己的JSON
并更改错误消息,例如
JsonInputFormatter
CustomJsonInputFormatter
注册public class CustomJsonInputFormatter : JsonInputFormatter
{
public CustomJsonInputFormatter(ILogger<CustomJsonInputFormatter> logger
, JsonSerializerSettings serializerSettings
, ArrayPool<char> charPool
, ObjectPoolProvider objectPoolProvider
, MvcOptions options
, MvcJsonOptions jsonOptions)
: base(logger, serializerSettings, charPool, objectPoolProvider, options, jsonOptions)
{
}
public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context)
{
var result = await base.ReadRequestBodyAsync(context);
foreach (var key in context.ModelState.Keys)
{
for (int i = 0; i < context.ModelState[key].Errors.Count; i++)
{
var error = context.ModelState[key].Errors[i];
context.ModelState[key].Errors.Add($"This is translated error { error.ErrorMessage }");
context.ModelState[key].Errors.Remove(error);
}
}
return result;
}
}
CustomJsonInputFormatter
将本地化服务注册到 services.AddMvc(options =>
{
var serviceProvider = services.BuildServiceProvider();
var customJsonInputFormatter = new CustomJsonInputFormatter(
serviceProvider.GetRequiredService<ILoggerFactory>().CreateLogger<CustomJsonInputFormatter>(),
serviceProvider.GetRequiredService<IOptions<MvcJsonOptions>>().Value.SerializerSettings,
serviceProvider.GetRequiredService<ArrayPool<char>>(),
serviceProvider.GetRequiredService<ObjectPoolProvider>(),
options,
serviceProvider.GetRequiredService<IOptions<MvcJsonOptions>>().Value
);
options.InputFormatters.Insert(0, customJsonInputFormatter);
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
中以自定义错误消息。