【问题标题】:Deserialize json without property names [duplicate]反序列化没有属性名称的json [重复]
【发布时间】:2021-07-06 10:59:40
【问题描述】:

我想反序列化下面的 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"})才能正确反序列化"

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

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

【问题讨论】:

标签: c# serialization json.net json-deserialization


【解决方案1】:

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

正如@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 区分大小写和"-sensitive。

下面的 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);
    }
}

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      使用这个类进行反序列化:

      public class OrderBook
      {
              public long lastUpdateId { get; set; }
              public List<List<string>> bids { get; set; }
              public List<List<string>> asks { get; set; }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-15
        相关资源
        最近更新 更多