Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何为本地化目的覆盖Json.Net模型绑定异常消息?_Json_Asp.net Core Mvc_Asp.net Core Localization - Fatal编程技术网

如何为本地化目的覆盖Json.Net模型绑定异常消息?

如何为本地化目的覆盖Json.Net模型绑定异常消息?,json,asp.net-core-mvc,asp.net-core-localization,Json,Asp.net Core Mvc,Asp.net Core Localization,我已使用ModelBindingMessageProvider.SetValueIsInvalidAccessor和其他ModelBindingMessageProvider值用翻译覆盖了所有模型绑定消息,以返回我的自定义资源字符串 然后我发现了可悲的事实。如果我的API控制器以JSON形式接收数据,则不会使用ModelBindingMessageProvider验证消息。相反,Json.Net起了作用,我得到了如下响应: "errors": { "countryId": [

我已使用
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,以便我的本地化消息可以工作

有没有办法捕获这些Json反序列化错误和错误 将它们重定向到ModelBindingMessageProvider,以便 信息会起作用吗

不,模型绑定和json输入是不同的,模型绑定器用于
FromForm
,JsonInputFormatter用于
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);
        }