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; } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д