我有一个JSON文本,来自Sharepoint 2013中的搜索,并希望将其反序列化为MyClass列表。 我有一个使用KeyValuePair的解决方案
var results = item["Cells"]["results"].ToObject<List<KeyValuePair<string, string>>>();
但是这种方法会删除日期格式等。一切都以字符串形式结束。例如。 JSON文件中正确的挪威语日期最终为文本中的准Norwenglish日期。
编辑:我正在使用Newtonsoft.Json库。
编辑:日期格式只是问题的一部分。反序列化是我的主要问题。
此示例简化了JSON和类。 JSON文件可以有许多这样的记录,因此它最终会出现在一个对象列表中。你有一个很好的解决方案来反序列化这个JSON吗?
JSON
{
"__metadata": {
"type": "SP.SimpleDataRow"
},
"Cells": {
"results": [
{
"__metadata": {
"type": "SP.KeyValue"
},
"Key": "Id",
"Value": "358553",
"ValueType": "Edm.Int64"
},
{
"__metadata": {
"type": "SP.KeyValue"
},
"Key": "Url",
"Value": "http://somewhere.com",
"ValueType": "Edm.String"
},
{
"__metadata": {
"type": "SP.KeyValue"
},
"Key": "Title",
"Value": "My title",
"ValueType": "Edm.String"
},
{
"__metadata": {
"type": "SP.KeyValue"
},
"Key": "MyDate",
"Value": "2017-09-10T11:10:19Z",
"ValueType": "Edm.DateTime"
}
]
}
}
类
public class MyClass
{
public int Id { get; set; }
public string Url { get; set; }
public string Title { get; set; }
public DateTime MyDate { get; set; }
}
答案 0 :(得分:1)
您可以使用以下转换器反序列化JSON中的"results"
数组:
public class KeyValuePropertyArrayConverter<T> : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(T).IsAssignableFrom(objectType);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;
var pairs = serializer.Deserialize<List<KeyValuePair<string, JToken>>>(reader);
var jObj = new JObject(pairs.Select(p => new JProperty(p.Key, p.Value)));
existingValue = existingValue ?? serializer.ContractResolver.ResolveContract(objectType).DefaultCreator();
serializer.Populate(jObj.CreateReader(), existingValue);
return existingValue;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
然后按如下方式定义MyClass
:
public class MyClass
{
public long Id { get; set; } // This should be long not int
public string Url { get; set; }
public string Title { get; set; }
public DateTime MyDate { get; set; }
}
然后,按以下步骤反序列化:
// Disable date recognition while parsing intermediate JToken representation as shown in
// https://stackoverflow.com/questions/35138346/jtoken-get-raw-original-json-value/35141787
var item = JsonConvert.DeserializeObject<JObject>(jsonString, new JsonSerializerSettings { DateParseHandling = DateParseHandling.None });
var finalSettings = new JsonSerializerSettings
{
Converters = { new KeyValuePropertyArrayConverter<MyClass>() /*, Add some appropriate IsoDateTimeConverter if required, */ },
// Or set DateFormatString if required
};
var myClass = item["Cells"]["results"].ToObject<MyClass>(JsonSerializer.CreateDefault(finalSettings));
注意:
您的JSON仅对应于MyClass
的单个实例 - 而不是它们的数组。 JSON中唯一的数组是属性值数组。
JSON指定"Id"
为"Edm.Int64"
,因此我将MyClass.Id
修改为long
。
通过在加载初始DateParseHandling = DateParseHandling.None
时设置JObject
,您可以将日期字符串识别推迟到最终反序列化,此时您可以应用适当的IsoDateTimeConverter
或DateFormatString
,和Json.NET可以在最终目标类中使用类型信息,以帮助识别嵌入在JSON中的日期。
我没有将序列化实现为相同的格式,因为您的问题没有请求此。
示例.Net fiddle。