给定以下json:
[ {"id":"123", ... "data":[{"key1":"val1"}, {"key2":"val2"}], ...}, ... ]
这是一个更大的树的一部分,我如何将"数据"属性反序列化为:
List<MyCustomClass> Data { get; set; }
或
List<KeyValuePair> Data { get; set; }
或
Dictionary<string, string> Data { get; set; }
使用Json.NET?任何一个版本都可以(不过我更喜欢MyCustomClass的列表(。我已经有一个包含其他属性的类,比如:
public class SomeData
{
[JsonProperty("_id")]
public string Id { get; set; }
...
public List<MyCustomClass> Data { get; set; }
}
其中"MyCustomClass"只包括两个属性(Key和Value(。我注意到有一个KeyValuePairConverter类听起来可以满足我的需要,但我找不到如何使用它的示例。谢谢。
最简单的方法是将键值对数组反序列化为IDictionary<string, string>
:
public class SomeData
{
public string Id { get; set; }
public IEnumerable<IDictionary<string, string>> Data { get; set; }
}
private static void Main(string[] args)
{
var json = "{ "id": "123", "data": [ { "key1": "val1" }, { "key2" : "val2" } ] }";
var obj = JsonConvert.DeserializeObject<SomeData>(json);
}
但是,如果您需要将其反序列化为自己的类,它可以是这样的:
public class SomeData2
{
public string Id { get; set; }
public List<SomeDataPair> Data { get; set; }
}
public class SomeDataPair
{
public string Key { get; set; }
public string Value { get; set; }
}
private static void Main(string[] args)
{
var json = "{ "id": "123", "data": [ { "key1": "val1" }, { "key2" : "val2" } ] }";
var rawObj = JObject.Parse(json);
var obj2 = new SomeData2
{
Id = (string)rawObj["id"],
Data = new List<SomeDataPair>()
};
foreach (var item in rawObj["data"])
{
foreach (var prop in item)
{
var property = prop as JProperty;
if (property != null)
{
obj2.Data.Add(new SomeDataPair() { Key = property.Name, Value = property.Value.ToString() });
}
}
}
}
看到我假设Value
是string
,并且我调用ToString()
方法,可以有另一个复杂的类。
感谢@Boo的回答,但就我而言,我需要做一些小的调整。我的JSON是这样的:
{
"rates": {
"CAD": 1.5649,
"CZK": 26.118,
...
},
"base": "EUR",
"date": "2020-08-16"
}
我的DTO看起来如下:
public IDictionary<string, decimal> Rates { get; set; }
public string Base { get; set; }
public DateTime Date { get; set; }
因此,唯一的调整是去除IDictionary
周围的IEnumerable
。
我最终做了这个:
[JsonConverter(typeof(MyCustomClassConverter))]
public class MyCustomClass
{
internal class MyCustomClassConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jObject = JObject.Load(reader);
foreach (var prop in jObject)
{
return new MyCustomClass { Key = prop.Key, Value = prop.Value.ToString() };
}
return null;
}
public override bool CanConvert(Type objectType)
{
return typeof(MyCustomClass).IsAssignableFrom(objectType);
}
}
public string Key { get; set; }
public string Value { get; set; }
}
public class Datum
{
public string key1 { get; set; }
public string key2 { get; set; }
}
public class RootObject
{
public string id { get; set; }
public List<Datum> data { get; set; }
}
我也使用了这个向导json2csharp.com为反序列化的生成类
使用
using RestSharp;
using Newtonsoft.Json;
IRestResponse restSharp= callRestGetMethodby_restSharp(api_server_url);
string jsonString= restSharp.Content;
RootObject rootObj= JsonConvert.DeserializeObject<RootObject>(jsonString);
return Json(rootObj);
如果您通过restsharp 呼叫rest
public IRestResponse callRestGetMethodby_restSharp(string API_URL)
{
var client = new RestSharp.RestClient(API_URL);
var request = new RestRequest(Method.GET);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("cache-control", "no-cache");
IRestResponse response = client.Execute(request);
return response;
}
您还可以从getpostman.com工具
您可以使用公共IEnumerable<IDictionary<字符串,字符串>gt;建议将数据作为大多数答案,但这不是最好的主意,因为它会为每个数组键值项创建一个新的字典。我建议使用List<KeyValuePair<字符串,字符串>gt;相反(或者您也可以创建一个自定义类,而不是使用KeyValuePair(
var json = "[{ "id": "123", "data": [ { "key1": "val1" }, { "key2" : "val2" } ] }]";
List<SomeData> listSomeData = JsonConvert.DeserializeObject<List<SomeData>>(json);
public class SomeData
{
[JsonProperty("id")]
public string Id { get; set; }
public List<KeyValuePair<string, string>> Data { get; set; }
[JsonConstructor]
public SomeData(JArray data)
{
Data = data.Select(d => new KeyValuePair<string, string>(
((JObject)d).Properties().First().Name,
((JObject)d).Properties().First().Value.ToString()))
.ToList();
}
}