Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.62/13: Рейтинг темы: голосов - 13, средняя оценка - 4.62
58 / 57 / 15
Регистрация: 15.09.2012
Сообщений: 557
1
.NET 2.x

Json-сериализация ассоциативного массива

05.02.2015, 21:31. Показов 2485. Ответов 19
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
В PHP есть асоциативный масив. При JSON-сериализации для GET запроса получается такая картина
PHP
1
 array[key1]=value1&array[key2]=value2&array[key3]=value3...
Как получить такую строку в С# ? Сериализация Dictionary, List, Array такого еффекта не дает.

Добавлено через 1 час 44 минуты
Это думаю нужно применять кодирование application/x-www-form-urlencoded. Кто знает как это делать средствами Net2.0 ?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
05.02.2015, 21:31
Ответы с готовыми решениями:

Newtonsoft.Json.JsonConvert Де-/Сериализация .NET и JS
Сериализовали мы допустим какой-то класс в .NET методом SerializeObject. Что мы получим в JS при...

Сериализация полученных данных из MySQL в формате JSON
Доброго времени суток, товарищи. Сначала, что я делаю. Получаю из внешнего источника строку в...

Сериализация и десериализация в Json нескольких разных классов
Добрый день. Стоит такая задача. Есть приложение которое сериализует данные, есть второе...

Сериализация структуры из массива
Помогите пж..:) есть структура public struct DiskProperties { ...

19
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
06.02.2015, 01:39 2
ASDFD12, what am I reading?

по-человечески теперь сформулируйте вопрос
0
58 / 57 / 15
Регистрация: 15.09.2012
Сообщений: 557
06.02.2015, 09:48  [ТС] 3
Попытка номер 2.
Если создать Dictionary
C#
1
2
3
4
5
Dictionary<string, object> dict = new Dictionary<string, object>();
dict.Add("key1","value1");
dict.Add("key2","value2");
dict.Add("key3","value3");
Log(Json.Serialize(dict));
Получим
C#
1
{"key1":"value1", "key2":"vlue2", "key3":"value3"}
При передачи этих данных в GET запросе должна быть такая строка.
C++
1
адрес?key1=value1&key2=value2&key3=value3
Первый вопрос
1. Как получить выше указанную строку ?
(Имеется ввиду есть ли уже готовые методы. Можно конечно в цикле распарсить словарь и получить данную строку. Но я думаю это кодирование application/x-www-form-urlencoding)
2. Второй вопрос.
Если есть такой метод (или набор методов) когда мы получаем выше описанную строку параметров из словаря,то :
ЧТО должно быть на входе, чтобы на выходе получить
C#
1
array[key1]=value1&array[key2]=value2&array[key3]=value3
0
653 / 589 / 171
Регистрация: 17.07.2012
Сообщений: 1,670
Записей в блоге: 1
06.02.2015, 10:09 4
Цитата Сообщение от ASDFD12 Посмотреть сообщение
Имеется ввиду есть ли уже готовые методы
Думаю, что нет, ибо они ни к чему. Что вам мешает написать свой в одну строку и не заморачиваться по этому поводу?
0
58 / 57 / 15
Регистрация: 15.09.2012
Сообщений: 557
06.02.2015, 10:39  [ТС] 5
Продемонстрируйте в одну строчку второй вопрос. Имеется ввиду должен быть общий контейнер для параметров - в нем лежат масивы, словари, списки. Это все должно распарсится с этого общего контейнера и сформироваться правильная строка параметров для GET запроса.
0
653 / 589 / 171
Регистрация: 17.07.2012
Сообщений: 1,670
Записей в блоге: 1
06.02.2015, 10:55 6
ASDFD12, теперь я понял, что вы хотите. В одну строчку не получится, да. Тем не менее, добавляется только ситуация с массивом/словарём. Тут у меня просто нет понятия, как это должно выглядеть, но опять же, всё это реализуется совсем несложным образом.
0
58 / 57 / 15
Регистрация: 15.09.2012
Сообщений: 557
06.02.2015, 11:04  [ТС] 7
Проблема в том что я не нашел на С# комбинации (список словарей, масив словарей, словарь словарей), которая бы соответствовала асоциативному масиву в PHP , который распарсивается в такую строчку
C#
1
array[key1]=value1&array[key2]=value2&array[key3]=value3
Тоесть перед каждым ключем стоит имя масива.
Чем предложите заменить?
0
653 / 589 / 171
Регистрация: 17.07.2012
Сообщений: 1,670
Записей в блоге: 1
06.02.2015, 12:02 8
ASDFD12, имя массива то что в Key словаря исходного? Теперь я снова ничего не понимаю.

Я короче совсем запутался, .Net-то какой?
0
58 / 57 / 15
Регистрация: 15.09.2012
Сообщений: 557
06.02.2015, 12:02  [ТС] 9
Спасибо. Порадовала строчка
C#
1
 yield return String.Format("{0}[{1}]={2}", parameter.Key, pair.Key, pair.Value);
Как по мне решение достаточно компактное. И все методы поддерживают Net2.0
Интересно только, нет ли метода кодирование строки в application/x-www-form-urlencoding?
Он по сути должен был автоматически это все сделать
0
653 / 589 / 171
Регистрация: 17.07.2012
Сообщений: 1,670
Записей в блоге: 1
06.02.2015, 12:09 10
Цитата Сообщение от ASDFD12 Посмотреть сообщение
Как по мне решение достаточно компактное. И все методы поддерживают Net2.0
да вот в этом-то и проблема, что нет. Смутил меня Dictionary в вашем примере.

Не по теме:

Решение, которое я удалил в предыдущем посте...

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
private static IEnumerable<string> GetParameters(Dictionary<string, object> parameters)
{
    foreach (var parameter in parameters)
    {
        if (parameter.Value as IDictionary != null)
        {
            var dict = ((IDictionary)parameter.Value).Cast<KeyValuePair<string, object>>();
            foreach (var pair in dict)
            {
                yield return String.Format("{0}[{1}]={2}", parameter.Key, pair.Key, pair.Value);
            }
        }
        else if ((parameter.Value as IList != null))
        {
            var en = ((IList)parameter.Value);
            for (int i = 0; i < en.Count; i++)
                yield return String.Format("{0}[{1}]={2}", parameter.Key, i.ToString(), en[i]);
        }
        else
        {
            yield return String.Format("{0}={1}", parameter.Key, parameter.Value);
        }
    }
}
 
public static string Serialize(Dictionary<string, object> parameters)
{
    return String.Join("&", GetParameters(parameters));
}

0
58 / 57 / 15
Регистрация: 15.09.2012
Сообщений: 557
06.02.2015, 12:27  [ТС] 11
Цитата Сообщение от Cupko Посмотреть сообщение
да вот в этом-то и проблема, что нет. Смутил меня Dictionary в вашем примере.
Может предложите более оригинальное решение.
Смысл вообще простой.
1.Нужен удобный и прозрачный механизм добавление параметров в контейнер (это типо для пользователя библиотеки).
На уровне библиотеки :
Нужно также удобно сортировать все параметры по ключу в алфавитном порядке.
И легко формировать строку параметров для GET запроса. С описаным выше нюансом для асоциативного масива PHP.
HttpWebRequest не используется.
0
653 / 589 / 171
Регистрация: 17.07.2012
Сообщений: 1,670
Записей в блоге: 1
06.02.2015, 12:44 12
ASDFD12, я просто со 2ым фреймворком не работал вообще, и немного подзабыл уже что там есть, а чего нет. Сейчас попробую чего-нибудь придумать.

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
30
31
32
33
34
35
36
37
public static IEnumerable<string> GetParameters(Dictionary<string, object> parameters)
{
    foreach (var parameter in parameters)
    {
        if (parameter.Value as IDictionary<string, object> != null)
        {
            var dict = ((IDictionary<string, object>)parameter.Value);
            foreach (var pair in dict)
            {
                yield return String.Format("{0}[{1}]={2}", parameter.Key, pair.Key, pair.Value);
            }
        }
        else if ((parameter.Value as IList != null))
        {
            var en = ((IList)parameter.Value);
            for (int i = 0; i < en.Count; i++)
                yield return String.Format("{0}[{1}]={2}", parameter.Key, i.ToString(), en[i]);
        }
        else
        {
            yield return String.Format("{0}={1}", parameter.Key, parameter.Value);
        }
    }
}
 
public static string Serialize(Dictionary<string, object> parameters)
{
    var result = GetParameters(parameters);
    var sb = new StringBuilder();
    foreach (var item in result)
    {
        sb.Append(item);
        sb.Append("&");
    }
    sb.Remove(sb.Length - 1, 1);
    return sb.ToString();
}
Такой код скомпилился под 2.0.
1
58 / 57 / 15
Регистрация: 15.09.2012
Сообщений: 557
06.02.2015, 13:03  [ТС] 13
Цитата Сообщение от Cupko Посмотреть сообщение
Сейчас попробую чего-нибудь придумать
Спасибо. Только хотел уточнить что передаются данные в формате Json.
Типо сначала конвертируем в Json, дальше нужно преобразовать в формат application/x-www-form
0
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
07.02.2015, 00:55 14
ASDFD12, ну так а причем тут JSON?
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<string, object> dict = new Dictionary<string, object>
            {
                {"key1", "value1"},
                {"key2", "value2"},
                {"key3", "value3"}
            };
            string s = ConvertToQueryString(dict);
            Console.WriteLine(s);
        }
 
        private static string ConvertToQueryString<TKey, TValue>(IEnumerable<KeyValuePair<TKey, TValue>> dict)
        {
            return string.Join("&", dict.Select(x => x.Key + "=" + x.Value));
        }
    }
Добавлено через 49 секунд
Почему этот метод лучше? А очень просто:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
        static void Main(string[] args)
        {
            Dictionary<string, object> dict = new Dictionary<string, object>
            {
                {"key1", "value1"},
                {"key2", "value2"},
                {"key3", "value1"},
                {"key4", "value2"},
                {"key5", "value1"},
                {"key6", "value2"},
                {"key7", "value1"},
                {"key8", "value2"},
                {"key9", "value1"},
                {"key10", "value2"},
                {"key11", "value1"},
                {"key12", "value2"},
                {"key13", "value1"},
                {"key14", "value2"},
                {"key15", "value1"},
            };
            string s = ConvertToQueryString(dict);
            Console.WriteLine(s);
        }
1
58 / 57 / 15
Регистрация: 15.09.2012
Сообщений: 557
07.02.2015, 11:06  [ТС] 15
Psilon, решение красивое, только в Net2.0 не поддерживается.
И я так понял он не сработает если value в свою очередь будет также словарем или списком словарей.
0
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
07.02.2015, 11:14 16
ASDFD12, ну в .Net 2.0 можно тоже написать
C#
1
2
3
4
5
6
7
        private static string ConvertToQueryString<TKey, TValue>(ICollection<KeyValuePair<TKey, TValue>> dict)
        {
            var result = new StringBuilder(20*dict.Count);
            foreach (var pair in dict)
                result.Append(pair.Key + "=" + pair.Value + "&");
            return result.Remove(result.Length - 1, 1).ToString();
        }
так даже чуть быстрее работать будет, чем вариант выше. Правда, 2 лишних строчки, но это же не проблема, если вызывать метод нужно точно также.

Можно убрать ограничение на ICollection (я просто его использую чтобы прикинуть, сколько памяти нужно билдеру), но можно и просто выделить большой кусок:
C#
1
2
3
4
5
6
7
        private static string ConvertToQueryString<TKey, TValue>(IEnumerable<KeyValuePair<TKey, TValue>> dict)
        {
            var result = new StringBuilder(8000);
            foreach (var pair in dict)
                result.Append(pair.Key + "=" + pair.Value + "&");
            return result.Remove(result.Length - 1, 1).ToString();
        }
Добавлено через 1 минуту
ASDFD12, по-умолчанию querystring это словарь - 1 ключ 1 значение, там не может быть вложенных словарей.
0
58 / 57 / 15
Регистрация: 15.09.2012
Сообщений: 557
07.02.2015, 11:27  [ТС] 17
Цитата Сообщение от Psilon Посмотреть сообщение
по-умолчанию querystring это словарь - 1 ключ 1 значение
Конечно в таком случае все банально просто.
Дело в том что в values как раз могут находится список словарей - это будет вместо асоциативного масива PHP
и он будет парсится как предложил Cupko,
C#
1
 yield return String.Format("{0}[{1}]={2}", parameter.Key, pair.Key, pair.Value);
И кроме того в values будет словарь, будет парсится типо так (в ключе key1 находится словарь)
C#
1
key1=subkey1=subvalue1&subkey2=subvalue2..
Добавлено через 2 минуты
И так теоретически может быть до бесконечности, тоесть subvalue1 может быть в свою очередь словарем).
Думаю это реализовать через рекурсивный вызов. Но еще в процесе)
0
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
07.02.2015, 11:33 18
ASDFD12, это не стадартный (чего еще от PHP ожидать ) формат передачи, Поэтому логично, что нужно самому писать метод для такой обработки. Тем более почему-то .Net 2.0 онли (хотя даже в XP, который уже почти помер, поддерживает 3.5)
0
58 / 57 / 15
Регистрация: 15.09.2012
Сообщений: 557
07.02.2015, 11:38  [ТС] 19
Цитата Сообщение от Psilon Посмотреть сообщение
почему-то .Net 2.0 онли
Для движка Unity3d
0
Master of Orion
Эксперт .NET
6098 / 4954 / 905
Регистрация: 10.07.2011
Сообщений: 14,522
Записей в блоге: 5
07.02.2015, 17:15 20
Cupko, лучше так писать (во-первых не надо дважды кастовать, во-вторых мало кто реализует IList.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var dict = parameter.Value as IDictionary<string, object>;
        if (dict  != null)
            foreach (var pair in dict)
            {
                yield return String.Format("{0}[{1}]={2}", parameter.Key, pair.Key, pair.Value);
                continue;
            }
        var enumerable = parameter.Value as IEnumerable; //тут можно что-то придумать, нужно дженерики все же юзать
        if (enumerable  != null))
        {
            int i = 0;
            foreach(var val in enumerable)
                yield return String.Format("{0}[{1}]={2}", parameter.Key, i.ToString(), val);
        }
        else
        {
            yield return String.Format("{0}={1}", parameter.Key, parameter.Value);
        }
Добавлено через 38 секунд
Цитата Сообщение от ASDFD12 Посмотреть сообщение
Для движка Unity3d
ват?
http://unity3d.com/unity/whats-new/unity-4.5.1

Добавлено через 3 минуты
Cupko, в общем, честно говоря, я не понимаю, зачем вам такое извращение. Нужен JSON - юзайте json, нужно конвертировать в querystring - она не предназначена для хранения иерархической информации. Смешивать одно с другим - еще хуже.

Добавлено через 5 часов 31 минуту
i++ забыл в цикле.
1
07.02.2015, 17:15
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.02.2015, 17:15
Помогаю со студенческими работами здесь

Ошибка при обработке Json - Cannot deserialize the current JSON array because the type requires a JSON object
Всем привет! Помогите, плиз, разобраться с ошибкой: An unhandled exception of type...

Ошибка при обработке Json - Cannot deserialize the current JSON array because the type requires a JSON object
Дополнительные сведения: Cannot deserialize the current JSON object (e.g. {&quot;name&quot;:&quot;value&quot;}) into...

Сериализация массива экземпляров класса
public class Employees { public int BirthDate; ...

Сериализация и десериализация формата Json
Здравствуйте Пытаюсь разобраться как десериализовать и сериализовать из формата Json в обычную...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru