使用 Syste.Text.Json 反序列化 json 时允许一个属性有多种类型

问题描述 投票:0回答:1

我期望传入数据中的特定属性是整数数组或字符串。在我的模型中定义此条件的正确方法是什么?

using System.Text.Json.Serialization;

public class TestClass
{
    [JsonPropertyName("values")
    public string? values { get; set; } = null; //this field should either be a string or an array.  nothing else.
}

供参考,在Python中我可以这样做,并且可以将我的值属性设置为字符串或int列表:

from pydantic import BaseModel, Field
from typing import List

class TestClass(BaseModel):
    values: List[int] | str = Field(None, alias="values")

提前谢谢你

c# serialization types system.text.json
1个回答
0
投票

C# 不支持具有多种(数据)类型的属性。对于您的情况,我建议使用两个属性来存储不同类型的值。

方法一:使用getter反序列化

public class TestClass
{
    [JsonInclude]
    [JsonPropertyName("values")]
    public JsonElement? values { get; set; } = null; //this field should either be a string or an array.  nothing else.
    
    [JsonIgnore]
    public string StringValue 
    { 
        get
        {
            if (values.HasValue && values.Value.ValueKind == JsonValueKind.String)
            {
                return values.Value.ToString();
            }
            
            return null;
        }       
    }
    
    [JsonIgnore]
    public int[] IntegerValues
    { 
        get
        {
            if (values.HasValue && values.Value.ValueKind == JsonValueKind.Array)
            {
                return values.Value.Deserialize<int[]>();
            }
            
            return null;
        }
    }
}

**方法 2:实施

JsonConverter

public class TestClassConverter : JsonConverter<TestClass>
{
    public override TestClass Read(
        ref Utf8JsonReader reader,
        Type typeToConvert,
        JsonSerializerOptions options)
        {
            TestClass value = new TestClass();

            JsonElement root = JsonElement.ParseValue(ref reader);
            JsonElement values = root.GetProperty("values");

            value.values = values;

            switch (values.ValueKind)
            {
                case JsonValueKind.String:
                    value.StringValue = values.ToString();
                    break;

                case JsonValueKind.Array:
                    value.IntegerValues = JsonSerializer.Deserialize<int[]>(values);
                    break;

                default:
                    throw new JsonException("Unsupported values type");
            }

            return value;
        }


    public override void Write(
        Utf8JsonWriter writer,
        TestClass value,
        JsonSerializerOptions options) =>
            writer.WriteStringValue(value.ToString());
}
[JsonConverter(typeof(TestClassConverter))]
public class TestClass
{
    [JsonInclude]
    [JsonPropertyName("values")]
    public JsonElement? values { get; set; } = null; //this field should either be a string or an array.  nothing else.
    
    [JsonIgnore]
    public string StringValue { get; set; }
    
    [JsonIgnore]
    public int[] IntegerValues { get; set; }
}
© www.soinside.com 2019 - 2024. All rights reserved.