Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
208 views
in Technique[技术] by (71.8m points)

c# - Overriding a property with an attribute

I'm trying to find a way to change the serialization behavior of a property.

Lets say I have a situation like this:

[Serializable]
public class Record
{
   public DateTime LastUpdated {get; set; }

   // other useful properties ...
}

public class EmployeeRecord : Record
{
   public string EmployeeName {get; set; }

   // other useful properties ...
}

Now I want to serialize EmployeeRecord. I don't want the LastUpdated property from the Record class to be serialized. (I do want LastUpdated to be serialized when I serialize Record, though).

First I tried hiding the LastUpdated property by using the new keyword and then adding the XmlIgnore attribute:

public class EmployeeRecord : Record
{
   public string EmployeeName {get; set; }

   [XmlIgnore]
   public new DateTime LastUpdated {get; set; }
   // other useful properties ...
}

But that didn't work. Then I tried making the base LastUpdated virtual and overriding it, keeping the attribute:

[Serializable]
public class Record
{
   public virtual DateTime LastUpdated {get; set; }

   // other useful properties ...
}

public class EmployeeRecord : Record
{
   public string EmployeeName {get; set; }

   [XmlIgnore]
   public override DateTime LastUpdated {get; set; }
   // other useful properties ...
}

This didn't work either. In both attempts the LastUpdated ignored the XmlIgnore attribute and happily went about its business of serializing.

Is there a way to make what I'm trying to do happen?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

First, the [Serializable] attr has nothing to do with the XmlSerializer. That is a red herring. [Serializable] is meaningful to System.Runtime.Serialization, while the XmlSerializer lives in System.Xml.Serialization. If you are decorating your class with [Serializable] and your members with [XmlIgnore] then you are probably confusing yourself or other readers of your code.

XmlSerialization in .NET is very flexible. Depending on how the serialization is being done, directly by you or indirectly, let's say by the web services runtime - you have different ways to control things.

One option is to use the propertyNameSpecified pattern to turn ON or OFF the property in XML Serialization. Suppose you have this code:

public class TypeA
{ 
  public DateTime LastModified;
  [XmlIgnore]
  public bool LastModifiedSpecified;
}

Then, if LastModifiedSpecified is false in an instance, the LastModified field will not be serialized for that instance. In the constructor for your type, you can set LastModifiedSpecified to always be true in the base type, and always false in the derived type. The actual boolean - LastModifiedSpecified - never gets serialized because it is marked XmlIgnore.

This little trick is documented here.

Your other option is to use XmlAttributeOverrides, which is a way of dynamically providing the set of XML serialization attributes (like XmlElementAttribute, XmlIgnoreAttribute, XmlRootAttribute, and so on...) - dynamically providing those attributes to the serializer at runtime. The XmlSerializer, instead of inspecting the type itself for those attributes, will just walk through the list of override attributes provided to its constructor.

    var overrides = new XmlAttributeOverrides();
    // ....fill the overrides here....
    // create a new instance of the serializer specifying overrides
    var s1 = new XmlSerializer(typeof(Foo), overrides);
    // serialize as normal, here.

This is illustrated in more detail here.

In your case, you would provide an XmlIgnoreAttribute as an override, but only when serializing the derived type. (or whatever) This works only when you directly instantiate the XmlSerializer - it won't work when serialization is done implicitly by the runtime, as with web services.

Cheers!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...