servicio - recorrer json c#
¿Puedes instanciar una instancia de objeto de JSON en.NET? (6)
Dado que los inicializadores de objetos son muy similares a JSON, y ahora hay tipos anónimos en .NET. Sería genial poder tomar una cadena, como JSON, y crear un objeto anónimo que represente la cadena JSON.
Use Iniciales de objetos para crear un tipo anónimo:
var person = new {
FirstName = "Chris",
LastName = "Johnson"
};
Sería increíble si pudiera pasar una representación en cadena del código del inicializador de objetos (preferiblemente algo como JSON) para crear una instancia de un tipo anónimo con esos datos.
No sé si es posible, ya que C # no es dinámico, y el compilador realmente convierte el Inicializador de objetos y el Tipo anónimo en un código fuertemente tipado que se puede ejecutar. Esto se explica en este artículo.
Tal vez la funcionalidad para tomar JSON y crear un Diccionario de clave / valor con ella funcionaría mejor.
Sé que puedes serializar / deserializar un objeto en JSON en .NET, pero lo que busco es una forma de crear un objeto que, en esencia, esté tipeado de manera similar a como funciona JavaScript.
¿Alguien sabe la mejor solución para hacer esto en .NET?
ACTUALIZACIÓN: Demasiado aclarar el contexto de por qué estoy preguntando esto ... Estaba pensando en cómo C # podría soportar mejor JSON en el nivel de lenguaje (posiblemente) y estaba tratando de pensar en maneras en que podría hacerse hoy, para conceptual razones. Entonces, pensé que lo publicaría aquí para comenzar una discusión.
¿Cuál es la aplicación para esto?
No iría por este camino por algunas razones.
Primero; puede requerir una gran cantidad de código de soporte utilizando la reflexión y tal para crear el método transparente del que está hablando.
En segundo lugar, como dijiste, C # es un lenguaje fuertemente tipado y cosas como estas quedaron fuera de la especificación del lenguaje por una razón.
En tercer lugar, la sobrecarga por hacer esto no valdría la pena. Recuerde que las páginas web (especialmente las consultas AJAX) deben ser realmente rápidas o que fracasen en el propósito. Si continúas y pasas el 50% serializando tus objetos entre C # y Javascript, entonces tienes un problema.
Mi solución sería crear una clase que simplemente encapsule un diccionario y que tome una cadena JSON como argumento ctor. A continuación, amplíe esa clase para cada tipo de consulta JSON que desee controlar. Esta será una solución fuertemente tipada y más rápida, pero aún así mantendrá la extensibilidad y la facilidad de uso. La desventaja es que hay más código para escribir por tipo de solicitud JSON.
:)
Deberías echarle un vistazo al proyecto JSON.net :
http://james.newtonking.com/pages/json-net.aspx
Básicamente estás hablando de la capacidad de hidratar un objeto de JSON, lo que hará. No hará los tipos anónimos, pero tal vez te acerque lo suficiente.
Escribí un método relativamente corto que analizará JSON y devolverá un diccionario de nombre / valor al que se puede acceder de forma similar al objeto real en JavaScript.
Aquí hay un uso de muestra del siguiente método:
var obj = ParseJsonToDictionary("{FirstName: /"Chris/", /"Address/":{Street:/"My Street/",Number:123}}");
// Access the Address.Number value
object streetNumber = ((Dictionary<string, object>)obj["Address"])["Number"];
Y, aquí está el código para el método ParseJsonToDictionary:
public static Dictionary<string, object> ParseJsonToDictionary(string json)
{
var d = new Dictionary<string, object>();
if (json.StartsWith("{"))
{
json = json.Remove(0, 1);
if (json.EndsWith("}"))
json = json.Substring(0, json.Length - 1);
}
json.Trim();
// Parse out Object Properties from JSON
while (json.Length > 0)
{
var beginProp = json.Substring(0, json.IndexOf('':''));
json = json.Substring(beginProp.Length);
var indexOfComma = json.IndexOf('','');
string endProp;
if (indexOfComma > -1)
{
endProp = json.Substring(0, indexOfComma);
json = json.Substring(endProp.Length);
}
else
{
endProp = json;
json = string.Empty;
}
var curlyIndex = endProp.IndexOf(''{'');
if (curlyIndex > -1)
{
var curlyCount = 1;
while (endProp.Substring(curlyIndex + 1).IndexOf("{") > -1)
{
curlyCount++;
curlyIndex = endProp.Substring(curlyIndex + 1).IndexOf("{");
}
while (curlyCount > 0)
{
endProp += json.Substring(0, json.IndexOf(''}'') + 1);
json = json.Remove(0, json.IndexOf(''}'') + 1);
curlyCount--;
}
}
json = json.Trim();
if (json.StartsWith(","))
json = json.Remove(0, 1);
json.Trim();
// Individual Property (Name/Value Pair) Is Isolated
var s = (beginProp + endProp).Trim();
// Now parse the name/value pair out and put into Dictionary
var name = s.Substring(0, s.IndexOf(":")).Trim();
var value = s.Substring(name.Length + 1).Trim();
if (name.StartsWith("/"") && name.EndsWith("/""))
{
name = name.Substring(1, name.Length - 2);
}
double valueNumberCheck;
if (value.StartsWith("/"") && value.StartsWith("/""))
{
// String Value
d.Add(name, value.Substring(1, value.Length - 2));
}
else if (value.StartsWith("{") && value.EndsWith("}"))
{
// JSON Value
d.Add(name, ParseJsonToDictionary(value));
}
else if (double.TryParse(value, out valueNumberCheck))
{
// Numeric Value
d.Add(name, valueNumberCheck);
}
else
d.Add(name, value);
}
return d;
}
Sé que este método puede ser un poco difícil, y probablemente podría optimizarse bastante, pero es el primer borrador y simplemente funciona.
Además, antes de quejarse de que no utiliza expresiones regulares, tenga en cuenta que no todo el mundo realmente entiende las expresiones regulares, y escribirlo de esa manera haría que sea más difícil para otros corregirlo si es necesario. Además, actualmente no sé demasiado bien la expresión regular, y el análisis de cadenas fue simplemente más fácil.
Hay lenguajes para .NET que tienen pato-tipado pero no es posible con C # usando Dot.Notation ya que C # requiere que todas las referencias de miembros se resuelvan en tiempo de compilación. Si desea utilizar la Dot.Notation, aún debe definir una clase en alguna parte con las propiedades requeridas, y usar el método que desee para crear una instancia de la clase a partir de los datos JSON. La predefinición de una clase tiene beneficios como tipeo fuerte, soporte de IDE, incluido intellisense, y no preocuparse por errores ortográficos. Aún puede usar tipos anónimos:
T deserialize<T>(string jsonStr, T obj) { /* ... */}
var jsonString = "{FirstName=''Chris'', LastName=''Johnson, Other=''unused''}";
var person = deserialize(jsonString, new {FirstName="",LastName=""});
var x = person.FirstName; //strongly-typed
No puede devolver un tipo anónimo desde un método **, por lo que la existencia de un tipo anónimo "rehidratado" se limitaría al método en el que se rehidrata. Algo sin sentido.
** Puedes devolverlo como un objeto (que requiere reflexión para acceder a sus propiedades - yeech) o puedes "lanzarlo con el ejemplo", lo cual tampoco tiene sentido, ya que requiere pasos adicionales y significa que ya sabes qué El tipo de objeto debería ser similar, entonces ¿por qué no simplemente crear un objeto y llenarlo en primer lugar?
También hay una biblioteca de análisis C # JSON aquí: