我正在尝试反序列化此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);
可以反序列化JSON。正确识别后,您可以反序列化为Dictionary<int, Merchant>。
Dictionary<int, Merchant>
但是您需要将您products在Merchant类中的定义更改为Dictionary<int, Product>。这里需要一个字典来处理您的数字键。List<Product>将无法正常工作。
products
Merchant
Dictionary<int, Product>
List<Product>
同样,要处理该88x31属性,您可以使用DataMember(Name = '88x31')映射将其映射到c#喜欢的东西image88x31。不幸的是,这确实意味着您的DTO属性将变为选择加入状态,因此您需要装饰所有成员。 加using System.Runtime.Serialization;
88x31
DataMember(Name = '88x31')
image88x31
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其反序列化为这种复杂类型。鉴于此服务:
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)像这样:
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请求一样使用它。
MerchantsRequest
控制台应用程序的一个完整工作示例,演示了将复杂JSON转换为服务请求的过程。
注意: 我在您的JSON中注意到您deals在一个对象上具有属性,而products在另一个对象上,我认为这是一个错字,因为您在的类中没有相应的属性deals。
deals