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.
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.
When I try to consume a WCF service which expose operations that return standard EF objects I receive a warning on these operations. The warning states "This operation is not supported in the WCF Test Client because it uses type < EntityName >". The generated source code for the entities in my EF model contains ordinary C# classes, inherited from EntityObject and decorated with [EdmEntityType],[Serializable] and [DataContract] attribute.
If I change the standard code generation process and instead produce Self Tracking Entities (STE) I receive classes which are also decorated with the DataContract attribute but they don't inherit from EntityObject anymore. WCF Operations that return STE objects ARE supported by the WCFTestClient.
What is it in EntityObject that prevent WCFTestClient from calling / displaying these operations?
EntityObject is also decorated with [Serializable] and [DataContract].
I know there are other tools besides WCFTestClient that I could use and I have already coded my own testclient but I'm curious of why it behaves like this.
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 have several classes such as Order, Customer, etc. These classes serve for holding data and nothing more. I want to be able to reuse these classes in other projects in the future, but for some reason I don't quite understand, WCF forces me to decorate the data members with the [DataMember] attribute, forcing me to reference WCF plumbing that I will never use in other projects.
I would imagine that WCF lets you take any serializable class and use it as a content type. Am I understanding this correctly?
Yes, with .NET 3.5 SP1, the WCF DataContractSerializer will now serialize any POCO class just the same way as the XmlSerializer will - any public property will be serialized.
I don't know for sure whether that's a good thing - one of the pillars of WCF is being explicit, in order to clearly state your intent. I personally find it a good thing to mark your classes with [DataContract] and your fields and properties you want to have serialized explicitly with [DataMember] - it makes it clearer as to what's going on, and it doesn't hurt your POCO class at all.
And btw: you don't have to reference any "WCF plumbing" to do this - those attributes live in System.Runtime.Serialization - a very generic system assembly.....
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... :)