c# - servicio - ¿Cómo deserializar los datos JSON?
serialize json c# newtonsoft (4)
Soy nuevo en el trabajo con datos JSON.
Estoy leyendo datos de un servicio web. Los datos de consulta devueltos son los siguientes:
[["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"]]
¿Hay alguna forma de deserializar estos datos de tal forma que el objeto base se genere sin que yo primero defina cómo es el objeto? En el ejemplo anterior, el objeto está definido por la primera fila:
["B02001_001E","NAME","state"],
En general, el servicio web devolverá los datos de la consulta formateados como una matriz JSON bidimensional en la que la primera fila proporciona nombres de columna y las filas posteriores proporcionan valores de datos.
Paso 1: visite json.org para encontrar la biblioteca JSON para cualquier tecnología que esté utilizando para llamar a este servicio web. Descargue y enlace a esa biblioteca.
Paso 2: digamos que estás usando Java. Utilizarías JSONArray así:
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);
}
}
Puede escribir su propio analizador JSON y hacerlo más genérico según sus necesidades. Aquí hay uno que sirvió mi propósito muy bien, la esperanza también te ayudará.
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;
}
}
Puedes deserializar esto muy fácilmente. La estructura de los datos en C # es simplemente List<string[]>
por lo que podría hacer;
List<string[]> data = JsonConvert.DeserializeObject<List<string[]>>(jsonString);
El código anterior supone que estás usando json.NET.
EDITAR: tenga en cuenta que json es técnicamente una matriz de matrices de cadenas. Prefiero usar List<string[]>
para mi propia declaración porque es mucho más intuitivo. No causará ningún problema para json.NET, si quieres que sea una matriz de matrices de cadenas, entonces necesitas cambiar el tipo a (creo) string[][]
pero hay algunas pequeñas y divertidas gotcha con irregularidades y Arrays 2D en C # que realmente no conozco, así que no me molesto en lidiar con esto aquí.
Si usa .Net 4.5 también puede usar el serializador .Net json estándar:
using System.Runtime.Serialization.Json;
...
Stream jsonSource = ...; // serializer will read data stream
var s = new DataContractJsonSerializer(typeof(string[][]));
var j = (string[][])s.ReadObject(jsonSource);
En .Net 4.5 y versiones anteriores puede usar la clase JavaScriptSerializer:
using System.Web.Script.Serialization;
...
JavaScriptSerializer serializer = new JavaScriptSerializer();
string[][] list = serializer.Deserialize<string[][]>(json);