JSON сериализация в Key-Value - C#

Узнай цену своей работы

Формулировка задачи:

Здравствуйте. Есть слудующий 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
        }
    ]
}
Я знаю, что его можно сериализовать классом следующего типа:
    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, но всё работает идеально.
Воистину, всё гениальное просто.. После получения json строки с сервера просто сделал замену Replace("name", "key") и его уже десериализовывал =D
Хотя.. использование 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; }
    }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

5   голосов , оценка 4 из 5