2

I've a few Classes from a assembly which is .Net 2.0. These Classes are marked with Serializable.

In my project, I use these classes in my Classes, which are marked with DataContract(IsReference=true) and DataMember.

Now I have the problem, with DataContractSerialiser that it serializes the private fields of my .Net 2.0 Classes, which will not work. But when I use XMLSerialiser, I cannot use IsReference, and so I can also not do this.

Is there a easy (simple) Solution for this? Maybe a someone has a own XMLSerializer which supports references?

Here is a bit of my code:

[DataContract(IsReference = true)]
public class ConnectionConfig: INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
            PropertyChanged(this, new PropertyChangedEventArgs("ObjectAsString"));
        }
    }

    private PLCConnectionConfiguration _configuration;
    [DataMember]
    public PLCConnectionConfiguration Configuration
    {
        get { return _configuration; }
        set { _configuration = value; NotifyPropertyChanged("Configuration"); }
    }
}

where PLCConnectionConfiguration comes from a .NET 2.0 assembly, and is decorated with [Serializeable]

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Jochen Kühner
  • 1,385
  • 2
  • 18
  • 43
  • You mean you don't want it to serialize the private fields (normally DataContractSerializer only serializes the public properties)? Or that you get an error when he tries to and fails? – Vincent Vancalbergh Mar 11 '11 at 09:36
  • Yes I dont't want to Serialize private Fields, but DataContractSerializer does this on classes decorated with [Serializable] – Jochen Kühner Mar 11 '11 at 11:21
  • what is `PLCConnectionConfiguration` in this example? – Marc Gravell Mar 11 '11 at 12:07
  • It is a class from another asembly, wich I could not change. This class is serializable, but not with the DataContractSerializer, because it serializes the private fields! (Thts my problem!) – Jochen Kühner Mar 11 '11 at 12:32

3 Answers3

0

Annotating a type with [DataContract] should be enough to tell it to look for the members marked [DataMember] - but it sounds like maybe you have a combination of data-contracts and vanilla objects.

If you strictly need xml, my recommendation here would be to write a set of DTO types and use DCS in graph-mode. This may require some mapping between your object model and the DTOs; but that is usually not a big problem. Note also that DCS in graph-mode is not typical xml output - it will be very different to what XmlSerializer would output.

If you just need to serialize arbitrary types (xml not being the issue), then the current experimental cut of protobuf-net supports all these scenarios; it'll handle the object references, and it'll allow you to work with both annotated and vanilla types (you just need to tell it how). If that is an option, perhaps provide a basic example of your model and I might be able to fill in some blanks.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
0

You should abstract the WCF datacontracts from your domain models. Consider the datacontracts to be a view of the model that you want to return in your service.

Annotate your datacontract with a [DataContract] attribute and all the properties you want to expose with a [DataMember] attribute. If there are properties you don't want to return you just DON'T annotate it with the [DataMember] attribute.

If you want your domain models to be XmlSerializable you annotate the class with the [Serializable] attribute.

It may require some additional typing and converting but its clearer overall imho.

Peter
  • 14,221
  • 15
  • 70
  • 110
  • 1
    You could also reduce the time spent converting from domain model object to data contract object using something like AutoMapper - http://automapper.codeplex.com/ – MattC Mar 11 '11 at 11:09
0

Perhaps you could use XmlSerializer and specify XmlAttributeOverrides to ignore the private fields you're not interested in:

var overrides = new XmlAttributeOverrides();
overrides.Add(typeof(PLCConnectionConfiguration), <name of private field to exclude>, new XmlAttributes { XmlIgnore = true });
...
var serialiser = new XmlSerializer(typeof(ConnectionConfig), overrides);

You'd obviously also have to mark your ConnectionConfig as Serializable and add [XmlIgnore] to the _configuration field.

Kai G
  • 3,371
  • 3
  • 26
  • 30