Why doesn't WCFTestclient understand standard EF objects but understands STE objects - wcf

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.

Related

What is the reason keeping attribute within WCF Service?

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.

Should a WCF service return an EntityObject or a POCO/DTO class?

I've been looking at a lot of WCF examples using EntityFramework and most of them seem to return some kind of POCO or DTO class to the client.
I was wondering why this was since the default EntityObject includes the [DataContract] attributes and implements INotifyPropertyChanged. Is returning a DTO or POCO class better than an EntityObject (or vise versa)? And is there specific instances where it is better to use one return value over another?
As a best practice, you should definitely have it return a DTO/POCO class that is explicitly designed as a data contract and has no persistence logic.
The reason is, if you pass an EntityObject, you are making an assumption that the consumer of the service will have a reference to the same data context, and this violates the SOA tenet of explicit boundaries. It reduces the reusability of your service.
It is probable that Microsoft implemented DataContract on the EntityObject to support some of their WCF-based database access tools like RIA. The INotifyPropertyChanged is for WPF binding support, and is not related to WCF or data contracts.
It is worth to return the POCO in some cases where you don't aware of persistence logic. I mean the same POCO can plugged to other ORM or for other purpose. Ok this is advantage of POCO over ORM but it also gives you performance boost over EntityObject which does add proxy/notifiers run time.
Returning POCO - You have to manually update the state of entity when received from WCF.
Returning EntityObject - You receive the entity with maintained state.

Is there a way to change EntityKey and ExtensionData access to protected when using Linq-to-entities and WCF?

I have been looking at using Linq to entities with WCF for some projects that we are doing. Everything so far has worked out great but there is one thing that I am not so sure about. Linq-to-entities is creating objects which have EntityKey and ExtensionData properties. I am happy about their access in the service but concerned about the fact that clients seem to have access to this too seeing as they are public properties in the EntityObject class.
It seems to me that this causes a leaky implementation because the client should not be aware of the fact that this object was obtained using linq-to-entities.
You can't change the access modifier because EntityKey property is inherited from parent EntityObject class which shows it as public. ExtensionData property is not related to entity framework. It is defined by IExtensibleDataObject which is implemented in all WCF proxies generated from Visual studio or svcutil. Again you can't change its access modifier.
This is usally the reason why people don't expose entities as data contracts in WCF. If you use EF v4.0 you can use POCO classes or Self tracking entities instead of heavy Entities. If you don't use EF v4.0 you should create separate data transfer objects or try to implement DataContractSurrogates for your entities.

WCF Data Contract / Serialization

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.

Exposing existing business objects in WCF

I know there have been similar questions on this topic but I wasn't completely sure they were solving the same problem. So just to be clear...
I have an existing class library that has namespaces for types, business logic and data access. The classes in the logic and data access namespaces are static and have basic crud methods to fill the type instances with data or take type instances that are already full and do inserts or updates in the database.
Now, in addition to the existing applications that reference this library directly, I want to also create a WCF service so that other applications can consume the objects and methods that way.
Every WCF turorial that I see creates the domain objects in the service project - but I don't want my objects defined in two places.
So I was thinking I could reference serialization in my existing class library and mark the type classes as [DataContract] and the properties as [DataMember]. Then, in the WCF project, create the [ServiceContract] interfaces with [OperationContract] methods to match the static logic classes and methods from the existing library that I want to expose. Then, from the WCF project, reference the existing class library and implement the WCF interfaces by having methods in it that call the existing library logic methods which return the existing library types.
Is this a good pattern?
It sounds good but retrofitting serialization tends to be more trouble than it seems at first. I would suggest that you build some lightweight data contracts into a service layer and then build a small tier that sits between your service layer and the business layer to translate the data contracts into business objects and vice-versa.
Assuming your business object can be serialized (have attribute Serializable) one approach could be creating DataContainer object, which will be your data contract. This object would be used in your CRUD methods.
For example your interface could be
Update(DataContainer obj)
Insert(DataContainer obj)
etc.
Then you would use Binary serialization to pack your object into array of bytes and pass it this way through WCF. On the other side you would deserialize them using again BinarySerialization. You just have to make sure that both sides (client and server) have valid version of assembly with your business objects types.