DataContractSerializer — Проблемы

У меня, должно быть, ОЧЕНЬ ГЛУПАЯ проблема с сериализатором контрактов данных. Он отказывается работать. Я просто пытаюсь сериализовать объект в XmlDocument, однако, похоже, я натыкаюсь на стену.

Вот контракты данных, которые я хочу сериализовать:

[DataContract(Namespace="urn://test", Name = "ServiceFault1")]
public class ServiceFault
{
    [DataMember()]
    public int hello { get; set; }

    [DataMember()]
    public List<Error> Errors {get; set;}
}

[DataContract(Namespace = "urn://test", Name = "Error1")]
public class Error
{
    [DataMember()]
    public string ErrorCategoryCode { get; set; }

    [DataMember()]
    public string LocalErrorCode { get; set; }

    [DataMember()]
    public string Description { get; set; }
}

И метод, который выполняет сериализацию;

    public static XmlDocument Serialize(ServiceFault toSer)
    {
        DataContractSerializer ser = new DataContractSerializer(toSer.GetType());

        MemoryStream mem = new MemoryStream();
        ser.WriteObject(XmlWriter.Create(mem), toSer);

        XmlDocument tmp = new XmlDocument();
        mem.Seek(0, SeekOrigin.Begin);
        tmp.Load(mem);

        return tmp;
    }

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

Если я использую XmlSerializer, это работает, однако я хотел бы понять, почему приведенный выше код не работает? Почему сериализатор всегда пуст?

Спасибо за любую помощь! ТМ


person themistry    schedule 04.10.2010    source источник
comment
При вызове .WriteObject просто передайте поток (например, mem) — не создавайте XmlWriter: ser.WriteObject(mem, toSer);   -  person marc_s    schedule 04.10.2010
comment
@marc_s, что бы это изменило? WriteObject все равно создаст XwlWriter внутри потока...   -  person Thomas Levesque    schedule 04.10.2010
comment
@Thomas Levesque: в моем случае, с XmlWriter, это не сработало, без - работает безупречно... поди разберись...   -  person marc_s    schedule 05.10.2010
comment
Марк, именно в этом и была проблема! Argh, я получил этот образец от Microsoft! :D Ну, я ожидал, что это будет что-то глупое. СПАСИБО!   -  person themistry    schedule 05.10.2010


Ответы (2)


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

DataContractSerializer serializer = new DataContractSerializer(toSers.GetType());
MemoryStream ms = new MemoryStream();
serializer.WriteObject(ms, toSer);
ms.Position = 0;

string serializedContent;
using(StreamReader sr = new StreamReader(ms))
{
  serializedContent = sr.ReadToEnd();   
}

Различия, которые я вижу, заключаются в том, что я пишу непосредственно в MemoryStream и устанавливаю Position в 0, а не вызываю Seek().

Вы можете загрузить результирующую строку в XmlDocument, если хотите, используя XmlDocument.LoadXml для экземпляра.

person benr    schedule 04.10.2010

Проблема заключается в следующей строке, потому что XmlWriter еще не сбросил свое содержимое в поток памяти:

ser.WriteObject(XmlWriter.Create(mem), toSer);

Вместо этого попробуйте использовать:

public static XmlDocument Serialize(ServiceFault toSer)
{
    DataContractSerializer ser = new DataContractSerializer(toSer.GetType());
    XmlDocument tmp = new XmlDocument();
    using (MemoryStream mem = new MemoryStream())
    {
        using (var memWriter = XmlWriter.Create(mem))
        {
            ser.WriteObject(memWriter, toSer);
        }

        mem.Seek(0, SeekOrigin.Begin);
        tmp.Load(mem);
    }
    return tmp;
}
person Reddog    schedule 04.10.2010