使用顶级数组和第一个未命名对象反序列化 Json
Deserialize Json with top Array and first unnamed object
我正在消费 API returns 以下 JSON:
[
{
"product": {
"id": 2,
"name": "Auto"
}
}
]
所以,我试图在 C# 对象中反序列化它,但没有成功。
我尝试了很多其他的 Whosebug 解决方案。
这是我的尝试:
public class DomainMessageResponse : BaseResponseMessage
{
public Example data { get; set; }
}
public class Example
{
[JsonProperty("product")]
public Product product { get; set; }
}
public class Product
{
[JsonProperty("id")]
public int id { get; set; }
[JsonProperty("name")]
public string name { get; set; }
}
问题是 JSON 以 [] 开头,而我们的通用方法(我从内部框架中使用)无法使用它。我收到以下异常:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type....
感谢@EZI 和@eocron 提供有效的解决方案。
您应该反序列化为 array/list。下面的代码应该可以工作...
var list = JsonConvert.DeserializeObject<List<Item>>(json);
public class Product
{
public int id { get; set; }
public string name { get; set; }
}
public class Item
{
public Product product { get; set; }
}
考虑到您要使用对象的方式,您的问题有两种解决方案。
第一个是简单地创建具有相同字段的 DTO。当您需要完全控制时使用:
using System.Collections.Generic;
using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
namespace ConsoleTest
{
class Program
{
[DataContract]
public class Example
{
[DataMember]
public Product Product { get; set; }
}
[DataContract]
public class Product
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
}
static void Main(string[] args)
{
var json = @"
[
{
""product"": {
""id"": 2,
""name"": ""Auto""
}
}
]";
var obj = JsonConvert.DeserializeObject<List<Example>>(json,
new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
});
}
}
}
当您想要 json 中的几个字段并且不太关心其他所有内容时使用第二个,并使用 dynamic 类型。易于编码,易于使用,看起来不错,但不太安全:
using System.Collections.Generic;
using Newtonsoft.Json;
namespace ConsoleTest
{
class Program
{
static void Main(string[] args)
{
var json = @"
[
{
""product"": {
""id"": 2,
""name"": ""Auto""
}
}
]";
dynamic list = JsonConvert.DeserializeObject<List<dynamic>>(json);
var id = (int)list[0].product.id;
}
}
}
我正在消费 API returns 以下 JSON:
[
{
"product": {
"id": 2,
"name": "Auto"
}
}
]
所以,我试图在 C# 对象中反序列化它,但没有成功。
我尝试了很多其他的 Whosebug 解决方案。
这是我的尝试:
public class DomainMessageResponse : BaseResponseMessage
{
public Example data { get; set; }
}
public class Example
{
[JsonProperty("product")]
public Product product { get; set; }
}
public class Product
{
[JsonProperty("id")]
public int id { get; set; }
[JsonProperty("name")]
public string name { get; set; }
}
问题是 JSON 以 [] 开头,而我们的通用方法(我从内部框架中使用)无法使用它。我收到以下异常:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type....
感谢@EZI 和@eocron 提供有效的解决方案。
您应该反序列化为 array/list。下面的代码应该可以工作...
var list = JsonConvert.DeserializeObject<List<Item>>(json);
public class Product
{
public int id { get; set; }
public string name { get; set; }
}
public class Item
{
public Product product { get; set; }
}
考虑到您要使用对象的方式,您的问题有两种解决方案。
第一个是简单地创建具有相同字段的 DTO。当您需要完全控制时使用:
using System.Collections.Generic;
using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
namespace ConsoleTest
{
class Program
{
[DataContract]
public class Example
{
[DataMember]
public Product Product { get; set; }
}
[DataContract]
public class Product
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
}
static void Main(string[] args)
{
var json = @"
[
{
""product"": {
""id"": 2,
""name"": ""Auto""
}
}
]";
var obj = JsonConvert.DeserializeObject<List<Example>>(json,
new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver()
});
}
}
}
当您想要 json 中的几个字段并且不太关心其他所有内容时使用第二个,并使用 dynamic 类型。易于编码,易于使用,看起来不错,但不太安全:
using System.Collections.Generic;
using Newtonsoft.Json;
namespace ConsoleTest
{
class Program
{
static void Main(string[] args)
{
var json = @"
[
{
""product"": {
""id"": 2,
""name"": ""Auto""
}
}
]";
dynamic list = JsonConvert.DeserializeObject<List<dynamic>>(json);
var id = (int)list[0].product.id;
}
}
}