我正在尝试反序列化此JSON
{
"39": {
"category": "Miscellaneous",
"country_whitelist": [],
"name": "domain.com",
"url_blacklist": [],
"country_blacklist": [],
"url_whitelist": [
"domain.com"
],
"deals": {
"425215": {
"status": "Ok",
"type": "",
"code": "CODE",
"end_date": "2014-03-01 04:00:00",
"title": "RandomTitle",
"url": "http://domain.com/foo",
"text": "Text Text Text",
"long_title": "Longer Text"
},
"425216": {
"status": "Ok",
"type": "",
"code": "CODE2",
"end_date": "2014-03-01 04:00:00",
"title": "RandomTitle2",
"url": "http://domain.com/bar",
"text": "Text Text Text",
"long_title": "Longer Text"
}
},
"88x31": "http://someimage/88x31.png",
"subcategory": "Other"
},
"40": {
"category": "Miscellaneous",
"country_whitelist": [],
"name": "domain.com",
"url_blacklist": [],
"country_blacklist": [],
"url_whitelist": [
"domain.com"
],
"products": {
"425215": {
"status": "Ok",
"type": "",
"code": "CODE",
"end_date": "2014-03-01 04:00:00",
"title": "RandomTitle",
"url": "http://domain.com/foo",
"text": "Text Text Text",
"long_title": "Longer Text"
},
"425216": {
"status": "Ok",
"type": "",
"code": "CODE2",
"end_date": "2014-03-01 04:00:00",
"title": "RandomTitle2",
"url": "http://domain.com/bar",
"text": "Text Text Text",
"long_title": "Longer Text"
}
},
"88x31": "http://someimage/88x31.png",
"subcategory": "Other"
}
}
我尝试使用Json.NET并尝试使用ServiceStack的反序列化程序,但我似乎无法获得此JSON的任何类型的表示。
阻止我的主要因素是我认为键是Int,但我无法控制我收到的JSON。
这是我建立的C#类
public class product
{
public string status { get; set; }
public string type { get; set; }
public string code { get; set; }
public string end_date { get; set; }
public string title { get; set; }
public string url { get; set; }
public string text { get; set; }
public string long_title { get; set; }
}
public class Merchant
{
public string category { get; set; }
public List<string> country_whitelist { get; set; }
public string name { get; set; }
public List<string> url_blacklist { get; set; }
public List<string> country_blacklist { get; set; }
public List<string> url_whitelist { get; set; }
public List<product> products { get; set; }
public string subcategory { get; set; }
}
public class Data
{
public Dictionary<int, Merchant> MainMerchants { get; set; }
}
我更喜欢使用ServiceStack,但任何其他有效的反序列化器都会很棒
var data = client.Get(json);
答案 0 :(得分:7)
可以反序列化您的JSON。正确识别后,您可以反序列化为Dictionary<int, Merchant>
。
但您需要将products
课程中Merchant
的定义更改为Dictionary<int, Product>
。它需要是一个字典来处理您的数字键。 List<Product>
无效。
另外,为了处理88x31
属性,您可以使用DataMember(Name = '88x31')
映射将其映射到c#喜欢的内容,例如image88x31
。不幸的是,这确实意味着您的DTO属性成为选择加入,因此您需要装饰所有成员。 添加using System.Runtime.Serialization;
完成这些更改后:
// Note I capitalized Product
public class Product
{
public string status { get; set; }
public string type { get; set; }
public string code { get; set; }
public string end_date { get; set; }
public string title { get; set; }
public string url { get; set; }
public string text { get; set; }
public string long_title { get; set; }
}
/*
* Use DataMember to map the keys starting with numbers to an alternative c# compatible name.
* Unfortunately this requires properties to opt in to the data contract.
*/
[DataContract]
public class Merchant
{
[DataMember]
public string category { get; set; }
[DataMember]
public List<string> country_whitelist { get; set; }
[DataMember]
public string name { get; set; }
[DataMember]
public List<string> url_blacklist { get; set; }
[DataMember]
public List<string> country_blacklist { get; set; }
[DataMember]
public List<string> url_whitelist { get; set; }
[DataMember]
public Dictionary<int, Product> products { get; set; }
[DataMember]
public string sub_category { get; set; }
// This maps the 88x31 key to a c# appropriate name
[DataMember(Name = "88x31")]
public string image88x31 { get; set; }
}
然后,您就可以毫无问题地反序列化为Dictionary<int, Merchant>
。
JsonSerializer.DeserializeFromString<Dictionary<int, Merchant>>("YOUR JSON STRING");
如果您希望能够将此请求直接发送到ServiceStack服务,则可以使用RequestBinder
反序列化为此复杂类型。鉴于这项服务:
请求DTO:
[Route("/Merchants", "POST")]
public class MerchantsRequest
{
public Dictionary<int, Merchant> MainMerchants { get; set; }
}
简单操作方法:
public class MerchantsService : Service
{
public void Post(MerchantsRequest request)
{
var merchant39 = request.MainMerchants.First(p=>p.Key == 39).Value;
Console.WriteLine("Name: {0}\nImage: {1}\nProduct Count: {2}", merchant39.name, merchant39.image88x31, merchant39.products.Count);
var merchant40 = request.MainMerchants.First(p=>p.Key == 40).Value;
Console.WriteLine("Name: {0}\nImage: {1}\nProduct Count: {2}", merchant40.name, merchant40.image88x31, merchant40.products.Count);
}
}
AppHost配置:
在AppHost
Configure
方法中,您需要在请求类型中添加绑定器。即typeof(MerchantsRequest)
如此:
public override void Configure(Funq.Container container)
{
Func<IRequest, object> merchantsRequestBinder = delegate(IRequest request) {
var json = WebUtility.HtmlDecode( request.GetRawBody() );
return new MerchantsRequest { MainMerchants = JsonSerializer.DeserializeFromString<Dictionary<int, Merchant>>(json) };
};
RequestBinders.Add(typeof(MerchantsRequest), merchantsRequestBinder);
...
}
此绑定方法会将您发送的json转换为MerchantsRequest
。然后,您可以像常规的ServiceStack请求一样使用它。
控制台应用程序的一个完整工作示例,演示了将复杂JSON转换为服务请求。
注:的我发现在你的JSON,你有属性deals
一个对象,而products
另一个,我以为这是一个错字,因为你不” t在deals
的类中有相应的属性。
答案 1 :(得分:0)
在你的json字符串中,对于products节点,它应该是这个吗?它转换的类型是List而不是字典?
我可以把它改成跟随json字符串
"products": [{
"status": "Ok",
"type": "",
"code": "CODE",
"end_date": "2014-03-01 04:00:00",
"title": "RandomTitle",
"url": "http://domain.com/foo",
"text": "Text Text Text",
"long_title": "Longer Text"
},
{
"status": "Ok",
"type": "",
"code": "CODE2",
"end_date": "2014-03-01 04:00:00",
"title": "RandomTitle2",
"url": "http://domain.com/bar",
"text": "Text Text Text",
"long_title": "Longer Text"
}],