反序列化没有属性名称的 json

问题描述

我想反序列化下面的 json 字符串,该字符串不使用出价或要价的属性名称

这就是我的课程的样子:

public class OrderBook
{
    public long lastUpdateId { get; set; }
    public List<Order> Bids { get; set; }
    public List<Order> Asks { get; set; }
}
public class Order
{
    public double Price { get; set; }
    public double Qty { get; set; }
}

这是 json 的样子。

{
  "lastUpdateId": 1027024,"bids": [
    [
      "4.00000000","431.00000000"
    ]
  ],"asks": [
    [
      "4.00000200","12.00000000"
    ]
  ]
}

当我尝试反序列化时,我收到以下错误消息:

“无法将当前 JSON 数组(例如 [1,2,3])反序列化为类型 'Order',因为该类型需要 JSON 对象(例如 {"name":"value"})才能正确反序列化">

我想也许我应该使用字典。但是出价或要价可以具有字典不允许的重复键。有人有什么建议吗?

在示例中,我只有一个出价和一个要价,但它将是多个出价和多个要价。

解决方法

请将此视为对其他答案的补充。

正如@Mansur Kurtov 正确指出的那样,这取决于您用于反序列化 JSON 的内容。

让我们同时使用 Newtonsoft 和 System.Text.Json.JsonSerializer 来测试这个案例。

使用 JsonConvert 时,@RonSplinter (OP) 答案中的 DTO 将起作用,但在直接使用 JsonSerializer 时会失败。将这些选项应用于 JsonSerializer 时,@RonSplinter 的答案将起作用。请注意,这适用于 .net Core 5 及更高版本。

var serializeOptions = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,NumberHandling = JsonNumberHandling.AllowReadingFromString
};

为了让测试在没有任何进一步配置的情况下运行,我们必须像@Mansur Kurtov 的回答那样做。

这样做的原因是 JsonSerializer 区分大小写和 "

下面的类 OrderBookUsingJsonPropertyName 展示了如何使用 JsonPropertyName 属性(仅受 JsonSerializer 支持)符合 c# 大小写。

public class OrderBookUsingDouble
{
    public long lastUpdateId { get; set; }
    public double[][] Bids { get; set; }
    public double[][] Asks { get; set; }
}

public class OrderBookUsingString
{
    public long lastUpdateId { get; set; }
    public string[][] bids { get; set; }
    public string[][] asks { get; set; }
}

public class OrderBookUsingJsonPropertyName
{
    [JsonPropertyName("lastUpdateId")] 
    public long LastUpdateId { get; set; }
    
    [JsonPropertyName("bids")] 
    public string[][] Bids { get; set; }

    [JsonPropertyName("asks")] 
    public string[][] Asks { get; set; }
}

public class JsonParserTests
{
    private const string Json = @"
    {
      ""lastUpdateId"": 1027024,""bids"": [
            [
            ""4.00000000"",""431.00000000""
            ]
            ],""asks"": [
            [
            ""4.00000200"",""12.00000000""
            ]
            ]
        }";

    [Fact]
    public void JsonConvert_OrderBookUsingDouble()
    {
        var orderBook = JsonConvert.DeserializeObject<OrderBookUsingDouble>(Json);
        Assert.Equal(2,orderBook.Bids[0].Length);
    }

    [Fact]
    public void JsonConvert_OrderBookUsingString()
    {
        var orderBook = JsonConvert.DeserializeObject<OrderBookUsingString>(Json);
        Assert.Equal(2,orderBook.bids[0].Length);
    }

    [Fact]
    public void JsonConvert_OrderBookUsingJsonPropertyName()
    {
        var orderBook = JsonConvert.DeserializeObject<OrderBookUsingJsonPropertyName>(Json);
        Assert.Equal(2,orderBook.Bids[0].Length);
    }

    [Fact]
    public void JsonSerializer_OrderBookUsingDouble_UsingOptions()
    {
        var serializeOptions = new JsonSerializerOptions
        {
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase,NumberHandling = JsonNumberHandling.AllowReadingFromString
        };
        var orderBook = System.Text.Json.JsonSerializer.Deserialize<OrderBookUsingDouble>(Json,serializeOptions);
        Assert.Equal(2,orderBook.Bids[0].Length);
    }

    [Fact]
    public void JsonSerializer_OrderBookUsingString()
    {
        var orderBook = System.Text.Json.JsonSerializer.Deserialize<OrderBookUsingString>(Json);
        Assert.Equal(2,orderBook.bids[0].Length);
    }

    [Fact]
    public void JsonSerializer_OrderBookUsingJsonPropertyName()
    {
        var orderBook =
            System.Text.Json.JsonSerializer.Deserialize<OrderBookUsingJsonPropertyName>(Json);
        Assert.Equal(2,orderBook.Bids[0].Length);
    }
}
,

已经解决了。只需将类更改为:

public class OrderBook
{
    public long lastUpdateId { get; set; }
    public double[][] Bids { get; set; }
    public double[][] Asks { get; set; }
}
,

使用此类进行反序列化:

By.PARTIAL_LINK_TEXT