Вопрос: JSON сериализация в Key-Value
Здравствуйте.
Есть слудующий json:
Json
JSON |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
| {
"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
}
]
} |
|
Я знаю, что его можно сериализовать классом следующего типа:
C# |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| 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; }
} |
|
Но там ведь по сути возвращается ключ-значение. Не хотелось бы городить лишние вспомогательны классы из-за этого.
Не подскажите, как лучше подобное сериализовать, чтобы получилось что-то вроде следующего?
C# |
1
2
3
4
5
| public class RootObject
{
public Dictionary<int, int> rates_scores_stats { get; set; }
public Dictionary<string, int> rates_statuses_stats { get; set; }
} |
|
Конкретно этот пример выдаёт ошибку десериализации =/
Код
C# |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| 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:
Добавлено через 1 час 0 минут
Обнаружил, что если использовать List<KeyValuePair<TKey, TValue>>, то
value подхватывается, а
key нет, ибо в json этот параметр называется
name.
Если изменить в json название параметра
name на
key, но всё работает идеально. Однако я не могу изменять формат выдачи ответа с сервера.
Есть ли возможность как-то заставить ассоциировать
name с ключём?
Добавлено через 15 минут
Сообщение от babaevkamil
Если изменить в json название параметра name на key, но всё работает идеально.
Воистину, всё гениальное просто..
После получения json строки с сервера просто сделал замену Replace("name", "key") и его уже десериализовывал =D
Добавлено через 19 минут
Хотя.. использование List портит очень многое.. теперь нельзя обратиться к значению по ключу.
Может всё же есть способ десериализовать это в словарь?