Partial interception of default XML serialization C#

  Kiến thức lập trình

I am trying to create an XML object serialization base class to accumulate a bunch of stuff that I’ve learned over the past few years, to have a ready to use example whenever I need it.

I want to add Xml comment functionality, and have found some stackoverflow post that helps me in that. With a bit of cleanup, here is what my code looks like:

// XmlComment attribute class
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public class XmlCommentAttribute(string value) : Attribute
{
    public string Value { get; set; } = value;
}

// Usage in code
[XmlComment("This is an example comment that describes the name.")]
[XmlComment("Second comment line")]
public string Name { get; set; }

// Added code to satisfy IXmlSerializable
public void WriteXml(XmlWriter writer)
{
    var properties = GetType().GetProperties();

    foreach (var propertyInfo in properties)
    {
        if (HasCommentAttribute(propertyInfo))
            HandleCommentAttribute(writer, propertyInfo);
 
        writer.WriteElementString(propertyInfo.Name, propertyInfo.GetValue(this).ToString());
    }
}

private static bool HasCommentAttribute(PropertyInfo propertyInfo) 
    => propertyInfo.IsDefined(typeof(XmlCommentAttribute), false);

private static void HandleCommentAttribute(XmlWriter writer, PropertyInfo propertyInfo)
{
    var comments = propertyInfo.GetCustomAttributes(typeof(XmlCommentAttribute), false);

    foreach (var comment in comments)
        if (comment is XmlCommentAttribute line)
            writer.WriteComment($" {line.Value} ");
}

Serialization result:

<!-- This is an example comment that describes the name. -->
<!-- Second comment line -->
<Name>John</Name>

Huray!, although, not quite. When I use the given WriteXml function, I run into issues where object do not serialize properly.

[XmlComment("This is an example comment that describes the name.")]
[XmlComment("Second comment line")]
public string Name { get; set; }

// Added class definition and property below
public class AttributeExample
{
    [XmlAttribute]
    public int Attrib1 { get; set; } = ushort.MaxValue;

    [XmlAttribute]
    public int Attrib2 { get; set; } = byte.MaxValue;

    [XmlAttribute]
    public int Attrib3 { get; set; } = short.MaxValue;
}

public AttributeExample ExampleOfAttributedObject { get; set; }

This serializes to:

<!-- This is an example comment that describes the name. -->
<!-- Second comment line -->
<Name>John</Name>
<ExampleOfAttributedObject>ConfigurationPersistence.ExampleConfigObject2+AttributeExample</ExampleOfAttributedObject>

Which is not quite correct.

The problem lies in the fact that the WriteXml function parses my object to a string with the writer.WriteElementString(propertyInfo.Name, propertyInfo.GetValue(this).ToString()) function call.

How do I get this object, and any of its child objects to serialize properly, like the standard implementation of WriteXml? How does the XmlSerializer do this? You have to iterate over all properties, and that property’s properties, and serialize every object’s value.

Theme wordpress giá rẻ Theme wordpress giá rẻ Thiết kế website

LEAVE A COMMENT