¿Cómo analizar JSON sin la biblioteca JSON.NET?

77

Estoy tratando de crear una aplicación Metro para Windows 8 en Visual Studio 2011 y, mientras intento hacerlo, tengo algunos problemas sobre cómo analizar JSONsin JSON.NETbiblioteca (todavía no es compatible con las aplicaciones metro) .

De todos modos, quiero analizar esto:

{
   "name":"Prince Charming",
   "artist":"Metallica",
   "genre":"Rock and Metal",
   "album":"Reload",
   "album_image":"http:\/\/up203.siz.co.il\/up2\/u2zzzw4mjayz.png",
   "link":"http:\/\/f2h.co.il\/7779182246886"
}
Eli Revah
fuente
1
Puede hacerlo con la manipulación de cadenas como lo hicimos antes JSON.NETy surgieron otras bibliotecas.
M.Babcock
Utilice JavascriptSerializer. Eche un vistazo a esta respuesta: stackoverflow.com/questions/8405458/…
frenchie
3
No deberías estar preguntando esto, MS no ha mostrado más amor por nada como Json. Hay Jsonadentro System.Web.Helpers, hay JsonQueryStringConverteradentro System.ServiceModel.Web, hay JavascriptSerializeradentro System.Web.Script.Serialization, DataContractJsonSerializeradentro System.Runtime.Serialization.Json... No es nada confuso.
Nawfal
3
Heck MS incluso ha decidido incluir a terceros Json.NETen su API web ASP.NET. Si pensaba que eso no era suficiente, la EM está apareciendo, System.Jsonpero actualmente no es apta para el consumo. Y Windows 8 es un caso especial para MS, por lo que también hay JsonValueen el Windows.Data.Jsonque es solo para Windows 8 y superior.
Nawfal
1
A finales de 2016: Parece que Microsoft adoptó Json.NET y posiblemente abandonó el nunca lanzado oficialmente System.Json: msdn.microsoft.com/en-us/library/ ... habla sobre "vista previa" y el paquete Nuget es ambos (todavía ) etiquetado como "Beta" y no se ha incluido en la lista , lo que sugiere que está obsoleto. (Hay un lanzamiento System.Json, pero es solo Silverlight).
mklement0

Respuestas:

96

Puede usar las clases que se encuentran en el espacio de nombres System.Json que se agregaron en .NET 4.5. Necesita agregar una referencia al ensamblado System.Runtime.Serialization

El método JsonValue.Parse () analiza el texto JSON y devuelve un JsonValue :

JsonValue value = JsonValue.Parse(@"{ ""name"":""Prince Charming"", ...");

Si pasa una cadena con un objeto JSON, debería poder convertir el valor a un JsonObject :

using System.Json;


JsonObject result = value as JsonObject;

Console.WriteLine("Name .... {0}", (string)result["name"]);
Console.WriteLine("Artist .. {0}", (string)result["artist"]);
Console.WriteLine("Genre ... {0}", (string)result["genre"]);
Console.WriteLine("Album ... {0}", (string)result["album"]);

Las clases son bastante similares a las que se encuentran en el espacio de nombres System.Xml.Linq .

dtb
fuente
19
Debe agregar una referencia al ensamblado System.Runtime.Serialization.
dtb
8
Utilice Nuget para instalar system.json: Install-Package System.Json
GordonB
3
Si no se puede encontrar el paquete, asegúrese de agregar el número de versión. Ejemplo: PM> Install-Package System.Json -Version 4.0.20126.16343. Encuentre la versión actual aquí: nuget.org/packages/System.Json
Adam K Dean
5
System.Json todavía está en versión beta, por lo que el paquete Nuget parece ser la forma de obtenerlo. No está integrado en el Framework V 4.5.1 completo más reciente. Personalmente, me gusta la API de Json.Net, que es mucho menos detallada y más rápida que Windows.Data.Json o System.Json. Ver james.newtonking.com/json/help/html/…
Shital Shah
3
No puedo encontrar system.json
kuldeep
38

Yo uso esto ... pero nunca he desarrollado ninguna aplicación metropolitana, así que no conozco ninguna restricción en las bibliotecas disponibles para ti. (tenga en cuenta que deberá marcar sus clases como con los atributos DataContract y DataMember)

public static class JSONSerializer<TType> where TType : class
{
    /// <summary>
    /// Serializes an object to JSON
    /// </summary>
    public static string Serialize(TType instance)
    {
        var serializer = new DataContractJsonSerializer(typeof(TType));
        using (var stream = new MemoryStream())
        {
            serializer.WriteObject(stream, instance);
            return Encoding.Default.GetString(stream.ToArray());
        }
    }

    /// <summary>
    /// DeSerializes an object from JSON
    /// </summary>
    public static TType DeSerialize(string json)
    {
        using (var stream = new MemoryStream(Encoding.Default.GetBytes(json)))
        {
            var serializer = new DataContractJsonSerializer(typeof(TType));
            return serializer.ReadObject(stream) as TType;
        }
    }
}

Entonces, si tuvieras una clase como esta ...

[DataContract]
public class MusicInfo
{
    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public string Artist { get; set; }

    [DataMember]
    public string Genre { get; set; }

    [DataMember]
    public string Album { get; set; }

    [DataMember]
    public string AlbumImage { get; set; }

    [DataMember]
    public string Link { get; set; }

}

Entonces lo usarías así ...

var musicInfo = new MusicInfo
{
     Name = "Prince Charming",
     Artist = "Metallica",
     Genre = "Rock and Metal",
     Album = "Reload",
     AlbumImage = "http://up203.siz.co.il/up2/u2zzzw4mjayz.png",
     Link = "http://f2h.co.il/7779182246886"
};

// This will produce a JSON String
var serialized = JSONSerializer<MusicInfo>.Serialize(musicInfo);

// This will produce a copy of the instance you created earlier
var deserialized = JSONSerializer<MusicInfo>.DeSerialize(serialized);
ctorx
fuente
¿como lo uso? me sigue preguntando por TType, ¿qué es eso?
Eli Revah
Si su tipo (clase) se llamara MyType, lo usaría así: JSONSerializer <MyType> .Serialize () y JSONSerializer <MyType> .Deserialize (myInstanceOfMyType)
ctorx
2
Parece que dtb tiene una forma nativa más nueva (respondida anteriormente) si está utilizando v4.5 del Framework.
ctorx
Tienes que usar Encoding.UTF8.GetString (stream.ToArray ()); si desea admitir unicode.
mrexodia
¿Cómo maneja, si tiene un objeto dentro de su objeto personalizado que no tiene un atributo DataContract y DataMember?
LEMUEL ADANE
7

Para aquellos que no tienen 4.5, aquí está mi función de biblioteca que dice json. Requiere una referencia de proyecto a System.Web.Extensions.

using System.Web.Script.Serialization;

public object DeserializeJson<T>(string Json)
{
    JavaScriptSerializer JavaScriptSerializer = new JavaScriptSerializer();
    return JavaScriptSerializer.Deserialize<T>(Json);
}

Por lo general, json se escribe en base a un contrato. Ese contrato puede y generalmente se codificará en una clase (T ). A veces, puede tomar una palabra del json y buscar en el navegador de objetos para encontrar ese tipo.

Uso de ejemplo:

Dado el json

{"logEntries":[],"value":"My Code","text":"My Text","enabled":true,"checkedIndices":[],"checkedItemsTextOverflows":false}

Podría analizarlo en un RadComboBoxClientStateobjeto como este:

string ClientStateJson = Page.Request.Form("ReportGrid1_cboReportType_ClientState");
RadComboBoxClientState RadComboBoxClientState = DeserializeJson<RadComboBoxClientState>(ClientStateJson);
return RadComboBoxClientState.Value;
Toddmo
fuente
1

Puede utilizar DataContractJsonSerializer. Consulte este enlace para obtener más detalles.

TheBoyan
fuente
Intenté eso con este código {DataContractJsonSerializer ser = new DataContractJsonSerializer (typeof (Song)); Elemento de la canción = (Song) ser.ReadObject (new MemoryStream (Encoding.UTF8.GetBytes (canción))); Debug.WriteLine (item.name); } y me da un error
Eli Revah
El error es El tipo 'Test1.Song' no se puede serializar. Considere marcarlo con el atributo DataContractAttribute y marcar todos sus miembros que desea serializar con el atributo DataMemberAttribute. Si el tipo es una colección, considere marcarlo con CollectionDataContractAttribute. Consulte la documentación de Microsoft .NET Framework para conocer otros tipos compatibles.
Eli Revah
1
@EliRevah: debe definir el contrato de datos para la deserialización con el atributo [DataContract] para la clase y agregar el atributo [DataMember] para cada miembro.
TheBoyan
0
using System;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Text;

namespace OTL
{
    /// <summary>
    /// Before usage: Define your class, sample:
    /// [DataContract]
    ///public class MusicInfo
    ///{
    ///   [DataMember(Name="music_name")]
    ///   public string Name { get; set; }
    ///   [DataMember]
    ///   public string Artist{get; set;}
    ///}
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class OTLJSON<T> where T : class
    {
        /// <summary>
        /// Serializes an object to JSON
        /// Usage: string serialized = OTLJSON&lt;MusicInfo&gt;.Serialize(musicInfo);
        /// </summary>
        /// <param name="instance"></param>
        /// <returns></returns>
        public static string Serialize(T instance)
        {
            var serializer = new DataContractJsonSerializer(typeof(T));
            using (var stream = new MemoryStream())
            {
                serializer.WriteObject(stream, instance);
                return Encoding.Default.GetString(stream.ToArray());
            }
        }

        /// <summary>
        /// DeSerializes an object from JSON
        /// Usage:  MusicInfo deserialized = OTLJSON&lt;MusicInfo&gt;.Deserialize(json);
        /// </summary>
        /// <param name="json"></param>
        /// <returns></returns>
        public static T Deserialize(string json)
        {
            if (string.IsNullOrEmpty(json))
                throw new Exception("Json can't empty");
            else
                try
                {
                    using (var stream = new MemoryStream(Encoding.Default.GetBytes(json)))
                    {

                        var serializer = new DataContractJsonSerializer(typeof(T));
                        return serializer.ReadObject(stream) as T;
                    }
                }
                catch (Exception e)
                {
                    throw new Exception("Json can't convert to Object because it isn't correct format.");
                }
        }
    }
}
O Thạnh Ldt
fuente