繁体   English   中英

反序列化 JSON object 不是 null 类型错误

[英]Deserialized JSON object not null for wrong type

如果我有以下 c# 记录:

public record MyRecord(string EndPoint, string Id);

我有一些 json 我试图反序列化为我的类型:

var myType= JsonSerializer.Deserialize<MyRecord>(
            jsonStr,
            new JsonSerializerOptions
            {
                PropertyNameCaseInsensitive = true
            }
        );

      if(myType is null)
      {
         ...
      }

其中jsonStr不是MyRecord类型而是其他一些类型,生成的myType而不是 null,只是 MyRecord 的一个实例,但具有空属性。 如果不是 null,我如何检查返回的类型是否无效?

JsonSerializer不会假设缺少 json 字符串的内容,前提是它至少与目标结构的格式相同(例如"{ }" )。

因此,您需要检查您的属性之一以及 object 本身的有效性:

var jsonStr = "{}";

var myType = JsonSerializer.Deserialize<MyRecord>(
        jsonStr,
        new JsonSerializerOptions
        {
            PropertyNameCaseInsensitive = true
        }
    );

if (!string.IsNullOrEmpty(myType?.Id))
{
    var x = myType;
}

请注意,类的行为也是相同的:

public class MyClass
{
    public string EndPoint { get; set; }
    public string Id { get; set; }
}

var myType2 = JsonSerializer.Deserialize<MyClass>(
        jsonStr,
        new JsonSerializerOptions
        {
            PropertyNameCaseInsensitive = true
        }
    );

if (!string.IsNullOrEmpty(myType2?.Id))
{
    var x = myType;
}

正如评论中提到的,您可以选择创建一个覆盖序列化行为的自定义转换器。

public class MyRecordConverter : JsonConverter<MyRecord>
{
    public override MyRecord Read(ref Utf8JsonReader reader, Type typeToConvert, 
        JsonSerializerOptions options)
    {
        if (reader.TokenType != JsonTokenType.StartObject)
        {
            return null;
        }
        
        var endpoint = string.Empty;
        var id = string.Empty;
        
        while (reader.Read())
        {
            if (reader.TokenType == JsonTokenType.EndObject)
            {
                break;
            }
            
            var propertyName = reader.GetString();
            reader.Read();
            
            if (propertyName.Equals(nameof(MyRecord.EndPoint),
                StringComparison.OrdinalIgnoreCase))
            {
                endpoint = reader.GetString();
            }
            else if (propertyName.Equals(nameof(MyRecord.Id), 
                StringComparison.OrdinalIgnoreCase))
            {
                id = reader.GetString();
            }
        }
        
        if (string.IsNullOrEmpty(endpoint) && string.IsNullOrEmpty(id))
        {
            return null;
        }
        
        return new MyRecord(endpoint, id);
    }

    public override void Write(Utf8JsonWriter writer, MyRecord value, 
        JsonSerializerOptions options)
    {
        throw new NotImplementedException();
    }
}

当传递给您的反序列化调用时:

var myType3 = JsonSerializer.Deserialize<MyRecord>(
        jsonStr,
        new JsonSerializerOptions
        {
            PropertyNameCaseInsensitive = true,
            Converters =
            {
                new MyRecordConverter()
            }
        }
    );

上面的空 json object 将返回 null 而不是初始化记录。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM