I am working with WCF .NET 3.5 SP1 and have read that one does NOT have to decorate their Entities/Collections with such things as [DataMember], [DataConract], and/or [Serializable]? What is the best way to go? What have you all encountered?
I am on 3.5 SP1.
See Using Data Contracts.
New complex types that you create must
have a data contract defined for them
to be serializable. By default, the
DataContractSerializer infers the data
contract and serializes all publicly
visible types. All public read/write
properties and fields of the type are
serialized. You can opt out members
from serialization by using the
IgnoreDataMemberAttribute. You can
also explicitly create a data contract
by using DataContractAttribute and
DataMemberAttribute attributes. This
is normally done by applying the
DataContractAttribute attribute to the
type. This attribute can be applied to
classes, structures, and enumerations.
The DataMemberAttribute attribute must
then be applied to each member of the
data contract type to indicate that it
is a data member, that is, it should
be serialized. For more information,
see Serializable Types.
Like #Terry said, it's probably better to proactively declare which properties you want to expose. This way you could future proof your code from unintentionally exposing fields when the base class adds a public property in the future.
I'm of the opinion that it won't hurt to proactively express you intent to use the class as a DataContract. I would guess that a class that isn't serializable still won't be useful as a DataContract in SP1... :)
Related
What is the benefit of keeping attribute in WCF service?
What I mean is why to give them [Datamember] and [Datacontract] and what's advantage and disadvantage?
What happens if I make attributes and its class in different project with simple class library project and I insert its "dll" reference to WCF service class library, which contains all operation that are [ServiceContract] and [operatinconntract] on this attribute.
WCF parameters need to be serializable. Value types such as int and string will be by default and therefore just work.
DataContractAttribute is used to mark complex types as serializable. See Using Data Contracts for more information.
Pre-WCF, serialization was done using the XmlSerializer class and by marking a type as [Serializable] it meant that all members were serialized by default.
However with DataContractSerializer which is the preferred serializer used in WCF, members of a class will not be serialized unless indicated.
Re having contract types in a different assembly - yes this is possible, and actually it's best practice to keep your contract types separate from your service implementation assembly.
I'm using attribute-free DataContract serialization (.NET 3.5 SP 1).
I want change EmitDefaultValue to false for all my DataContracts.
How I can achieve this?
If you want to use the EmitDefaultValue property on the DataMemberAttribute that you apply to a property, then you will have to apply the DataContractAttribute to the type.
This has the unfortunate side-effect of having to place the DataMemberAttribute attribute on all members of the type that you wish to serialize (the ones you were assuming before you used attribute-free Data Contract serialization) due to the nature of Data Contract serialization being all-in when using the attributes.
You can try implementing ISeriaizable interface.
In this case, DataContractSerializer will call your code to perform the mapping, giving you complete control.
Are there any ways to tell WCF to serialize the whole class when it returns? Do I literally have to add DataMember to every property?
Since .NET 3.5 SP1, you don't have to do this anymore.
If you don't have any [DataContract] and [DataMember] attributes, the DataContractSerializer class will behave like the old XmlSerializer: it will serialize all public read/write properties that are listed in the class.
You do lose a few things in the process though:
since you don't have [DataMember] attributes, you cannot define an order of the fields anymore - they'll be serialized in the order of appearance
you cannot omit a public property (since that would require [DataMember] on all other properties/fields)
you cannot define a property to be Required (that would be on the [DataMember] attribute again)
your class now needs to have a public, parameter-less constructor (usually not needed for data contracts)
Read all about it in detail from Aaron Skonnard at Pluralsight.
I love marc's answer, but I want to add some more info.
DataContractSerializer and DataContractJsonSerializer both support, out of the box, many other serialization models as well. This includes IXmlSerializable, Serializable, and ISerializable. POCO support was added in .NET 3.5 SP1, but support for these other models has always been there since .NET 3
This blog post details the extent of the support and more importantly, the prioritization of different models by the serializer (i.e., it tells you what DataContract-based serializers would do if you have one type decorated with multiple serialization models)
So, if you read that blog post, you'll notice that POCO support is last in the priority list. It is the serializer's last resort, if there is absolutely no other serialization programming model available on the type or its parent. For example, if the type is an enumerable of some sort, it will get serializaed according to traditional collection rules. If it's ISerializable or Serializable, it will get serialized according to their serialization rules.
Another important difference: during deserialization of all other types, the default zero-params constructor is never called. For POCO types, it is always called! This gives you an additional hook you don't have so easily in other serialization models!
A class that has the [DataContract] attribute, is it not automatically serialized?
If not, is it a requirement to use the [Serializable] attribute (or inherit from ISerialize)?
I ask this because I have old code from a previous project that apparently the [DataContract] classes do not mention anything, explicitly, about serialization.
The ultimate question:
I want a WCF operation (method) to return a DataContract class.
Does the method have to explicitly serialize the class before returning it, or is it automatically serialized? I always thought it would be the latter.
Thanks!
No, [Serializable] is not necessary on a data contract. It is also not necessary for XML Serialization.
There's a few options for serialization in .NET. SerializableAttribute and ISerializable go back to the beginning and are used by the BinaryFormatter, SoapFormatter, etc.
DataContractSerializer, being relatively new, can support objects that define their serialization ability with SerializableAttribute, but it's not necessary. If you are just serializing the object using DataContractSerializer then using the data contract attributes is all you need to do.
Obviously the members you mark as serializable must also be of serializable types.
For more information, see Types Supported by the Data Contract Serializer on MSDN.
Just to add on to this, DataContractSerializer supports far more than just DataContract types. See this excellent blog post for a detailed walk-through of the entire universe of types supported by DataContractSerializer: http://blogs.msdn.com/b/sowmy/archive/2006/02/22/536747.aspx
I created a simple WCF application which expose one operation. This operation takes a composite data type as parameter.
I have not decorated this composite data type with [DataContract] attribute. But this is working and I can see the Schema for this in WSDL.
Now my understanding is that this new custom type should be decorated with [Serializable] or [dataContract] attribute to take part in the Web services operation.
What I am missing here?
POCO support have been introduced in WCF since .NET 3.5 SP1 and you no longer need to decorate your objects with [DataContract] and [DataMember] attributes. Public properties will be automatically exposed. Although I would recommend you explicitly marking them with those attributes.
As Darin says, sp1 introduced support for inferred data contracts. If the marshalled type is a public type and it is not decorated with the DataContract attribute, WCF will automatically infer such an attribute and apply the DataMemeber attribute to all public members of the type.
In his book "Programming WCF Services", Juval Löwy says;
In my opinion, relying on inferred data contracts is a sloppy hack that goes against the grain of most everything else in WCF. ... Do use the DataContract attribute, and be explicit about your data contracts. This will enable you to tap into data contract features such as versioning.