【问题标题】:Set JSON object root using DataContractJsonSerializer使用 DataContractJsonSerializer 设置 JSON 对象根
【发布时间】:2011-10-28 14:32:18
【问题描述】:

当使用System.Runtime.Serialization.Json.DataContractJsonSerializer 序列化对象时,有没有办法在 JSON 字符串中设置“根”或顶级键?

例如,这是一个类:

[DataContract]
public class Person
{
    public Person() { }
    public Person(string firstname, string lastname)
    {
        this.FirstName = firstname;
        this.LastName = lastname;
    }

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

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

当它被序列化使用时...

public static string Serialize<T>(T obj)
{
    Json.DataContractJsonSerializer serializer = 
        new DataContractJsonSerializer(obj.GetType());
    MemoryStream ms = new MemoryStream();
    serializer.WriteObject(ms, obj);
    string retVal = Encoding.Default.GetString(ms.ToArray());
    ms.Dispose();
    return retVal;
}

生成的 JSON 字符串如下所示:

{"FirstName":"Jane","LastName":"McDoe"}

有没有办法让序列化程序添加一些值?

例如:

{Person: {"FirstName":"Jane","LastName":"McDoe"}}

当然,我可以简单地更改我的 Serialize 方法来包装返回的 JSON 字符串,例如:

string retVal = "{Person:" + Encoding.Default.GetString(ms.ToArray()) + "}";

但我想知道是否有某种方法可以告诉序列化程序添加它? DataContract 属性上的 namespace 属性似乎没有帮助。

【问题讨论】:

  • 使用JSON.NET,它会让你在使用JSON时大大更轻松;我发现开箱即用的 .NET 产品非常非常缺乏。
  • 为什么要把它包装在类型中?你提出的建议对我来说似乎不是好的 JSON。我会更进一步,只做一个数组。 {人员:[人员]}
  • 实际上我正在使用 CouchDB 客户端。当您通过 CouchDB API 添加对象 (JSON) 时,它希望该对象具有标签。我也会检查 JSON.NET。谢谢
  • 我还注意到其中一个 Serialize 方法签名要求提供“XmlDictionaryString rootName”参数,但它似乎不起作用.. 现在可以在 JSON.NET 上使用

标签: c# .net json serialization


【解决方案1】:

你可以这样做,但它不是太漂亮 - 你需要知道DataContractJsonSerializer 使用的一些JSON to XML mapping 规则。对于简单的情况,您只想将对象包装在类型名称中,这相当简单——下面的代码就是这样做的。您需要使用所需的“根”名称创建序列化程序(在本例中,我使用类型名称),并将已被赋予根元素的 XmlDictionaryWriter 实例传递给它。

public class StackOverflow_7930629
{
    [DataContract]
    public class Person
    {
        public Person() { }
        public Person(string firstname, string lastname)
        {
            this.FirstName = firstname;
            this.LastName = lastname;
        }

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

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

    public static string Serialize<T>(T obj)
    {
        DataContractJsonSerializer serializer =
            new DataContractJsonSerializer(typeof(T), typeof(T).Name);
        MemoryStream ms = new MemoryStream();
        XmlDictionaryWriter w = JsonReaderWriterFactory.CreateJsonWriter(ms);
        w.WriteStartElement("root");
        w.WriteAttributeString("type", "object");
        serializer.WriteObject(w, obj);
        w.WriteEndElement();
        w.Flush();
        string retVal = Encoding.Default.GetString(ms.ToArray());
        ms.Dispose();
        return retVal;
    }
    public static void Test()
    {
        Console.WriteLine(Serialize(new Person("Jane", "McDoe")));
    }
}

正如其中一个 cmets 所提到的,使用 JSON 和 DataContractJsonSerializer 并不是很友好。一些特定于 JSON 的库,例如 JSON.NET 或 JsonValue 类型(nuget 包 JsonValue)可以让您的生活更轻松。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多