Можете ли вы контролировать глубину десериализации DataContractSerializer? - PullRequest
2 голосов
/ 05 января 2009

У меня есть довольно большой объектный граф, который я сериализовал в файл через DataContractSerializer. Теперь я хочу представить список этих файлов пользователю на выбор. В этом списке я хочу показать некоторые подробности о файле, которые являются свойствами корневого объекта. Я не хочу загружать весь график в память, так как меня интересует только отображение свойств корневого узла.

Кто-нибудь знает способ управления «глубиной» десериализации, чтобы я мог просто извлечь корневой объект из файла и пропустить дочерние элементы? Я бы предпочел не рассматривать файл как необработанный XML, так как я не делаю никаких необработанных манипуляций с XML где-либо еще, и это будет еще одна ветвь кода, которую я должен синхронизировать.

Моя единственная идея сейчас состоит в том, чтобы создать совместимый «сводный» объект, содержащий только интересующие меня свойства и ни одного из дочерних элементов, и десериализовать файл в него. Это должно пропустить детей, поскольку они не имеют отношения к объекту резюме.

Есть ли лучший способ сделать это?

Обновление / уточнение : Атрибуты не тот ответ, который я ищу. Во-первых, они будут предотвращать попадание «лишних» свойств в файл при первой сериализации объекта.

Во-вторых, они более постоянны, чем то, что я пытаюсь сделать. В конце концов, я хочу десериализовать весь файл, но не сейчас. Я пытаюсь показать сводный список файлов, которые пользователь выберет для импорта. Во время импорта мне понадобятся все дети и внуки. Это просто избыточно на шаге 1. Это потенциально большие файлы, поэтому полная десериализация некоторых из них просто для того, чтобы я мог отобразить информацию их заголовков, не сработает.

Надеюсь, это устранит путаницу в исходном вопросе.

Ответы [ 3 ]

1 голос
/ 05 января 2009

Это в значительной степени так, как вы хотите это сделать. DataContractSerializer предназначен для обработки этой ситуации, когда вы должны иметь типы, которые концептуально одинаковы, но разные типы с точки зрения CLR, которые вы хотите сериализовать друг в друга.

Учитывая это, просто создайте объект с подобным подмножеством свойств, которые вы хотите сериализовать, и передайте этот тип в DataContractSerializer.

Убедитесь, что для типа «итоговый», который вы задаете свойства атрибута DataContract (а также любых атрибутов DataMember или атрибутов DataContract для предоставляемых вами дочерних элементов), в частности, свойства Name и Namespace, отражающие имя и пространство имен не сводный тип (поскольку они должны совпадать).

1 голос
/ 05 января 2009

Моя первая рекомендация будет заключаться в манипулировании XML, если вы просто хотите извлечь некоторые детали из корневого узла. Другая возможность, хотя я не знаю последствий для производительности, заключается в использовании возможностей управления версиями DataContractSerializer для этой проблемы. В вашем контракте на данные отметьте все поля, кроме тех, которые вам понадобятся в сводке, как необязательные. Затем скопируйте контракт данных как другой класс, оставив необязательные поля. Десериализовать в новый, меньший контракт данных.

class Program
{
    static void Main(string[] args)
    {
        Person a = new Person();
        Person b = new Person();
        a.Name = "Mike";
        b.Name = "Joe";
        b.Parent = a;

        DataContractSerializer dtc = new DataContractSerializer(typeof(Person));

        StringBuilder sb = new StringBuilder();
        using (XmlWriter xr = XmlWriter.Create(sb))
        {
            dtc.WriteObject(xr, b);
        }

        object n;

        DataContractSerializer dtc2 = new DataContractSerializer(typeof(TinyPerson));

        using (XmlReader xr = XmlReader.Create(new StringReader(sb.ToString())))
        {
            n = dtc2.ReadObject(xr);
        }

    }
}

[DataContract(Name="Person")]
public class Person
{
    [DataMember]
    public string Name;

    [DataMember(IsRequired=false)]
    public Person Parent; 
}


[DataContract(Name = "Person")]
public class TinyPerson
{
    [DataMember]
    public string Name;

}
0 голосов
/ 05 января 2009

вы можете контролировать вашу сериализацию с помощью атрибутов. читать дальше здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...