2014-01-02 3 views
1

У меня есть класс, содержащий строку только для чтения. Таким образом, мне нужно вручную обрабатывать xmlserialization. Но кажется, что использование этого класса в более грандиозной настройке с автоматической сериализацией xml разрушает процесс десериализации.IXmlSerializable реализация разрушает xml-сериализацию

Первый мой чтения класс

public class RO : IXmlSerializable 
{ 
    public string Name { get; private set; } 

    // for serialization 
    protected RO(){} 
    public RO(string name) 
    { 
    this.Name = name; 
    } 

    public XmlSchema GetSchema() 
    { 
    return null; 
    } 

    public void ReadXml(XmlReader reader) 
    { 
    Name = reader.ReadString(); 
    } 

    public void WriteXml(XmlWriter writer) 
    { 
    writer.WriteString(Name); 
    } 
} 

затем класс обертка затаив только для чтения объекта и некоторое значение

public class Holder 
{ 
    public RO a; 
    public decimal b; 
} 

и теперь я сериализации и десериализации экземпляра держателя

class Program 
{ 
    static void Main(string[] args) 
    { 
    XmlSerializer xml = new XmlSerializer(typeof(Holder)); 
    var s = new StringWriter(); 
    var holder = new Holder() { a = new RO("foo"), b = 234 }; 
    xml.Serialize(s, holder); 
    string ss = s.ToString(); 
    Console.WriteLine("*****"); 
    Console.WriteLine(ss); 
    Console.WriteLine("*****"); 
    holder = (Holder) xml.Deserialize(new StringReader(ss)); 
    Console.WriteLine(holder.a.Name); 
    Console.WriteLine(holder.b); 
    } 
} 

на экране симпатичный xml

***** 
<?xml version="1.0" encoding="utf-16"?> 
<Holder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http:// 
www.w3.org/2001/XMLSchema"> 
    <a>foo</a> 
    <b>234</b> 
</Holder> 
***** 

но когда мы выводим значения и б мы получаем для нашей десятичной .. несмотря мы видим в XML

foo 
0 

ответ

2

Я подозреваю, что проблема заключается в том, что вы не читаете до конца содержащего элемента - я подозреваю, вы хотите:

public void ReadXml(XmlReader reader) 
{ 
    Name = reader.ReadElementContentAsString(); 
} 

В documentation for ReadXml состояния:

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

ReadString будет просто читать строку и останавливаться, когда она попадает в тег конца элемента; ReadElementContentAsString позиционирует читателя после тега концевого элемента.

Я только что попробовал приведенный выше код с вашим образцом, и он решает проблему там, по крайней мере.

+0

Хорошо, мой источник документации был http://msdn.microsoft.com/en-us/library/system.xml.serialization.ixmlserializable(v=vs.110).aspx –

+0

@ Карло: Да, это очень неудачно что пример сломан :( –

Смежные вопросы