如何为本地化目的覆盖Json.Net模型绑定异常消息? [英] How to override Json.Net model binding exception messages for localization purposes?

查看:59
本文介绍了如何为本地化目的覆盖Json.Net模型绑定异常消息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用ModelBindingMessageProvider.SetValueIsInvalidAccessor和其他ModelBindingMessageProvider值覆盖了所有带有转换的模型绑定消息,以返回我的自定义资源字符串.

I've overridden all model binding messages with translations using ModelBindingMessageProvider.SetValueIsInvalidAccessor and other ModelBindingMessageProvider values to return my custom resource strings.

然后我发现了可悲的真相.如果我的API控制器以JSON形式接收数据,则不会使用ModelBindingMessageProvider验证消息.取而代之的是,Json.Net介入了,我得到了如下响应:

And then I discovered the sad truth. If my API controller receives the data as JSON, then ModelBindingMessageProvider validation messages are not being used. Instead, Json.Net kicks in and I get something like this in response:

  "errors": {
    "countryId": [
      "Input string '111a' is not a valid number. Path 'countryId', line 3, position 23."
    ]
  },

我查看了Json.Net的GitHub源-实际上,它似乎具有用行号等定义的确切错误消息.

I looked in GitHub source of Json.Net - indeed, it seems to have such exact error messages defined with line numbers etc.

因此,ModelState设法将它们拉入,而不是使用自己的ModelBindingMessageProvider消息.

So, ModelState manages to pull them in instead of using its own ModelBindingMessageProvider messages.

我试图禁用Json.Net错误处理:

I tried to disable Json.Net error handling:

.AddJsonOptions(options =>
                {
                 ...
                    options.SerializerSettings.Error = delegate (object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args)
                    {
                        // ignore them all
                        args.ErrorContext.Handled = true;
                    };
                })

但这没什么区别.

是否可以捕获这些Json反序列化错误并将其重定向到ModelBindingMessageProvider,以便我的本地化消息正常工作?

Is there any way to catch these Json deserialization errors and redirect them to ModelBindingMessageProvider, so that my localized messages would work?

推荐答案

是否有任何方法可以捕获这些Json反序列化错误,并且 将它们重定向到ModelBindingMessageProvider,以便我本地化 消息会起作用吗?

Is there any way to catch these Json deserialization errors and redirect them to ModelBindingMessageProvider, so that my localized messages would work?

否,模型绑定和json输入不同,模型绑定器用于FromForm,而JsonInputFormatter用于FromBody.他们遵循不同的方式.您无法自定义ModelBindingMessageProvider中的错误消息.

No, model binding and json input are different, model binder is for FromForm, and JsonInputFormatter is for FromBody. They are following different way. You could not custom the error message from ModelBindingMessageProvider.

对于JSON,您可以实现自己的JsonInputFormatter并更改错误消息,例如

For JSON, you may implement your own JsonInputFormatter and change the error message like

  1. 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);
        }
    

  • CustomJsonInputFormatter中注册本地化服务以自定义错误消息.

  • Register localized Service into CustomJsonInputFormatter to custom the error message.

    这篇关于如何为本地化目的覆盖Json.Net模型绑定异常消息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆