首页 新闻 会员 周边

.NET Core System.Text.Json 反序列化 Guid 的问题

0
悬赏园豆:100 [已解决问题] 解决于 2019-10-01 11:33

对于可空的 Guid 类型(Guid?),如果 json 中对应的值为空字符串(""),则反序列化时会报错:

System.FormatException: The JSON value is not in a supported Guid format.
   at System.Text.Json.Utf8JsonReader.GetGuid()
   at System.Text.Json.Serialization.Converters.JsonConverterGuid.Read(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options)

而使用 Newtonsoft.Json 则没这个问题,请问如何解决?

dudu的主页 dudu | 高人七级 | 园豆:30943
提问于:2019-09-30 15:21
< >
分享
最佳答案
0

可以通过自定义JsonConverter来处理不支持的类型转换,下面只实现了一个Guid的自定义转换,在实现Guid?的时候,发现在重写Read方法时候,返回默认的default (return null) 的时候,在序列化的时候,好像不走Write方法,不能自定义输出结果,该属性的序列化的值一直是null,在反序列化时候返回默认的Guid,可以解决。

using System;
using System.Buffers;
using System.Buffers.Text;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace q_120383
{
    class Program
    {
        static void Main(string[] args)
        {
            var options = new JsonSerializerOptions
            {
                Converters = {new EmptyStringToGuidConverter()}
            };
            var testJsonStr = "{\"UserId\":\"\",\"Name\":\"\"}";
            var p = JsonSerializer.Deserialize<Person>(testJsonStr, options);
            Console.WriteLine(p.UserId);
            var s = JsonSerializer.Serialize(p, options);
            Console.WriteLine(s);
        }
    }

    public class Person
    {
        public Guid UserId { get; set; }
        public string Name { get; set; }
    }

    public class EmptyStringToGuidConverter : JsonConverter<Guid>
    {
        public override Guid Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            if (reader.TokenType == JsonTokenType.Null)
                return Guid.Empty;

            if (reader.TokenType == JsonTokenType.String)
            {
                ReadOnlySpan<byte> span = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan;
                if (Utf8Parser.TryParse(span, out Guid value, out var bytesConsumed) && span.Length == bytesConsumed)
                    return value;

                return Guid.Empty;
            }

            throw ThrowHelper.GetFormatException(DataType.Guid);
        }

        public override void Write(Utf8JsonWriter writer, Guid value, JsonSerializerOptions options)
        {
            if (Guid.Empty.Equals(value))
                writer.WriteStringValue("");
            else
                writer.WriteStringValue(value.ToString());
        }
    }
}
收获园豆:60
ohyex | 小虾三级 |园豆:1496 | 2019-10-01 09:45
其他回答(4)
0
收获园豆:20
通信的搞程序 | 园豆:1747 (小虾三级) | 2019-09-30 15:40
0

说实话,这个System.Text.Json相比json.net太弱了,很多坑。DataTable,DataSet都序列化不了,json.net就能轻松搞定

收获园豆:10
村委第一书记 | 园豆:26 (初学一级) | 2019-09-30 15:49

我也踩坑了

支持(0) 反对(0) 张朋举 | 园豆:1915 (小虾三级) | 2019-10-01 08:37
0

还是用Newtonsoft.Json吧
内置的json问题是多多。并且对自定义jobject之类的不方便。更别提dynamic的支持也没有。

收获园豆:10
张朋举 | 园豆:1915 (小虾三级) | 2019-10-01 08:40

现在微软的程序员水平就这么差吗,写的什么狗屎api

支持(1) 反对(0) iwobz | 园豆:200 (初学一级) | 2019-11-10 00:26

反序列化dynamic可以这样解决
var dics = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
var obj = new ExpandoObject();
foreach (var item in dics)
{
obj.TryAdd(item.Key, item.Value?.ToString());
}
return obj;

支持(0) 反对(0) known | 园豆:163 (初学一级) | 2021-09-09 17:07
-1

哈哈,悲催的 .net core

日暮青色 | 园豆:475 (菜鸟二级) | 2019-10-02 09:27
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册