Guapo
Guapo

Reputation: 3482

Serialize without attribute or deserialize with attribute override?

I have a class like this:

public class Item
{
    [XmlAttribute("Name")]
    public string Name { get; set; }
    [XmlAttribute("Id")]
    public int Id { get; set; }
    [XmlAttribute("Entry")]
    public int Entry { get { return this.Id; } set { this.Id = value; } }
}

And I don't want to serialize the Entry attribute but still want to be able to deserialize it from files that have said attribute.

If I either set XmlIgnore it will not read during deserialization and if I don't it will write both Entry and Id to my serialized file which I don't want.

I know I could generate a secondary class with excludes Entry altogether and use that specific one for serializing, but I grew curious if there is a way to make so it will not serialize the Id or it will deserialize the Entry into the Id attribute instead?

I am open to other suggestions as well...

EDIT:

Also tried using XmlIgnoreAttribute as explained here:

http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlattributes.xmlignore%28v=vs.110%29.aspx

With true on my serialization and false on my deserialization, but didn't work.


Just to further clarify the issue, how the XML's are formatted is not something I control and what I am doing is merely a 3rd party application that will read those files and save them back. To me the Entry attribute is redundant and unneeded hence why I save it to the Id as they are the same, however there are many elements with no Id and instead they have the Entry, once my application is used to read and re-save the file it removes the Entry and saves it as Id instead.

Also to serialize and deserialize it I have to inject the root element name:

XmlSerializer serializer = new XmlSerializer(typeof(T), new XmlRootAttribute(root));
using (XmlReader reader = XmlReader.Create(file))
{
    return (T)serializer.Deserialize(reader);
}

Because the root name will differ from file to file I have to inject it.

Upvotes: 1

Views: 380

Answers (2)

Adrian Salazar
Adrian Salazar

Reputation: 5319

You need to steer away from non nullable types in order to do that...

Just consider the small change on the code:

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

    [XmlAttribute("Id")]
    public int Id { get; set; }

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

Now you can tell the serializer that you want to exclude certain field in the serialization process, by adding a member function to the class called ShouldSerializeXYZ() where XYZ is the name of the field you want to control.

In this case, the function needed would look like:

public bool ShouldSerializeEntry()
{
    // Here you complete control on when to include the field
    // As a simple example I excluded the field if its empty
    // But you can make more complex conditions 
    return !String.IsNullOrEmpty(Entry);
}

You can have one method per each property, so in theory you could also add a ShouldSerialize for Name, and Id but on my experience, this technique will not work with non nullable types.

Upvotes: 1

Lucas Damiani
Lucas Damiani

Reputation: 77

I suggest that you implement your own custom XML serialize/deserialize logic. You can get more information about how to do that on this link.

http://www.codeproject.com/Articles/474453/How-to-customize-XML-serialization

Upvotes: 1

Related Questions