Другое

Десериализация JSON в Dictionary<string, string> в ASP.NET

Узнайте, как преобразовать JSON в Dictionary<string, string> в ASP.NET 3.5 с помощью Json.NET, JavaScriptSerializer и динамических типов, а также как обрабатывать различные типы значений.

Как десериализовать JSON в Dictionary<string, string> в ASP.NET?

У меня есть простой список ключ‑значение в JSON, который отправляется в ASP.NET через POST. Например:

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

Мне нужно преобразовать его в обычный Dictionary<string, string> или аналогичную структуру данных, например:

  • хеш‑таблицу
  • Dictionary<string, object>
  • StringDictionary
  • двумерный массив строк

Я использую ASP.NET 3.5 и Json.NET (который уже применяю для сериализации на клиент). Ни одна из этих библиотек не предоставляет простого способа десериализовать JSON в простую коллекцию ключ‑значение без использования строго типизированных .NET‑объектов.

Какие лучшие подходы для этого?

Ограничения

  1. Я не хочу реализовывать собственный парсер JSON.
  2. Я пока не могу использовать ASP.NET 4.0.
  3. Предпочитаю избегать устаревшего класса ASP.NET JSON.

Вы можете десериализовать JSON в Dictionary<string, string> в ASP.NET 3.5 несколькими способами с использованием Json.NET, хотя прямое десериализование в строго типизированный Dictionary<string, string> может быть проблематичным из‑за вопросов преобразования типов. Ниже перечислены самые эффективные методы:

Содержание

Проблемы прямой десериализации Dictionary<string, string>

Попытка напрямую десериализовать JSON в Dictionary<string, string> с помощью Json.NET часто завершается неудачей, потому что парсер JSON не преобразует все типы значений в строки автоматически.

csharp
// Это может не сработать, если значения не все строки
Dictionary<string, string> dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);

Проблема возникает, потому что Json.NET выполняет точное сопоставление типов во время десериализации, поэтому если ваш JSON содержит какие‑то не‑строковые значения, десериализация выбросит исключение или завершится без ошибок.

Альтернативный подход: Dictionary<string, object>

Самый надёжный подход в ASP.NET 3.5 — сначала десериализовать в Dictionary<string, object>, а затем преобразовать в Dictionary<string, string>:

csharp
public Dictionary<string, string> DeserializeJsonToDictionary(string json)
{
    // Шаг 1: Десериализовать в Dictionary<string, object>
    Dictionary<string, object> tempDict = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
    
    // Шаг 2: Преобразовать в Dictionary<string, string>
    Dictionary<string, string> result = new Dictionary<string, string>();
    foreach (var kvp in tempDict)
    {
        result.Add(kvp.Key, kvp.Value?.ToString() ?? string.Empty);
    }
    
    return result;
}

Этот подход обрабатывает все типы значений JSON, преобразуя их в строковое представление с помощью метода ToString().

Использование JavaScriptSerializer в ASP.NET 3.5

ASP.NET 3.5 включает класс JavaScriptSerializer в сборке System.Web.Extensions, который предоставляет встроенные возможности десериализации JSON:

csharp
using System.Web.Script.Serialization;

public Dictionary<string, string> DeserializeWithJavaScriptSerializer(string json)
{
    JavaScriptSerializer serializer = new JavaScriptSerializer();
    // Это автоматически создаёт Dictionary<string, object>
    Dictionary<string, object> result = serializer.DeserializeObject(json) as Dictionary<string, object>;
    
    // Преобразовать в словарь строк
    Dictionary<string, string> stringDict = new Dictionary<string, string>();
    foreach (var kvp in result)
    {
        stringDict.Add(kvp.Key, kvp.Value?.ToString() ?? string.Empty);
    }
    
    return stringDict;
}

Согласно исследованию из TeknotopNews, этот подход использует встроенную функциональность .NET 3.5 и надёжно работает для простых пар ключ‑значение.

Решение с динамическим типом

Другой подход — использовать тип dynamic для значений, что обеспечивает большую гибкость:

csharp
public Dictionary<string, dynamic> DeserializeWithDynamicValues(string json)
{
    // Это хорошо работает, но значения остаются динамическими
    return JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(json);
}

Как отмечено в обсуждении StackOverflow, это часто считается «лучшим способом десериализации в словарь», поскольку он обрабатывает все типы значений JSON без ошибок преобразования.

Если вам нужны строковые значения, но вы хотите сохранить гибкость, можно расширить этот подход:

csharp
public Dictionary<string, string> DeserializeWithDynamicConversion(string json)
{
    Dictionary<string, dynamic> dynamicDict = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(json);
    Dictionary<string, string> result = new Dictionary<string, string>();
    
    foreach (var kvp in dynamicDict)
    {
        result.Add(kvp.Key, kvp.Value?.ToString() ?? string.Empty);
    }
    
    return result;
}

Пользовательский метод преобразования

Для более надёжной обработки можно создать обобщённый метод десериализации, который обрабатывает различные структуры JSON:

csharp
public Dictionary<string, string> DeserializeToDictionary(string json)
{
    try
    {
        // Сначала попытаться десериализовать напрямую
        var dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
        return dict ?? new Dictionary<string, string>();
    }
    catch
    {
        // Если не удалось, перейти к подходу с объектным словарём
        Dictionary<string, object> tempDict = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
        Dictionary<string, string> result = new Dictionary<string, string>();
        
        foreach (var kvp in tempDict)
        {
            if (kvp.Value != null)
            {
                result.Add(kvp.Key, kvp.Value.ToString());
            }
            else
            {
                result.Add(kvp.Key, string.Empty);
            }
        }
        
        return result;
    }
}

Альтернатива StringDictionary

Если вы готовы использовать StringDictionary вместо Dictionary<string, string>, можно воспользоваться StringDictionaryConverter Json.NET:

csharp
public StringDictionary DeserializeToStringDictionary(string json)
{
    StringDictionary result = JsonConvert.DeserializeObject<StringDictionary>(json);
    return result;
}

Однако обратите внимание, что StringDictionary нечувствителен к регистру и имеет некоторые ограничения по сравнению с Dictionary<string, string>. Согласно CodeProject, этот подход хорошо работает в сценариях ASP.NET 3.5.

Производительность и рекомендации

Сравнение производительности

Метод Производительность Типобезопасность Гибкость Рекомендовано
Прямой Dictionary<string, string> Самый быстрый Высокая Низкая ❌ Только для чисто строкового JSON
Dictionary<string, object> Хорошая Средняя Высокая ✅ Лучший общий подход
JavaScriptSerializer Хорошая Средняя Высокая ✅ Хорошо для ASP.NET 3.5
Динамический Хорошая Низкая Самая высокая ✅ Для максимальной гибкости

Рекомендованный подход

Для вашего сценария ASP.NET 3.5 я рекомендую использовать подход Dictionary<string, object> с Json.NET:

csharp
public Dictionary<string, string> ProcessJsonFormData(string json)
{
    // Десериализовать в словарь объектов
    Dictionary<string, object> formData = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
    
    // Преобразовать в словарь строк
    Dictionary<string, string> result = new Dictionary<string, string>();
    
    foreach (var kvp in formData)
    {
        // Обработать нулевые значения корректно
        result.Add(kvp.Key, kvp.Value?.ToString() ?? string.Empty);
    }
    
    return result;
}

Пример использования

csharp
// В вашем контроллере ASP.NET
public ActionResult ProcessData()
{
    string json = Request.Form["formData"]; // или получить из Request.InputStream
    
    try
    {
        Dictionary<string, string> formData = ProcessJsonFormData(json);
        
        // Использовать словарь
        foreach (var kvp in formData)
        {
            // Обработать пары ключ‑значение
            string key = kvp.Key;
            string value = kvp.Value;
        }
        
        return Json(new { success = true, data = formData });
    }
    catch (Exception ex)
    {
        return Json(new { success = false, error = ex.Message });
    }
}

Этот подход обеспечивает гибкость при работе с различными типами значений JSON, сохраняя при этом интерфейс словаря строк, который вам нужен. Он надёжный, производительный и хорошо работает в рамках ограничений ASP.NET 3.5.

Источники

  1. StackOverflow: Как десериализовать JSON в простой Dictionary<string,string> в ASP.NET?
  2. Newtonsoft.Json: Deserialize a Dictionary
  3. Microsoft Learn: Как десериализовать JSON в C#
  4. Alex Zaitzev: C#, ASP.NET MVC: Deserialize JSON to Dictionary
  5. TeknotopNews: Deserialize JSON to Dictionary<string,string> in ASP.NET
  6. CodeProject: Strongly typed deserialization of ASP.NET 3.5 ScriptService JSON

Вывод

  • Прямое десериализование в Dictionary<string, string> часто не удаётся из‑за несоответствия типов.
  • Самый надёжный подход — десериализовать сначала в Dictionary<string, object>, а затем преобразовать в строки.
  • JavaScriptSerializer предоставляет встроенную альтернативу для приложений ASP.NET 3.5.
  • Динамические типы обеспечивают максимальную гибкость при работе с различными типами значений JSON.
  • Всегда обрабатывайте нулевые значения корректно, чтобы избежать исключений во время выполнения.
  • Учитывайте компромиссы между типобезопасностью, производительностью и гибкостью при выборе подхода.

Для ваших конкретных требований ASP.NET 3.5 метод преобразования из Dictionary<string, object> в Dictionary<string, string> обеспечивает лучший баланс надёжности и производительности, избавляя от необходимости писать собственный парсер JSON.

Авторы
Проверено модерацией
Модерация