Custom attributes in data contracts

Topics: General Discussion Forum, July and December Releases Forum, Service Factory Modeling Edition Forum
Jun 25, 2008 at 11:11 AM
Edited Jun 25, 2008 at 11:23 AM

Hi 

In some of my DataContracts I have some custom properties that gives me an SerializationException when serialized. I use the same DataContracts (assembly) on both service and client.  

The message sounds something like: "Type 'CustomerContract' in assembly 'DataContracts' is not marked as serializeable

An example of my DataContract that gives my the exception:

[DataContract]
public class CustomerContract : IExtensibleDataObject
{
        private int invoiceItemAggregateOption;

[DataMember]
[DerivedAttribute("Customer.InvoiceItemAggregateOption")]
public int InvoiceItemAggregateOption
{
    get{]
    set{}
}
 

The DerivedAttribute class looks like this:

public class DerivedAttribute : Attribute
{
    public string Path;
    
    public DerivedAttribute(string path)
    {
        Path = path;
    }
}


DataContracts that does not have the "DerivedAttribute" attribute works as a charm, so I guess this is the reason I get this SerializationException

When using the SvcUtil.exe/VS 2008 autogenerated proxy client custom attributes work work very well. It all started when I started to use ChannelFactory and shared assemblies. 

So my question is: Is it possible to use custom attributes on DataContracts? And how?

Jun 25, 2008 at 3:48 PM
I know this may sound wierd but did you try setting "DerivedAttribute" as [Serializable] ?
Regarding this, did you notice any difference between the generated proxy types that include your attribute and the actual attribute type in your library?
Jun 26, 2008 at 3:12 PM

I tried to mark the attribute with [Serializable] but it didn't make any difference. That makes sense if it doesn't matter as you said, it works fine for you with and without.

 Then I tried to set [Serializable] for every contract in its inherited contracts like this:

 

[DataContract]
[Serializable]
public class CustomerContract : EntityContract, IExtensibleDataObject
{

}

 

[DataContract]
[Serializable]
public class EntityContract : IExtensibleDataObject
{

}

After this I got a new message:

Type System.Runtime.Serialization.ExtensionDataObject in the assembly System.Runtime.Serialization, version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 is not marked as serializable.

As you can see this is not a class that I have control over, because its in the System.Runtime.Serialization assembly, and its not serializable. Is it wrong to make my datacontracts implement this interface? I have commed a step further, but not reached the goal yet... Anyone?

Jul 1, 2008 at 8:17 AM
I figured it out. I had to set the KnownTypeAttribute for every Contract which a Contract inherits, like this:

[DataContract]
[Serializable]
[KnownType(typeof(EntityContract))]
public class CustomerContract : EntityContract, IExtensibleDataObject
{
        


I also had to NonSerializedAttribute on the private property in the implementation of interface IExtensibleDataObject like this:

[System.NonSerializedAttribute()]
private ExtensionDataObject extensionData;
public ExtensionDataObject ExtensionData
{
    get {;}
    set {;}
}