问题描述
我想反序列化下面的 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