当前位置:  开发笔记 > 编程语言 > 正文

如何将JSON字符串反序列化为C#对象?

如何解决《如何将JSON字符串反序列化为C#对象?》经验,为你挑选了1个好方法。

考虑以下内容:您有一个返回JSON字符串的服务,并且在您的C#代码中,您希望将返回值用作对象(例如:通过其名称获取其各种属性)。

样本JSON:

{ 
    "Name": "Jon Smith", 
    "Address": 
    { 
        "City": "New York",
        "State": "NY" 
    },
    "Age": 42 
}

示例C#用法:

var object = ... // this is what I am asking for
Console.WriteLine(object.Name); // this should print out "Jon Smith"
Console.WriteLine(object.Address.State); // this should print out "NY"

使用第三方库的情况下,C#提供哪些选项?



1> qqbenq..:

如果您不知道确切的数据协定(或您不关心它),则可以借助System.Web.Helpers.Json类和dynamic对象轻松地做到这一点:

dynamic json = System.Web.Helpers.Json.Decode(@"{ ""Name"": ""Jon Smith"", ""Address"": { ""City"": ""New York"", ""State"": ""NY"" }, ""Age"": 42 }");
Console.WriteLine(json.Name);           // prints "Jon Smith"
Console.WriteLine(json.Address.State);  // prints "NY"

关于这一点的注释:您将不得不添加对System.Web.Helpers程序集的引用。

当然,并不是每个人都喜欢dynamic,有些人更喜欢拥有定义明确的数据合同。对于他们来说,解决方案要长一些:

您必须为数据合同创建匹配的类,并相应地赋予它们属性:

// class for the root object:
[DataContract]
public class Person
{
    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public Address Address { get; set; }

    [DataMember]
    public int Age { get; set; }
}

// class for the address object:
[DataContract]
public class Address
{
    [DataMember]
    public string City { get; set; }

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

您可以将成员标记为具有IgnoreDataMember属性,以便忽略它们,或添加IsRequired=true使其成为必需属性。

定义了这些合同之后,您可以轻松地将JSON字符串解析为一个Person对象:

DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Person));
using( MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(@"{ ""Name"": ""Jon Smith"", ""Address"": { ""City"": ""New York"", ""State"": ""NY"" }, ""Age"": 42 }")))
{
    var person = (Person)ser.ReadObject(stream);
    Console.WriteLine(person.Name);             // prints "Jon Smith"
    Console.WriteLine(person.Address.State);    // prints "NY"
}

注意:DataContractJsonSerializer驻留在System.ServiceModel.Web程序集中,因此您必须为此添加引用。(当然还有System.Runtime.Serialization组装。)

为了使它更易于使用,可以在数据协定类中添加static ParseTryParse方法:

public static Person Parse(string jsonString)
{
    if (String.IsNullOrWhiteSpace(jsonString)) throw new ArgumentNullException("The jsonString parameter shouldn't be null or an empty string.");

    DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Person));
    using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)))
    {
        return (Person)ser.ReadObject(stream);
    }
}

public static bool TryParse(string jsonString, out Person result)
{
    try
    {
        result = Person.Parse(jsonString);
        return true;
    }
    catch (Exception ex)
    {
        if (ex is ArgumentNullException || ex is SerializationException)
        {
            result = null;
            return false;
        }
        throw;
    }
}

就像LB在他们的评论中提到的那样,JavaScriptSerializer如果添加了对System.Web.Extensions程序集的引用,则可以使用它来简化操作:

var person = new JavaScriptSerializer().Deserialize(@"{ ""Name"": ""Jon Smith"", ""Address"": { ""City"": ""New York"", ""State"": ""NY"" }, ""Age"": 42 }");

为此,您仍然需要上面的类,但是如果愿意,可以省略-“ ugly”-属性。(但是使用这种方法,您将无法将零件标记为强制性...)

推荐阅读
赛亚兔备_393
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有