none
DataContract versus Serializable

    Question

  • Okay, I LIKE and PREFER Data Contracts versus Serializable. I have built and tested many scenarios and the tests work great and I like the level of control.

    Now I am looking at converting some existing functionality and am also looking at 'backwards' compatibility and the question I am going to ask does not seem to be clearly answered (at least where I looked).

    If I use the DataContract to establish serialization, what happens with non-WCF access to the class. Are classes marked with DataContract also Serializable?

    I also noticed that DataContracts support .NET 2.0 featues like nullable types. If I add nullable types and they serialize fine for WCF - again - what happens with the class when it passed to non-WCF membrs that require Serializable? What happens to nullable types?

    Is the any info that provides accurate (not a blog or opinion) details on how to deal with this.

    If using DataContracts does not provide backward compatibility, can both attributes be used simultaneously? Are there any known "gottchas" besides the obvious degredation of performance?

    I would like detailed and specific info on this, any ideas where to find it?

    TIA

    Trevor

    Saturday, January 20, 2007 11:49 PM

Answers

  • 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 takes the projection of [DataContract]

    3. Here is the docs on data transfer and serialziation in WCF which provides a lot of detail on the serializers and know type

    http://msdn2.microsoft.com/en-us/library/ms730035.aspx

     

    Wednesday, January 24, 2007 7:20 PM

All replies

  • >>If I use the DataContract to establish serialization, what happens with non-WCF access to the class. Are classes marked with DataContract also >>Serializable?

    DataContractSerializer only will understand DataContract and DataMember attributes. So, you should be able to access you classes
    fine but for Serialization you need the [Serializable] attribute or implement ISerializable.

    Check these articles blog might offer some help

    http://blogs.msdn.com/sowmy/archive/2006/02/22/536747.aspx

    http://msdn.microsoft.com/msdnmag/issues/06/08/servicestation/default.aspx

    http://dotnet.org.za/hiltong/articles/50121.aspx

    >>If using DataContracts does not provide backward compatibility, can both attributes be used simultaneously?
    I think so.


    T.Ramesh.

     

    Sunday, January 21, 2007 4:51 PM
  • I am still not "sure", based on your comment.

    Specifically, I want to "know" that both attributes can (for sure) be used simultaneously.

    On a side note :

    I am leaning towards the NetDataContractAttribute because of the "KnownAttribute" requirements. I understand that a huge feature of WCF is true services, as in a third-parties will access the services, but known attributes works horribly for using WCF on an N-Tiered enterprise application where WCF will operate on a completely internal level.

    Specifically, I am testing a generics-based version of the MVP (Model View Presenter) pattern. I am not a fan of a view for every class, nor a service for every class, it makes no sense to me when the actions/tasks/ behavior is identical for all views. Thus, the presenter operates using generics and works on the type provided, not on every specific pre-defined type. I have hundreds of classes that use the same presenter, so having to declare hundreds of known types on a contract is not good, nor particulary friendly to OO design patterns in general.

    I agree that known types work GREAT for third-parties and alleviate many problems; however, someone made the decision not to pass types along with the interface as the NetDataContractAttribute provides.

    I highly suggest that this is reconsidered. Forcing usrs to one teams' version of the correct implementation is simply too restrictive especially when the current model does not work for the scnario I described. I really can't imagine that any developer is going to be particularly happy to learn that WCF is a Y where known types pass on correctly and unknown types are rejected.

    Trevor

    Wednesday, January 24, 2007 12:31 AM
  • 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 takes the projection of [DataContract]

    3. Here is the docs on data transfer and serialziation in WCF which provides a lot of detail on the serializers and know type

    http://msdn2.microsoft.com/en-us/library/ms730035.aspx

     

    Wednesday, January 24, 2007 7:20 PM
  • I hate to correct an old post like this, but for the sake of anyone else looking for information on this issue, I feel it is necessary to point out that the above "answer" is incorrect. DataContractAttribute and SerializableAttribute (or ISerializable) can NOT be used together. Doing so will cause an exception when the DataContractSerializer attempts to serialize the object. This is documented in the MSDN entry for the DataContractSerializer:

     

    The DataContractAttribute attribute should not be applied to classes that already implement the ISerializable interface or that are marked with the SerializableAttribute. An exception is thrown if you try to serialize an instance of such a type.

     

    For existing types, the SerializableAtttribute or ISerializable is understood by the DataContractSerializer, so you don't need DataContract (unless you are trying to use an existing type to conform to a WCF contract with different naming requirements, in which case, as far as I can tell, you are out of luck). For new types, you can choose which one to use. There are several factors to consider:

     

    1. SerializableAttribute/ISerializable is understood by the "old" serialization engine; DataContractAttribute is not.

    2. DataContractAttribute is opt-in; SerializableAttribute is opt-out; ISerializable is completely custom

    3. ISerializable gives you the option of controlling the serialization of the object to handle special situations (e.g. singletons)

    4. DataContractAttribute/DataMemberAttribute give you control over the name AND namespace of each member, giving you more flexibility in conforming to contracts and interoperating between types.

    • Proposed as answer by Eric Anastas Wednesday, June 30, 2010 5:10 AM
    Tuesday, May 22, 2007 4:27 PM
  • I ended all my problems by taking over the serialization process. From my view, there are two major categories  of communication: internal and external. My major issues have been dealing with internal communication needs where I control the client and the server. It is extreme overkill to redefine (especially in terms of international compliance) what is being sent internally. My client has full knowledge of what it sends and receives as well as the server.

     

    For internal needs, its much simpler to use WCF contracts that involve byte[] and type. For external - I.e. web services for third-party access, all those definitions for contracts and services are critical. So, for internal needs, I will still emphasize that I think there should be a focused effort to support both needs "out-of-the-box". It should be simple: assume we share a common library and I should not have to redefine anything to send it over the wire. Futhermore, I should be able to send any object that is serializable over the same method. If you think byte[] and type, then you can imagine what I mean. To accomplish this now, I preserialize it myslef and have the contract identify the type that relates to the byte array.

     

     

    Trevor

    Wednesday, May 23, 2007 1:09 AM
  • @David A Nelson,  I think what he meant by saying DataContract and Serializable can be used together, is that you can have both together within the same serialization.  Although one type cannot have both attributes, you can mix the properties of a type with both DataContracts and Serializable.

    IE:

    [DataContract]
    [Serializable]
    public class A
    {
    //Does not work!
    }
    
    
    [DataContract]
    public class B { }
    
    [Serializable]
    public class C { }
    
    [DataContract]
    public class D //Mixing of Serializable and DataContract that works
    {
       [DataMember]
       public B B { get; set; }
    
       [DataMember]
       public C C { get; set; }
    }
    
    
    Wednesday, March 16, 2011 3:13 PM
  • I use classes that are both DataContact and Serializable just fine with .NET 3.5: sometimes they are serialized via DCS (for storage) and other times they are serialized via Serialiable (for a clone). The restriction/warning note can only be found in .NET 3 and previous documentation and is not present on the .NET 3.5 or .NET 4 documentation pages.

    YMMV.


    • Edited by pstickne Friday, November 18, 2011 3:16 AM
    Friday, November 18, 2011 3:15 AM

  • The DataContractAttribute attribute should not be applied to classes that already implement the ISerializable interface or that are marked with the SerializableAttribute. An exception is thrown if you try to serialize an instance of such a type.

    This is documented in the MSDN entry for .NetFramework 3.0 http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer(v=VS.85).aspx.

    This restriction has been removed in .NetFramework 4.0 http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.aspx.

    You can use both attributes on a class together, it wouldn't cause any issue. [DataContact] is used for XML stream serialization and [Serializable] is for binary stream serialization. In many cases we have to use both stream types.

    Wednesday, July 04, 2012 7:41 PM
  • Good to know: This remark from MSDN appears in .NET 3.0, but not in .NET 3.5 and up.

    And from personal experience I can say that using both [DataContract] and [Serializable] attributes works well on .NET 4.5.


    • Edited by tsemer Thursday, September 26, 2013 9:32 AM
    Thursday, September 26, 2013 9:30 AM
  • Again, the first example works in .NET 3.5 and up (see my remark to David A Nelson)
    Thursday, September 26, 2013 9:33 AM