对于可空的 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
则没这个问题,请问如何解决?
可以通过自定义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());
}
}
}
自定义JsonConverter 应该可以
说实话,这个System.Text.Json相比json.net太弱了,很多坑。DataTable,DataSet都序列化不了,json.net就能轻松搞定
我也踩坑了
还是用Newtonsoft.Json吧
内置的json问题是多多。并且对自定义jobject之类的不方便。更别提dynamic的支持也没有。
现在微软的程序员水平就这么差吗,写的什么狗屎api
反序列化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;
哈哈,悲催的 .net core