JSON сериализация в Key-Value - C#
Формулировка задачи:
Здравствуйте.
Есть слудующий json:
Я знаю, что его можно сериализовать классом следующего типа:
Но там ведь по сути возвращается ключ-значение. Не хотелось бы городить лишние вспомогательны классы из-за этого.
Не подскажите, как лучше подобное сериализовать, чтобы получилось что-то вроде следующего?
Конкретно этот пример выдаёт ошибку десериализации =/
Воистину, всё гениальное просто..
После получения json строки с сервера просто сделал замену Replace("name", "key") и его уже десериализовывал =D
{
"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
}
]
} public class RatesScoresStat
{
public int name { get; set; }
public int value { get; set; }
}
public class RatesStatusesStat
{
public string name { get; set; }
public int value { get; set; }
}
public class RootObject
{
public List<RatesScoresStat> rates_scores_stats { get; set; }
public List<RatesStatusesStat> rates_statuses_stats { get; set; }
} public class RootObject
{
public Dictionary<int, int> rates_scores_stats { get; set; }
public Dictionary<string, int> rates_statuses_stats { get; set; }
}using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.IO;
using System.Net;
namespace ShikiTestApp
{
class Program
{
static void Main(string[] args)
{
string json = "{'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}]}";
var result = JsonConvert.DeserializeObject<TestClass>(json);
Console.WriteLine(result.rates_scores_stats[9]);
}
}
public class TestClass
{
public Dictionary<int, int> rates_scores_stats { get; set; }
public Dictionary<string, int> rates_statuses_stats { get; set; }
}
}
Newtonsoft.Json.JsonSerializationException не обработано
HResult=-2146233088
Message=Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'System.Collections.Generic.Dictionary`2[System.Int32,System.Int32]' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
Path 'rates_scores_stats', line 1, position 23.
Source=Newtonsoft.Json
StackTrace:
в Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureArrayContract(JsonReader reader, Type objectType, JsonContract contract)
в Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id)
в Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
в Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
в Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
в Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
в Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
в Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
в Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
в Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
в Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
в Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value)
в ShikiTestApp.Program.Main(String[] args) в D:\Clouds\OneDrive\Documents\Visual Studio 2015\Projects\!Experemental\ShikiTestApp\ShikiTestApp\Program.cs:строка 18
в System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
в System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
в Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
в System.Threading.ThreadHelper.ThreadStart_Context(Object state)
в System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
в System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
в System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
в System.Threading.ThreadHelper.ThreadStart()
InnerException:
Обнаружил, что если использовать List>, то
value
подхватывается, аkey
нет, ибо в json этот параметр называетсяname
. Если изменить в json название параметраname
наkey
, но всё работает идеально. Однако я не могу изменять формат выдачи ответа с сервера. Есть ли возможность как-то заставить ассоциироватьname
с ключём?
Если изменить в json название параметра name на key, но всё работает идеально.
Хотя.. использование List портит очень многое.. теперь нельзя обратиться к значению по ключу.
Может всё же есть способ десериализовать это в словарь?
Решение задачи: «JSON сериализация в Key-Value»
textual
Листинг программы
class Program
{
static void Main(string[] args)
{
string json = "{'rates_scores_stats':[{'name':10,'value':3551},{'name':9,'value':1002},{'name':8,'value':823},{'name':7,'value':493},{'name':6,'value':218},{'name':5,'value':139},{'name':4,'value':80},{'name':3,'value':41},{'name':2,'value':26},{'name':1,'value':83}],'rates_statuses_stats':[{'name':'Запланировано','value':2505},{'name':'Смотрю','value':7870},{'name':'Просмотрено','value':1949},{'name':'Отложено','value':1444},{'name':'Брошено','value':1358}]}";
var result = JsonConvert.DeserializeObject<MyClass>(json, new JsonSerializerSettings { Converters = new JsonConverter[] { new JsonGenericDictionaryOrArrayConverterNameValueMod() } });
Console.WriteLine(result.rates_scores_stats[10] + " | " + result.rates_statuses_stats["Брошено"]);
Console.ReadLine();
}
}
public class MyClass
{
public IDictionary<int, int> rates_scores_stats { get; set; }
public IDictionary<string, int> rates_statuses_stats { get; set; }
}