System.Text.Json 使用构造函数反序列化

Dan*_*iel 1 c# system.text.json

我正在使用 System.Text.Json 进行反序列化。

我想使用构造函数来SerialNo(string serialNo)构建我的对象。

public class SerialNo
{
    [JsonConstructor]
    public SerialNo(string serialNo)
    {
        if (serialNo == null) throw new ArgumentNullException(nameof(serialNo));

        if (string.IsNullOrWhiteSpace(serialNo)) throw new Exception("My exception text");

        Value = serialNo.Trim('0');
    }

    public string Value { get; set; }
}

public class Item
{
    public SerialNo SerialNo { get; set; }

    public string AffiliationOrgCode { get; set; }
}

public class Root
{
    public List<Item> Item { get; set; }
}

public class DeserializationTestsWithSystemTextJson
{
    private const string JsonString = @"
        {
            ""item"": [
              {
                ""serialNo"": ""000000000002200878"",
                ""affiliationOrgCode"": ""OrgCode1""
              },
              {
                ""serialNo"": ""000000000002201675"",
                ""affiliationOrgCode"": ""OrgCode1""
              }
            ]
        }
    ";

    [Fact]
    public void Simple_Deserialization_With_SystemTextJson()
    {
        var options = new JsonSerializerOptions(JsonSerializerDefaults.Web);
        var deserializedClass = JsonSerializer.Deserialize<Root>(JsonString, options);

        Assert.NotNull(deserializedClass);
        Assert.Equal("2201675", deserializedClass.Item[1].SerialNo.Value);
    }
}
Run Code Online (Sandbox Code Playgroud)

失败

JSON 值无法转换为 JsonNetDeserialization.Test.WithSystemText.SerialNo。路径:$.item[0].serialNo | 行号:3 | 内联字节位置:44。

有任何想法吗?

Dav*_*idG 5

由于您要将 a 转换string为 a SerialNo,因此您需要一个自定义转换器。例如:

public class SerialNoConverter : JsonConverter<SerialNo>
{
    public override SerialNo? Read(ref Utf8JsonReader reader, Type typeToConvert, 
        JsonSerializerOptions options)
    {
        var serialNo = reader.GetString();
        return new SerialNo(serialNo);
    }

    public override void Write(Utf8JsonWriter writer, SerialNo value, 
        JsonSerializerOptions options)
    {
        // Left for OP if required
        throw new NotImplementedException();
    }
}
Run Code Online (Sandbox Code Playgroud)

要使用它,您可以向您的类添加一个属性:

public class Item
{
    [JsonConverter(typeof(SerialNoConverter))]
    public SerialNo SerialNo { get; set; }

    public string AffiliationOrgCode { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

或者将转换器添加到您的序列化器选项中:

options.Converters.Add(new SerialNoConverter());
Run Code Online (Sandbox Code Playgroud)

这是一个运行示例