Як проаналізувати JSON без бібліотеки JSON.NET?


77

Я намагаюся створити додаток Metro для Windows 8 на Visual Studio 2011. і поки я намагаюся це зробити, у мене виникають деякі проблеми щодо синтаксичного аналізу JSONбез JSON.NETбібліотеки (це ще не підтримує програми метро) .

У будь-якому випадку, я хочу проаналізувати це:

{
   "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"
}

1
Ви можете зробити це за допомогою маніпулювання рядками, як це робили ті з нас раніше JSON.NETта інших бібліотек.
M.Babcock 05.03.12

Використовуйте JavascriptSerializer. Погляньте на цю відповідь: stackoverflow.com/questions/8405458/…
французька

3
Ви не повинні про це запитувати, MS не виявляє більше любові до нічого подібного до Json. Там же Jsonв System.Web.Helpers, є JsonQueryStringConverterв System.ServiceModel.Web, є JavascriptSerializerв System.Web.Script.Serialization, DataContractJsonSerializerв System.Runtime.Serialization.Json... Не зовсім заплутаною.
nawfal

3
Heck MS навіть вирішив включити третю сторону Json.NETдо свого веб-API ASP.NET. Якщо ви думали, що цього недостатньо, MS придумує, System.Jsonале в даний час непридатна для споживання. І для Windows 8 являє собою особливий випадок для MS, так є і JsonValueв Windows.Data.Jsonякому тільки для Windows 8 і вище.
nawfal

1
Станом на кінець 2016 року: Схоже, що Microsoft прийняла Json.NET і, можливо, відмовилася від ніколи офіційно не випущеного System.Json: msdn.microsoft.com/en-us/library/… говорить про "попередній перегляд", і пакет Nuget є обом (досі ) з позначкою "Бета" та не входить до списку , що передбачає припинення. (Є випущений System.Json, але лише Silverlight).
mklement0

Відповіді:


96

Ви можете використовувати класи, знайдені у просторі імен System.Json , додані в .NET 4.5. Вам потрібно додати посилання на збірку System.Runtime.Serialization

Метод JsonValue.Parse () аналізує текст JSON і повертає JsonValue :

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

Якщо ви передасте рядок з об'єктом JSON, ви зможете передати значення в 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"]);

Класи досить схожі на ті, що знайдені у просторі імен System.Xml.Linq .


19
Вам потрібно додати посилання на збірку System.Runtime.Serialization.
dtb

8
Використовуйте Nuget для встановлення system.json: Install-Package System.Json
GordonB

3
Якщо пакет не вдається знайти, обов’язково додайте номер версії. Приклад: PM> Install-Package System.Json -Version 4.0.20126.16343. Знайдіть поточну версію тут: nuget.org/packages/System.Json
Adam K Dean

5
System.Json все ще знаходиться в бета-версії, і тому пакет Nuget, здається, є способом отримати його. Він не вбудований в останню повну версію Framework V 4.5.1. Особисто мені подобається API Json.Net, який є набагато менш багатослівним і швидшим, ніж Windows.Data.Json або System.Json. Дивіться james.newtonking.com/json/help/html/…
Shital Shah

3
не можу знайти system.json
Kuldeep

38

Я використовую це ... але ніколи не розробляв жодної програми для метро, ​​тому я не знаю жодних обмежень щодо доступних для вас бібліотек. (зверніть увагу, вам потрібно буде позначити свої класи як з атрибутами DataContract та 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;
        }
    }
}

Отже, якби у вас був такий клас ...

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

}

Тоді ти використовував би його так ...

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

як я ним користуюся? він продовжує запитувати мене про TType, що це?
Елі Рева

Якби ваш тип (клас) називався MyType, ви б використовували його так: JSONSerializer <MyType> .Serialize () та JSONSerializer <MyType> .Deserialize (myInstanceOfMyType)
ctorx

2
Схоже, dtb має новіший рідний спосіб (на який відповіли вище), якщо ви використовуєте v4.5 Framework.
ctorx

Ви повинні використовувати Encoding.UTF8.GetString (stream.ToArray ()); якщо ви хочете підтримувати Unicode.
mrexodia

Як ви поводитесь, якщо у вашому користувацькому об’єкті є об’єкт, який не має атрибута DataContract та DataMember?
ЛЕМУЕЛ АДАНЕ

7

Для тих, хто не має 4.5, ось моя функція бібліотеки, яка читає json. Це вимагає посилання на проект System.Web.Extensions.

using System.Web.Script.Serialization;

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

Зазвичай json виписується на підставі контракту. Цей контракт може і зазвичай буде кодифікований у класі ( T). Іноді ви можете взяти слово з json і здійснити пошук у браузері об’єктів, щоб знайти цей тип.

Приклад використання:

Враховуючи json

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

Ви можете проаналізувати його на такий RadComboBoxClientStateоб’єкт:

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

6

Ви пробували використовувати JavaScriptSerializer? Є такожDataContractJsonSerializer


Ні, ти можеш пояснити мені, що це?
дякуй


Re JavaScriptSerializer: На момент написання статті його сторінка MSDN рекомендує замість цього використовувати Json.NET .
mklement0

1

Можна використовувати DataContractJsonSerializer. Детальніше див. Це посилання .


Я спробував, що за допомогою цього коду {DataContractJsonSerializer ser = new DataContractJsonSerializer (typeof (Song)); Елемент пісні = (Пісня) ser.ReadObject (новий MemoryStream (Encoding.UTF8.GetBytes (пісня))); Debug.WriteLine (item.name); } і це видає мені помилку
Eli Revah

Помилка типу "Test1.Song" не може бути серіалізованою. Подумайте про те, щоб позначити його атрибутом DataContractAttribute та позначити всіх його членів, яких ви хочете серіалізувати, атрибутом DataMemberAttribute. Якщо тип - це колекція, подумайте про позначення його за допомогою CollectionDataContractAttribute. Інші типи підтримуваних типів див. У документації Microsoft .NET Framework.
Елі Рева

1
@EliRevah - Вам потрібно визначити контракт даних для десериалізації за допомогою атрибута [DataContract] для класу та додати атрибут [DataMember] для кожного члена.
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.");
                }
        }
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.