Встановіть корінь об'єкта JSON за допомогою DataContractJsonSerializer

При серіалізації об'єкта, використовуючи System.Runtime.Serialization.Json.DataContractJsonSerializer , чи є спосіб встановити ключ "root" або верхнього рівня в рядку 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 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()) + "}";

Але мені було цікаво, чи був якийсь спосіб сказати серіалізатору, щоб додати його? Властивість namespace на атрибуті DataContract не допомогло.

4
Насправді я працюю над клієнтом CouchDB .. при додаванні об'єкта (JSON) через API CouchDB він хоче об'єкт мати мітку. Я також перевірив JSON.NET. Дякую
додано Автор ZimSystem, джерело
Я також помічаю, що один з підписів методу Serialize просить вказати параметр "XmlDictionaryString rootName", але він, здається, не працює .. Гаразд на JSON.NET зараз
додано Автор ZimSystem, джерело
Використовуйте JSON.NET , це серйозно полегшить ваше життя багато при роботі з JSON; Я вважаю, що .NET-пропозиції не входять в комплект, щоб бути дуже, дуже не вистачає.
додано Автор casperOne, джерело
Чому ви хочете загорнути його у тип? Те, що ви пропонуєте, не схоже на хороший JSON для мене. Я б просто йшов на один крок далі і просто зробив масив. {Persons: [Person]}
додано Автор Jamie, джерело

1 Відповіді

Ви можете це зробити, але це не дуже гарне - вам потрібно знати деякі JSON до XML-картографування правил, які використовує DataContractJsonSerializer . Для простого випадку, коли ви просто хочете обернути об'єкт у назві типу, це досить просто - наведений нижче код робить це. Потрібно створити серіалізатор із потрібним іменем "root" (в даному випадку я використовував назву типу) і передав йому екземпляр 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 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")));
    }
}

Як було зазначено в одному з коментарів, робота з JSON і DataContractJsonSerializer не є чимось надто дружньою. Деякі бібліотеки JSON, такі як JSON.NET або типи JsonValue (пакет nuget JsonValue), можуть полегшити ваше життя.

1
додано
var chat = new Chat();
var chat = new Chat();
642 учасників

Обсуждение вопросов по C# / .NET / .NET Core / .NET Standard / Azure Сообщества-организаторы: — @itkpi — @dncuug

ІТ КПІ - JavaScript
ІТ КПІ - JavaScript
504 учасників

співтовариство javascript розробників в Telegram