如何在没有JSON.NET库的情况下解析JSON?


76

我正在尝试在Visual Studio 2011上为Windows 8构建Metro应用程序。在尝试执行该操作时,我遇到了一些如何在JSON不使用JSON.NET库的情况下进行解析的问题(它尚不支持Metro应用程序) 。

无论如何,我想解析一下:

{
   "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 2012年

使用JavascriptSerializer。看看这个答案:stackoverflow.com/questions/8405458/...
frenchie

3
您不应该问这个,MS并没有像Json那样表现出更多的爱。有JsonSystem.Web.Helpers,有JsonQueryStringConverterSystem.ServiceModel.Web,有JavascriptSerializerSystem.Web.Script.SerializationDataContractJsonSerializerSystem.Runtime.Serialization.Json所有混乱......不是。
nawfal

3
Heck MS甚至决定Json.NET在其ASP.NET Web API中包括第三方。如果您认为这还不够,那就是MS正在提出,System.Json但目前不适合使用。和Windows 8是MS的一个特例,所以也有JsonValueWindows.Data.Json这仅适用于Windows 8及以上。
nawfal

1
截至2016年末:似乎微软已经接受Json.NET,并可能放弃了从未正式发布的版本System.Jsonmsdn.microsoft.com/en-us/library/…谈论“预览”,而Nuget包既( )标签为“测试版”,并且未列出,表明已弃用。(有发行版System.Json,但仅适用于Silverlight)。
mklement0 '16

Answers:


96

您可以使用.NET 4.5中添加的System.Json命名空间中找到的类。您需要添加对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 2012年

8
使用Nuget来安装system.json:安装软件包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中的。我个人喜欢Json.Net的API,它比Windows.Data.Json或System.Json的冗长得多,而且速度更快。参见james.newtonking.com/json/help/html/…–
Shital Shah

3
找不到system.json
kuldeep '18

37

我用这个...但是从未做过任何Metro应用开发,所以我不知道对您可用的库有任何限制。(请注意,您需要将类标记为具有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 2012年

2
如果您正在使用Framework v4.5,则dtb似乎具有较新的本机方式(上面已回答)。
ctorx 2012年

您必须使用Encoding.UTF8.GetString(stream.ToArray()); 如果您想支持unicode。
mrexodia

如果自定义对象中有一个没有DataContract和DataMember属性的对象,该如何处理?
LEMUEL ADANE

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;


1

您可以使用DataContractJsonSerializer。有关更多详细信息,请参见此链接


我尝试使用此代码{DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Song)); 歌曲项目=(Song)ser.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(song))); Debug.WriteLine(item.name); },这给了我一个错误
Eli Revah,2012年

错误是“ Test1.Song”类型无法序列化。考虑使用DataContractAttribute属性标记它,并使用DataMemberAttribute属性标记要序列化的所有成员。如果类型是集合,请考虑使用CollectionDataContractAttribute对其进行标记。有关其他受支持的类型,请参见Microsoft .NET Framework文档。
伊莱·瑞瓦

1
@EliRevah-您需要使用该类的[DataContract]属性定义反序列化的数据协定,并为每个成员添加[DataMember]属性。
TheBoyan'3

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.");
                }
        }
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.