Як проаналізувати 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.