Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert xml attribute to custom object during deserialization in C# using XmlSerializer

I get

InvalidCastException: Value is not a convertible object: System.String to IdTag

while attempting to deserialize xml attribute.

Here's the sample xml:

<?xml version="1.0" encoding="windows-1250"?>
<ArrayOfItem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Item Name="Item Name" ParentId="SampleId" />
</ArrayOfItem>

Sample classes:

public class Item
{
   [XmlAttribute]
   public string Name { get; set; }

   [XmlAttribute]
   public IdTag ParentId { get; set; }
}

[Serializable]
public class IdTag
{
    public string id;
}

The exception is thrown from Convert.ToType() method (which is called from XmlSerializer). AFAIK there is no way to "implement" IConvertible interface for System.String to convert to IdTag. I know I can implement a proxy property i.e:

public class Item
{
    [XmlAttribute]
    public string Name {get; set;}

    [XmlAttribute("ParentId")]
    public string _ParentId { get; set; }

    [XmlIgnore]
    public IdTag ParentId 
    { 
        get { return new IdTag(_ParentId); } 
        set { _ParentId = value.id; }
    }
}

Is there any other way?

like image 586
Chris Rosinski Avatar asked Jun 25 '15 13:06

Chris Rosinski


People also ask

What is the correct way of using XML Deserialization?

As with the CreatePo method, you must first construct an XmlSerializer, passing the type of class to be deserialized to the constructor. Also, a FileStream is required to read the XML document. To deserialize the objects, call the Deserialize method with the FileStream as an argument.

How do you serialize and deserialize an object in C# using XML?

Just mark up what you want to serialize with [XmlElement(name)] (or XmlAttribute, XmlRoot, etc) and then use the XmlSerializer. If you need really custom formating, implement IXmlSerializable.

What is XML Deserialization?

Serialization is a process by which an object's state is transformed in some serial data format, such as XML or binary format. Deserialization, on the other hand, is used to convert the byte of data, such as XML or binary data, to object type.


1 Answers

You have to tell the XmlSerializer what string it needs to look for in your IdTag object. Presumably, there's a property of that object that you want serialized (not the whole object).

So, you could change this:

[XmlAttribute]
public IdTag ParentId { get; set; }

to this:

[XmlIgnore]
public IdTag ParentIdTag { get; set; }

[XmlAttribute]
public string ParentId 
{ 
    get { return ParentIdTag.id; } 
    set { ParentIdTag.id = value; } 
}

Note the difference between this and what you posted - when you deserialize this, your ParentIdTag proxy object should be properly initialized.

like image 125
Dan Field Avatar answered Sep 27 '22 16:09

Dan Field