{
"rates_scores_stats": [{
"name": 10,
"value": 3545
}, {
"name": 9,
"value": 1004
}, {
"name": 8,
"value": 820
}, {
"name": 7,
"value": 493
}, {
"name": 6,
"value": 218
}, {
"name": 5,
"value": 138
}, {
"name": 4,
"value": 80
}, {
"name": 3,
"value": 41
}, {
"name": 2,
"value": 26
}, {
"name": 1,
"value": 83
}
],
"rates_statuses_stats": [{
"name": "Запланировано",
"value": 2506
}, {
"name": "Смотрю",
"value": 7861
}, {
"name": "Просмотрено",
"value": 1947
}, {
"name": "Отложено",
"value": 1443
}, {
"name": "Брошено",
"value": 1358
}
]
}
Есть JSON описанный выше. Для десериализации я использую Newtonsoft.Json.
В частности, метод JsonConvert.DeserializeObject(json)
Я знаю, что для этого json можно описать типичный класс следующим образом
Тоже самое текстом: http://pastexen.com/code.php?file=aMvORa6As3.cs
Но мне надо превратить это не в коллекцию вспомогательных классов или же коллекцию KeyValuePair. Мне нужен именно словарь, чтобы я мог обратиться к такому объекту следующим образом:
var result = JsonConvert.DeserializeObject
Можно ли как-нибудь сериализовать это в словарь? Может с помощью get/set как-то извернуться?
P.S.:
Я знаю, что в шарпе есть Linq, который позволит сделать что-то типо result.FirstOrDefault(x.value => x.name == "10"), но я пишу переносимую библиотеку и хочу упростить доступ к данным =/
Ответ
Например, можно десериализовать в JObject, и потом сконвертировать данные вручную:
var obj = JObject.Parse(json);
var rates_scores_stats =
((JArray)obj["rates_scores_stats"]).ToDictionary(entry => (int)entry["name"],
entry => (int)entry["value"]);
var rates_statuses_stats =
((JArray)obj["rates_statuses_stats"]).ToDictionary(entry => (string)entry["name"],
entry => (int)entry["value"]);
var result = new MyClass()
{
rates_scores_stats = rates_scores_stats,
rates_statuses_stats = rates_statuses_stats
};
Альтернативный ответ здесь. Немного модифицировав его, можно получить менее «ручное» решение.
Создадим отдельный конвертер (спёрт и модифицирован из ответа по ссылке):
public class JsonGenericDictionaryOrArrayConverter : JsonConverter
{
// поскольку у вас в JSON'е не key/value, а name/value, нужен специальный класс
// для десериализации одного элемента массива
class NameValuePair
public override bool CanConvert(Type objectType)
{
return GetDictionaryKeyValueTypes(objectType).Count() == 1;
}
public override bool CanWrite { get { return false; } }
object ReadJsonGeneric
var dict = existingValue as IDictionary
if (tokenType == JsonToken.StartArray)
{
var pairs = new JsonSerializer()
.Deserialize
public override object ReadJson(
JsonReader reader, Type objectType, object existingValue,
JsonSerializer serializer)
{
// Throws an exception if not exactly one.
var keyValueTypes = GetDictionaryKeyValueTypes(objectType).Single();
var method = GetType().GetMethod(
"ReadJsonGeneric",
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);
var genericMethod = method.MakeGenericMethod(
new[] { keyValueTypes.Key, keyValueTypes.Value });
return genericMethod.Invoke(
this,
new object[] { reader, objectType, existingValue, serializer });
}
public override void WriteJson(
JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotSupportedException();
}
static IEnumerable
static IEnumerable
Имея этот вспомогательный класс, можно десериализовать просто так:
var settings = new JsonSerializerSettings
{
Converters = { new JsonGenericDictionaryOrArrayConverter() }
};
var result = JsonConvert.DeserializeObject
Обновление: Для portable library (.NET 4.5.1 + Windows Universal 8.1 + Windows Phone 8.1) у меня скомпилировалось такое:
public class JsonGenericDictionaryOrArrayConverter : JsonConverter
{
// поскольку у вас в JSON'е не key/value, а name/value, нужен специальный класс
// для десериализации одного элемента массива
class NameValuePair
public override bool CanConvert(Type objectType)
{
return GetDictionaryKeyValueTypes(objectType).Count() == 1;
}
public override bool CanWrite { get { return false; } }
public object ReadJsonGeneric
var dict = existingValue as IDictionary
if (tokenType == JsonToken.StartArray)
{
var pairs = new JsonSerializer()
.Deserialize
public override object ReadJson(
JsonReader reader, Type objectType, object existingValue,
JsonSerializer serializer)
{
// Throws an exception if not exactly one.
var keyValueTypes = GetDictionaryKeyValueTypes(objectType).Single();
var method = GetType().GetTypeInfo().GetDeclaredMethod("ReadJsonGeneric");
var genericMethod = method.MakeGenericMethod(
new[] { keyValueTypes.Key, keyValueTypes.Value });
return genericMethod.Invoke(
this,
new object[] { reader, objectType, existingValue, serializer });
}
public override void WriteJson(
JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotSupportedException();
}
static IEnumerable
static IEnumerable
Комментариев нет:
Отправить комментарий