Вопрос по asp.net-web-api, json, c#, json.net, .net – Десериализовать словарь с помощью JSON.NET

2

Я использую Newtonsoft.Json с версией 4.0.8 и пытаюсь использовать его с веб-API. Поэтому я хотел десериализовать JSON с

JsonConvert.DeserializeObject<AClass>(jsonString);

Это работает, пока я не добавил словарь как свойство в этот класс и не хочу десериализовать его.

Строка JSON имеет вид

{ 
   "Date":null,
   "AString":"message",
   "Attributes":[
                   {"Key":"key1","Value":"value1"},      
                   {"Key":"key2","Value":"value2"}
                ],
    "Id":0,
    "Description":"...
}

При десериализации исключения типаJsonSerializationException происходит с сообщением: & quot;Cannot deserialize JSON array into type 'System.Collections.Generic.Dictionary`2[System.String,System.String]'.& Quot;

Что я здесь не так делаю?

UPDATE1: При сериализации с JSON.NET я получаю следующее для словаря:

Attributes":{"key1":"value1","key2":"value2"}

Похоже, что WebApi десериализует объект не так, как Json.Net. На стороне сервера я использую следующую строку для неявной десериализации:

return new HttpResponseMessage<AClass>(object);

UPDATE2: В качестве обходного пути я пришел к следующей линии на стороне сервера.

return new HttpResponseMessage<string>(JsonConvert.SerializeObject(license).Base64Encode());

Я конвертирую его на стороне сервера Json.Net и передаю как строку в кодировке base64. Таким образом, Json.Net может десериализовать свой собственный формат.

Но это все еще не то, что я хочу, так есть ли еще какие-нибудь предложения?

Какой JSON вы получите, если сериализуете класс? Rawling
Спасибо за ваш быстрый ответ. Я обновил свой вопрос соответственно. dasheddot
Если только в Web API или Newtonsoft не предусмотрена опция, позволяющая обрабатывать словари в «напротив» таким образом, я бы просто предложил использовать одну и ту же библиотеку на каждом конце (сериализовать / десериализовать), если это вообще возможно. Rawling

Ваш Ответ

4   ответа
3

Это должно работать, если вы объявитеAttributes какList<KeyValuePair<string, string>>

1
Dictionary<string, object> result = JsonConvert.DeserializeObject<Dictionary<string, object>>(strJsonResult);
0

DataContract атрибуты иКласс DataContractJsonSerializer для обеспечения формата сообщения:

    [DataContract]
    public class Message
    {
        [DataMember]
        public DateTime? Date { get; set; }
        [DataMember]
        public string AString { get; set; }
        [DataMember]
        public Dictionary<string, string> Attributes { get; set; }
        [DataMember]
        public int Id { get; set; }
        [DataMember]
        public string Description { get; set; }
    }

        DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(Message));

        Message message = null;
        using (MemoryStream jsonStream = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)))
        {
            // Deserialize
            message = (Message)jsonSerializer.ReadObject(jsonStream);

            // Go to the beginning and discard the current stream contents.
            jsonStream.Seek(0, SeekOrigin.Begin);
            jsonStream.SetLength(0);

            // Serialize
            jsonSerializer.WriteObject(jsonStream, message);
            jsonString = Encoding.UTF8.GetString(jsonStream.ToArray());
        }

Сериализация этого возврата приводит к следующему JSON:

{"AString":"message","Attributes":[{"Key":"key1","Value":"value1"},{"Key":"key2","Value":"value2"}],"Date":null,"Description":"...","Id":0}
Спасибо, но я хочу сделать это с Json.Net, так как мы уже используем его в нескольких местах решения, поэтому я больше не хочу использовать .Nets DataContractSerializer. dasheddot
1

эта почтазвонит

JsonConvert.SerializeObject(yourObject, new KeyValuePairConverter());

получает ваш JSON в формате, который создает для вас Web API.

Ergo, можно предположить, что вызов

JsonConvert.DeserializeObject<AClass>(jsonString, new KeyValuePairConverter());

будет делать обратное и правильно обрабатывать стиль Web API.

Я понятия не имею, существует ли эта перегрузка, хотя; попробуйте и посмотрите, что получится ...

Я попробовал это, но с тем же результатом. Такое же исключение возникает даже при использовании преобразователя keyvaluepair, применяемого при десериализации. dasheddot
Эх, достаточно честно. Стоит попробовать.

Похожие вопросы