Подтвердить что ты не робот

Как десериализовать данные JSON?

Я новичок в работе с данными JSON.

Я читаю данные из веб-службы. Данные запроса отправляются обратно:

[["B02001_001E","NAME","state"],
 ["4712651","Alabama","01"],
 ["691189","Alaska","02"],
 ["6246816","Arizona","04"],
 ["18511620","Florida","12"],
 ["9468815","Georgia","13"],
 ["1333591","Hawaii","15"],
 ["1526797","Idaho","16"],
 ["3762322","Puerto Rico","72"]]

Есть ли способ десериализовать эти данные таким образом, чтобы базовый объект генерировался без меня, сначала определяя, что такое объект? В приведенном выше примере объект определяется первой строкой:

           ["B02001_001E","NAME","state"],

В общем случае веб-служба возвращает данные запроса, отформатированные в виде двумерного массива JSON, где первая строка содержит имена столбцов, а последующие строки предоставляют значения данных.

4b9b3361

Ответ 1

Вы можете легко удалить десериализацию. Структура данных в С# - это всего лишь List<string[]>, поэтому вы можете просто сделать:

  List<string[]> data = JsonConvert.DeserializeObject<List<string[]>>(jsonString);

Приведенный выше код предполагает, что вы используете json.NET.

EDIT: Обратите внимание, что json является технически массивом строковых массивов. Я предпочитаю использовать List<string[]> для моего собственного объявления, потому что он более интуитивно понятен. Это не вызовет никаких проблем для json.NET, если вы хотите, чтобы это был массив массивов строк, тогда вам нужно изменить тип на (я думаю) string[][], но есть некоторые забавные маленькие матчи с зубчатыми и двумерными массивами в С#, о котором я действительно не знаю, поэтому я просто не беспокоюсь об этом.

Ответ 2

Если вы используете .Net 4.5, вы также можете использовать стандартный .net json serializer:

using System.Runtime.Serialization.Json;
...    
Stream jsonSource = ...; // serializer will read data stream
var s = new DataContractJsonSerializer(typeof(string[][]));
var j = (string[][])s.ReadObject(jsonSource);

В .Net 4.5 и старше вы можете использовать класс JavaScriptSerializer:

using System.Web.Script.Serialization;
...
JavaScriptSerializer serializer = new JavaScriptSerializer();
string[][] list = serializer.Deserialize<string[][]>(json);

Ответ 3

Шаг 1. Перейдите на json.org, чтобы найти библиотеку JSON для любой технологии, которую вы используете, для вызова этого веб-сервиса. Загрузите и подключитесь к этой библиотеке.

Шаг 2: Скажем, вы используете Java. Вы бы использовали JSONArray следующим образом:

JSONArray myArray=new JSONArray(queryResponse);
for (int i=0;i<myArray.length;i++){
    JSONArray myInteriorArray=myArray.getJSONArray(i);
    if (i==0) {
        //this is the first one and is special because it holds the name of the query.
    }else{
        //do your stuff
        String stateCode=myInteriorArray.getString(0);
        String stateName=myInteriorArray.getString(1);
    }
}

Ответ 4

Вы можете написать собственный анализатор JSON и сделать его более универсальным на основе вашего требования. Вот тот, который хорошо послужил моей цели, надеюсь, вам тоже помогут.

class JsonParsor
{
    public static DataTable JsonParse(String rawJson)
    {
        DataTable dataTable = new DataTable();
        Dictionary<string, string> outdict = new Dictionary<string, string>();
        StringBuilder keybufferbuilder = new StringBuilder();
        StringBuilder valuebufferbuilder = new StringBuilder();
        StringReader bufferreader = new StringReader(rawJson);
        int s = 0;
        bool reading = false;
        bool inside_string = false;
        bool reading_value = false;
        bool reading_number = false;
        while (s >= 0)
        {
            s = bufferreader.Read();
            //open JSON
            if (!reading)
            {
                if ((char)s == '{' && !inside_string && !reading)
                {
                    reading = true;
                    continue;
                }
                if ((char)s == '}' && !inside_string && !reading)
                    break;
                if ((char)s == ']' && !inside_string && !reading)
                    continue;
                if ((char)s == ',')
                    continue;
            }
            else
            {
                if (reading_value)
                {
                    if (!inside_string && (char)s >= '0' && (char)s <= '9')
                    {
                        reading_number = true;
                        valuebufferbuilder.Append((char)s);
                        continue;
                    }
                }
                //if we find a quote and we are not yet inside a string, advance and get inside
                if (!inside_string)
                {
                    if ((char)s == '\"' && !inside_string)
                        inside_string = true;
                    if ((char)s == '[' && !inside_string)
                    {
                        keybufferbuilder.Length = 0;
                        valuebufferbuilder.Length = 0;
                                reading = false;
                                inside_string = false;
                                reading_value = false;
                    }
                    if ((char)s == ',' && !inside_string && reading_number)
                    {
                        if (!dataTable.Columns.Contains(keybufferbuilder.ToString()))
                            dataTable.Columns.Add(keybufferbuilder.ToString(), typeof(string));
                        if (!outdict.ContainsKey(keybufferbuilder.ToString()))
                            outdict.Add(keybufferbuilder.ToString(), valuebufferbuilder.ToString());
                        keybufferbuilder.Length = 0;
                        valuebufferbuilder.Length = 0;
                        reading_value = false;
                        reading_number = false;
                    }
                    continue;
                }

                //if we reach end of the string
                if (inside_string)
                {
                    if ((char)s == '\"')
                    {
                        inside_string = false;
                        s = bufferreader.Read();
                        if ((char)s == ':')
                        {
                            reading_value = true;
                            continue;
                        }
                        if (reading_value && (char)s == ',')
                        {
                            //put the key-value pair into dictionary
                            if(!dataTable.Columns.Contains(keybufferbuilder.ToString()))
                                dataTable.Columns.Add(keybufferbuilder.ToString(),typeof(string));
                            if (!outdict.ContainsKey(keybufferbuilder.ToString()))
                            outdict.Add(keybufferbuilder.ToString(), valuebufferbuilder.ToString());
                            keybufferbuilder.Length = 0;
                            valuebufferbuilder.Length = 0;
                            reading_value = false;
                        }
                        if (reading_value && (char)s == '}')
                        {
                            if (!dataTable.Columns.Contains(keybufferbuilder.ToString()))
                                dataTable.Columns.Add(keybufferbuilder.ToString(), typeof(string));
                            if (!outdict.ContainsKey(keybufferbuilder.ToString()))
                                outdict.Add(keybufferbuilder.ToString(), valuebufferbuilder.ToString());
                            ICollection key = outdict.Keys;
                            DataRow newrow = dataTable.NewRow();
                            foreach (string k_loopVariable in key)
                            {
                                CommonModule.LogTheMessage(outdict[k_loopVariable],"","","");
                                newrow[k_loopVariable] = outdict[k_loopVariable];
                            }
                            dataTable.Rows.Add(newrow);
                            CommonModule.LogTheMessage(dataTable.Rows.Count.ToString(), "", "row_count", "");
                            outdict.Clear();
                            keybufferbuilder.Length=0;
                            valuebufferbuilder.Length=0;
                            reading_value = false;
                            reading = false;
                            continue;
                        }
                    }
                    else
                    {
                        if (reading_value)
                        {
                            valuebufferbuilder.Append((char)s);
                            continue;
                        }
                        else
                        {
                            keybufferbuilder.Append((char)s);
                            continue;
                        }
                    }
                }
                else
                {
                    switch ((char)s)
                    {
                        case ':':
                            reading_value = true;
                            break;
                        default:
                            if (reading_value)
                            {
                                valuebufferbuilder.Append((char)s);
                            }
                            else
                            {
                                keybufferbuilder.Append((char)s);
                            }
                            break;
                    }
                }
            }
        }

        return dataTable;
    }
}