如果使用 Newtonsoft Json 解析字符串,字符串里面有不清真的格式,那么默认的解析将会炸掉。如果想要自己解决字符串中的不清真格式,可以使用传入 JsonSerializerSettings 的方法

我写了一段字符串,里面需要解析为日期请看代码

@"[
      '2009-09-09T00:00:00Z',
      '这是歪楼的',
      [
        1
      ],
      '1977-02-20T00:00:00Z',
      null,
      '2000-12-01T00:00:00Z'
    ]"

小伙伴很快就可以看到,这里有一个歪楼的字符串

如果直接解析,那么将会炸掉


            List<DateTime> list = JsonConvert.DeserializeObject<List<DateTime>>(@"[
      '2009-09-09T00:00:00Z',
      '这是歪楼的',
      [
        1
      ],
      '1977-02-20T00:00:00Z',
      null,
      '2000-12-01T00:00:00Z'
    ]");

运行上面代码,可以看到一个有趣的代码

自己解决不合法的字符串可以通过 JsonSerializerSettings 的方法,里面有一个委托,在发现有不清真的字符串的时候就会调用这个委托

             List<string> errors = new List<string>();

               new JsonSerializerSettings
                {
                    Error = (sender, e) =>
                    {
                        errors.Add(e.ErrorContext.Error.Message);
                        e.ErrorContext.Handled = true;
                    },
                    Converters = { new IsoDateTimeConverter() }
                }

其实这里的 DeserializeObject 可以传入两个参数,一个是字符串,一个是 JsonSerializerSettings 所以就可以做到在发现不清真的字符串的时候调用委托,同时支持传入从字符串转类的方法

           List<string> errors = new List<string>();

            List<DateTime> list = JsonConvert.DeserializeObject<List<DateTime>>(@"[
      '2009-09-09T00:00:00Z',
      '这是歪楼的',
      [
        1
      ],
      '1977-02-20T00:00:00Z',
      null,
      '2000-12-01T00:00:00Z'
    ]",
                new JsonSerializerSettings
                {
                    Error = (sender, e) =>
                    {
                        errors.Add(e.ErrorContext.Error.Message);
                        e.ErrorContext.Handled = true;
                    },
                    Converters = { new IsoDateTimeConverter() }
                });

这时运行代码不会炸掉,因为设置了 e.ErrorContext.Handled 是 true 如果想要记录问题同时需要炸掉,那么就不要写这个代码

所有代码请看 github

Serialization Error Handling


本文会经常更新,请阅读原文: https://dotnet-campus.github.io//post/dotnet-%E6%89%8B%E5%8A%A8%E8%A7%A3%E5%86%B3-json-%E8%A7%A3%E6%9E%90%E4%B8%AD%E4%B8%8D%E5%90%88%E6%B3%95%E5%AD%97%E7%AC%A6%E4%B8%B2.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

知识共享许可协议 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 lindexi (包含链接: https://dotnet-campus.github.io/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系