Why can't I use WCF DataContract and ISerializable on the same class?
Asked Answered
M

3

11

I have a class that I need to be able to serialize to a SQLServer session variable and be available over a WCF Service. I have declared it as follows

namespace MyNM
{
[Serializable] 
[DataContract(Name = "Foo", Namespace = "http://www.mydomain.co.uk")]

public class Foo : IEntity, ISafeCopy<Foo>
{
    [DataMember(Order = 0)] 
    public virtual Guid Id { get; set; }

    [DataMember(Order = 1)] 
    public virtual string a { get; set; }

    DataMember(Order = 2)]
    public virtual Bar c { get; set; }

    /* ISafeCopy implementation */
}


[Serializable]
[DataContract(Name = "Bar ", Namespace = "http://www.mydomain.co.uk")]
public class Bar : IEntity, ISafeCopy<Bar>
{
    #region Implementation of IEntity

    DataMember(Order = 0)]
    public virtual Guid Id { get; set; }
    [DataMember(Order = 1)]
    public virtual Baz y { get; set; }

    #endregion

    /* ISafeCopy implementation*/
}


[Serializable]
[DataContract]
public enum Baz
{
    [EnumMember(Value = "one")]
    one,
    [EnumMember(Value = "two")]
    two,
    [EnumMember(Value = "three")]
    three
}

But when I try and call this service, I get the following error in the trace log.

"System.Runtime.Serialization.InvalidDataContractException: Type 'BarProxybcb100e8617f40ceaa832fe4bb94533c' cannot be ISerializable and have DataContractAttribute attribute."

If I take out the Serializable attribute, the WCF service works, but when the object can't be serialized to session. If I remove the DataContract attribute from class Bar, the WCF service fails saying

Type 'BarProxy3bb05a31167f4ba492909ec941a54533' with data contract name 'BarProxy3bb05a31167f4ba492909ec941a54533:http://schemas.datacontract.org/2004/07/' is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer

I've tried adding a KnownType attribute to the foo class

[KnownType(typeof(Bar))]

But I still get the same error.

Can anyone help me out with this?

Many thanks

Dave

Mashie answered 17/3, 2010 at 10:33 Comment(1)
S
7

This question on MSDN might help: DataContract versus Serializable.

The accepted answer from that thread:

  1. [DataContract] and [Serializable] can be used together.

  2. DataContractSerializer understands both of them. If the type is marked with both of them, it will take the projection of [DataContract]

  3. Here are the docs on data transfer and serialization in WCF which provide a lot of detail on the serializers and known type: Data Transfer and Serialization

Singlefoot answered 17/3, 2010 at 10:38 Comment(4)
Thanks - in the end, what I did was make copies of my classes and returned them across the service.Mashie
would be nice to have the actual answer here, rather than a link as the forums are currently down for maintenance...Sourdine
@MaxSchilling: You're right - having just a link without a summary is bad practice (I've learnt since I posted that answer). I'll fix it once the forums are up.Singlefoot
This answer is wrong, or poorly worded. [DataContract] and [Serializable] CANNOT be used together. You can use either with DataContractSerializer but applying both attributes will not work.Gurule
R
2

I know this is very late, but in case anyone reads this, we had a similar issue. Our solution to leave the DataContract as is so WCF serialized fine, and then when we serialized to the SQL Server session, we serialized the object to JSON and wrote that to the session.

Rachelrachele answered 23/4, 2013 at 15:2 Comment(0)
H
0

I ran into this same problem with serialization for the entity framework pocos across wcf. Nothing was working and I was about to give up when I tried removing the virtual tags from the members. All of a sudden it started working. Give that a try.

Hagiography answered 27/11, 2011 at 4:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.