Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using XmlIgnore on generated partial classes

I've got a LINQ 2 SQL generated class I'd like to expose through a webservice. There are some internal properties I don't want to be available.

Normally I'd throw [XmlIgnore] in there but because the properties are in the generated half I can't do that.

I've been looking at using MetadataType following this post which looks like it should allow me to define the property attributes in another class.

My code looks something like this:

[MetadataType(typeof(ProspectMetaData))]
public partial class Prospect : ApplicationBaseObject
{
}

public class ProspectMetaData
{
     [XmlIgnore]
     public object CreatedDateTime { get; set; }

     [XmlIgnore]
     public object AmendedDateTime { get; set; }

     [XmlIgnore]
     public object Timestamp { get; set; }
}

I'm referencing this through an ASP.NET Web Service from a Silverlight Project.

The issue is that the [XmlIgnore] attributes are being ignored, those properties are being sent through.

Does anyone have any insight into what might be going wrong here? and what might be the best way to do this?

like image 413
Tristan Warner-Smith Avatar asked Jun 10 '09 13:06

Tristan Warner-Smith


3 Answers

You can do this by passing your own XmlAttributeOverrides to the XmlSerializer, in the XmlAttributeOverrides you can change the XmlIgnore to true for the fields/properties you wish without touching the DBML generated code and it works like a charm, use the same overrides to deserialize as well...

Refer this link for more information

    // Create the XmlAttributeOverrides and XmlAttributes objects.
    XmlAttributeOverrides xOver = new XmlAttributeOverrides();

    XmlAttributes attrs = new XmlAttributes();
    attrs.XmlIgnore = true;

    /* Setting XmlIgnore to true overrides the XmlIgnoreAttribute
        applied to the following fields. Thus it will be serialized.*/
    xOver.Add(typeof(Prospect), "CreatedDateTime", attrs);
    xOver.Add(typeof(Prospect), "AmendedDateTime", attrs);
    xOver.Add(typeof(Prospect), "Timestamp", attrs);

    XmlSerializer xSer = new XmlSerializer(typeof(Prospect), xOver);
    TextWriter writer = new StreamWriter(outputFilePath);
    xSer.Serialize(writer, object);
like image 149
Ash Avatar answered Nov 17 '22 15:11

Ash


AFAIK, MetadataTypeAttribute is not supported by XmlSerializer (although it would be nice - I've simply never checked). And as you say, you can't add member attributes in a partial class.

One option may be to make the generated properties non-public (private, protected or internal) - and name it something like TimestampStorage (etc) - then re-expose them (in the partial class) on the public API:

 [XmlIgnore]
 public object Timestamp {
     get {return TimestampStorage; }
     set {TimestampStorage = value; }
 }
 // and other properties

(since XmlSerializer only looks at the public API). The biggest problem here is that LINQ-to-SQL queries (Where etc) will only work against the generated columns (TimestampStorage etc). I've used this approach before with the member as internal, allowing my DAL class to use the internal property... but it is a bit of a fudge.

like image 22
Marc Gravell Avatar answered Nov 17 '22 14:11

Marc Gravell


I agree with Marc. The easiest thing to do is mark them internal. Optionally, you can then re-expose them in the partial class with [XmlIgnore]. BTW, You can control the accessibility of the properties in the linq2sql designer. Get at the properties dialog and you'll see a place to set them

like image 34
Erik Mork Avatar answered Nov 17 '22 15:11

Erik Mork