Wie analysiere ich JSON ohne JSON.NET-Bibliothek?

76

Ich versuche, eine Metro-Anwendung für Windows 8 in Visual Studio 2011 zu erstellen. Während ich dies versuche, habe ich einige Probleme beim Parsen JSONohne JSON.NETBibliothek (die Metro-Anwendungen werden noch nicht unterstützt). .

Wie auch immer, ich möchte Folgendes analysieren:

{
   "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
quelle
1
Sie können dies mit String-Manipulationen tun, wie wir es zuvor getan haben JSON.NETund andere Bibliotheken entstanden sind.
M.Babcock
Verwenden Sie JavascriptSerializer. Schauen Sie sich diese Antwort an: stackoverflow.com/questions/8405458/…
frenchie
3
Sie sollten das nicht fragen, MS hat nicht mehr Liebe für so etwas gezeigt wie für Json. Es gibt Jsonin System.Web.Helpers, gibt es JsonQueryStringConverterin System.ServiceModel.Web, gibt es JavascriptSerializerin System.Web.Script.Serialization, DataContractJsonSerializerin System.Runtime.Serialization.Json... überhaupt nicht verwirrend.
Nawfal
3
Heck MS hat sogar beschlossen, Dritte Json.NETin seine ASP.NET-Web-API aufzunehmen. Wenn Sie dachten, dass das nicht genug ist, kommt MS auf die Idee, ist System.Jsonaber derzeit nicht für den Konsum geeignet. Und Windows 8 ist ein spezieller Fall für MS, so gibt es auch JsonValuein Windows.Data.Jsondem nur für Windows 8 und höher.
Nawfal
1
Stand Ende 2016: Es scheint, dass Microsoft Json.NET angenommen und möglicherweise die nie offiziell veröffentlichte Version aufgegeben hat System.Json: msdn.microsoft.com/en-us/library/… spricht über "Vorschau" und das Nuget-Paket ist beides (immer noch) ) mit "Beta" gekennzeichnet und nicht gelistet , was auf eine Ablehnung hindeutet. (Es gibt eine veröffentlichte System.Json, aber es ist nur Silverlight).
mklement0

Antworten:

96

Sie können die im System.Json-Namespace enthaltenen Klassen verwenden, die in .NET 4.5 hinzugefügt wurden. Sie müssen einen Verweis auf die Assembly System.Runtime.Serialization hinzufügen

Die JsonValue.Parse () -Methode analysiert JSON-Text und gibt einen JsonValue zurück :

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

Wenn Sie eine Zeichenfolge mit einem JSON-Objekt übergeben, sollten Sie den Wert in ein JsonObject umwandeln können :

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"]);

Die Klassen sind denen im System.Xml.Linq-Namespace ziemlich ähnlich .

dtb
quelle
19
Sie müssen einen Verweis auf die Assembly System.Runtime.Serialization hinzufügen.
dtb
8
Verwenden Sie Nuget, um system.json zu installieren: Install-Package System.Json
GordonB
3
Wenn das Paket nicht gefunden werden kann, stellen Sie sicher, dass Sie die Versionsnummer hinzufügen. Beispiel : PM> Install-Package System.Json -Version 4.0.20126.16343. Die aktuelle Version finden Sie hier: nuget.org/packages/System.Json
Adam K Dean
5
System.Json befindet sich noch in der Beta-Phase und daher scheint das Nuget-Paket der richtige Weg zu sein, um es zu bekommen. Es ist nicht in das neueste vollständige Framework V 4.5.1 integriert. Persönlich mag ich die API von Json.Net, die viel weniger ausführlich und schneller ist als Windows.Data.Json oder System.Json. Siehe james.newtonking.com/json/help/html/…
Shital Shah
3
kann system.json nicht finden
kuldeep
37

Ich benutze dies ... habe aber noch nie eine Metro-App-Entwicklung durchgeführt, daher kenne ich keine Einschränkungen für Bibliotheken, die Ihnen zur Verfügung stehen. (Beachten Sie, dass Sie Ihre Klassen wie mit den Attributen DataContract und DataMember markieren müssen.)

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;
        }
    }
}

Also, wenn Sie eine Klasse wie diese hatten ...

[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; }

}

Dann würden Sie es so verwenden ...

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
quelle
Wie benutze ich es? es fragt mich immer wieder nach TType, was ist das?
Eli Revah
Wenn Ihr Typ (Klasse) MyType heißt, würden Sie ihn folgendermaßen verwenden: JSONSerializer <MyType> .Serialize () und JSONSerializer <MyType> .Deserialize (myInstanceOfMyType)
ctorx
2
Es sieht so aus, als ob dtb eine neuere native Methode hat (oben beantwortet), wenn Sie v4.5 des Frameworks verwenden.
Ctorx
Sie müssen Encoding.UTF8.GetString (stream.ToArray ()) verwenden. wenn Sie Unicode unterstützen möchten.
Mrexodia
Wie gehen Sie vor, wenn sich in Ihrem benutzerdefinierten Objekt ein Objekt befindet, das kein DataContract- und DataMember-Attribut enthält?
LEMUEL ADANE
7

Für diejenigen, die nicht 4.5 haben, ist hier meine Bibliotheksfunktion, die json liest. Es erfordert einen Projektverweis auf System.Web.Extensions.

using System.Web.Script.Serialization;

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

Normalerweise wird json aufgrund eines Vertrags ausgeschrieben. Dieser Vertrag kann und wird normalerweise in einer Klasse ( T) kodifiziert . Manchmal können Sie ein Wort aus dem json nehmen und den Objektbrowser durchsuchen, um diesen Typ zu finden.

Anwendungsbeispiel:

Angesichts des json

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

Sie können es in ein RadComboBoxClientStateObjekt wie das folgende analysieren :

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

Sie können verwenden DataContractJsonSerializer. Siehe diesen Link für weitere Details.

TheBoyan
quelle
Ich habe das mit diesem Code versucht {DataContractJsonSerializer ser = new DataContractJsonSerializer (typeof (Song)); Song item = (Song) ser.ReadObject (neuer MemoryStream (Encoding.UTF8.GetBytes (song))); Debug.WriteLine (item.name); } und es gibt mir einen Fehler
Eli Revah
Der Fehler ist Typ 'Test1.Song' kann nicht serialisiert werden. Markieren Sie es mit dem DataContractAttribute-Attribut und markieren Sie alle Mitglieder, die Sie serialisieren möchten, mit dem DataMemberAttribute-Attribut. Wenn es sich bei dem Typ um eine Sammlung handelt, sollten Sie ihn mit dem CollectionDataContractAttribute markieren. Weitere unterstützte Typen finden Sie in der Microsoft .NET Framework-Dokumentation.
Eli Revah
1
@EliRevah - Sie müssen den Datenvertrag für die Deserialisierung mit dem Attribut [DataContract] für die Klasse definieren und für jedes Mitglied das Attribut [DataMember] hinzufügen.
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
quelle