.NET Framework Bookmark and Share   
 index > Windows Communication Foundation > Using custom attributes in DataContracts makes my DataContracts unserializeable
 

Using custom attributes in DataContracts makes my DataContracts unserializeable

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 {}

}

}

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?

RightCoder
Hi,

Have you marked your custom attribute with [Serializable]? Actually it works fine here - both
with and without it, so it might be something else. ( ChannelFactory / Shared assembly scenario ).


--larsw
Lars Wilhelmsen

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 inits inherited contracts likethis:

[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 aclass 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?

RightCoder
YOu can use IExtensibleDataObject but you will need to add a reference to the assembly. Also when derviing from a class, make sure to add teh [KnownType(typeof(baseClassName))] attribute to the new class so that the wsdl generation can correctly pick up the base class members.
Dan Rigsby

Should I use the KnownType attribute for every subclass in the inheritance hierarchy or just the lowest base class?

Eg:

public class CustomerContract : ActorContract, IExtensibleDataObject

{

}

public class ActorContract : EntityContract, IExtensibleDataObject

{

}

public class EntityContract : IExtensibleDataObject

{

// Implements the IExtensibleDataObject interface

}

Should this declare the CustomerContract with the only known type EntityContractlike this:

[DataContract]

[Serializable]

[KnownType(typeof(EntityContract))]

public class CustomerContract : ActorContract, IExtensibleDataObject

{

}

RightCoder
Yes, sothat the wsdl can generate the correct properties.

Dan Rigsby

Sorry that I'm not sure what you said yes to. I asked you a twofolded question, sorry for that.

To make the question a bit clearer:

Should I declare every inherited class as a known type like this:

1)

[DataContract]

[Serializable]

[KnownType(typeof(ActorContract))]

[KnownType(typeof(EntityContract))]

public class CustomerContract : ActorContract, IExtensibleDataObject

{

}

or just like this:

2)

[DataContract]

[Serializable]

[KnownType(typeof(EntityContract))]

public class CustomerContract : ActorContract, IExtensibleDataObject

{

}

Which is the correct way? 1 or 2?

Again, sorry being so daft...

RightCoder
The first way. You want to make sure that the metadata gets all that it needs.

Dan Rigsby

I did what you said, but now it's the ExtensionDataObject that is the problem. My base contract implements the interface IExtensionDataObject:

[DataContract]

[Serializable]

public class EntityContract : IExtensibleDataObject

{

#region IExtensibleDataObject Members

private ExtensionDataObject extensionData;

public ExtensionDataObject ExtensionData

{

get { return extensionData; }

set { extensionData = value; }

}

#endregion

}

I get this error message:

System.Runtime.Serialization.SerializationException: Type 'System.Runtime.Serialization.ExtensionDataObject' in Assembly 'System.Runtime.Serialization, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable.

As you can see in the code snippet above I have implemented it in the base class and it is in a assembly that I have no control over. Why this message?

RightCoder

I did what you said, but now it's the ExtensionDataObject that is the problem. My base contract implements the interface IExtensionDataObject:

[DataContract]

[Serializable]

public class EntityContract : IExtensibleDataObject

{

#region IExtensibleDataObject Members

private ExtensionDataObject extensionData;

public ExtensionDataObject ExtensionData

{

get { return extensionData; }

set { extensionData = value; }

}

#endregion

}

I get this error message:

System.Runtime.Serialization.SerializationException: Type 'System.Runtime.Serialization.ExtensionDataObject' in Assembly 'System.Runtime.Serialization, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable.

As you can see in the code snippet above I have implemented it in the base class and it is in a assembly that I have no control over. Why this message?

RightCoder
Hi,

Are you really sure you use the DataContractSerializer and not the XmlSerializer?

--larsw
Lars Wilhelmsen
How do I know that? I mean, I create DataContract classes and tag them with the tag [DataContract]. What else could I do or should not do? As you can read I'm not that sure, but I think I use the right serializer here. How can I find this out for sure?

RightCoder
You're using the DataContractSerializer. The [DataContract] attribute makes this the case. The reason ExtensionDataObject is still giving you trouble is because you're exposing an instance of that non-serializable class in a property. If that property is defined in the interface, then you're out of luck. You'll need to define your own interface or base class that does what the ExtensionDataObject does, only without the annoyance of being non-serializable. Although I thought that the ExtensionDataObject class is something that the VS-generated client-side proxy code uses... why do you need it?
jbatte

You can use google to search for other answers

Custom Search

More Threads

• Properly exposing multiple objects in WCf Service
• WCF credential issue
• WCF service iis host on my ISP
• Why WCF formatter is throwing an exception?
• A questions about nullable types and DataMembers
• Determine the tcp ports the client use
• Fulted Channel
• HTTP/1.1 415 Missing Content Type - How to avoid this?
• Reliable messaging with MSMQ over WCF
• Sharing Service Instances and Singleton Service