How to stop wcf service generating entity framework references - wcf

I have a WCF service containing an entity framework project.
I also have DTO classes that I use to expose the data. The entity objects get mapped to DTO objects.
When I generate a service proxy I am seeing both the entity object and the DTO object.
If I have a table called Product I get a Product and a Product1 reference.
This didn't use to happen.
What have I done to cause this and how can I stop my entity objects being exposed?
More Info:
When EF generates a model object from the database, it adds a data contract attribute like this:
[EdmEntityTypeAttribute(NamespaceName="KernMobile_V5Model", Name="JobMaster")]
[Serializable()]
[DataContractAttribute(IsReference=true)]
public partial class JobMaster : EntityObject
I assume this means that it will be exposed by the service?

The service only exposes objects that are used in the service operations, or are specified as a known type to be exposed.
If your client proxy is generating an object for these entity framework objects, you must be exposing them through your service somehow. This can be as request or response objects, or as properties on those objects.

Related

How can I send POCO Entities through WCF Service when I don't want to track the entity *later*?

I have an ASP.NET MVC 4 project, where Controller calls a WCF Service layer, that calls Business Layer, that use a Repository of EF 5.0 Entities. Then the results are returned as POCO entities to the Controller.
It works fine while the WCF Service is directly referenced as a Library, but I know it won't work referenced as a Service because they will need to be serialized, and with ProxyCreation enabled this is not possible.
I don't want to create DTOs because I use generated POCO entities, that's why they exist in my humble opinion.
I want to track changes only before the POCO entities reach Service layer.
A lot of people talk about using DTOs even when they are identical to POCOs, if I do that, I could create auto-generated copied classes just with different names to be a "Proxy disabled POCO as DTO", what would be a little strange.
Could I kill the proxy class of a POCO, in a way the object could be serialized when returned from the Service layer?
Also I don't know if this idea is a good practice. But would be great to send "clean" entities to my Controllers, ready to me mapped to ViewModels.
I'm looking for performance too.
The problem is solved using ProxyDataContractResolver. We must use [Serializable] and [DataContract(IsReference=true)] too. With this combination, ProxyCreation can be enabled.
The way we handled this was by doing the following:
Customize the T4 generating the POCO classes so that it generates classes decorated with
[Serializable()] and [DataContract(IsReference=true)] attribute.
Both frontend (views) and backend (wcf service / business layer) references the POCO generated classes, since you won't be using proxy due to IsReference=true.
and that's basically it.
With this, you don't have to create DTO and just use the POCO classes both in backend and frontend.
Keep in mind though, that WCF using IsReference=true handles does not like redundant objects (so this would be an issue on some POCO classes with navigation properties).

Database entity exposed as object in WCF service

I have a WCF service in which I have a method which returns an IQueryable of an object representing a database table (Accommodation) using Entity Framework. When I try and use that method on the client side the method does not return IQueryable but object. I looked at the code for the service and the Accommodation class that Entity Framework generates has this attribute
[DataContractAttribute(IsReference=true)]
So, AFAIK the client should be able to see that class. What is going wrong here?
Thanks,
Sachin
The type will only appear in the metadata if it is used on the contract. The metadata has no idea what IQueryable is - its a definition of behavior whereas the contract only defines state so the generated code will use somethingit does understand in this situation - i.e. object
It is really not a good idea to use the EF generated types on your service contract - you, in effect, tightly couple your service consumers to your data access layer. Use EF internally in the service and use types which define the data you want to pass around on the service boundary

Consuming Entity Framework entities in a client application that are exposed using a WCF services

I have a DAL where I have Entity Framework to expose entities. These entities are used in a WCF Service project and exposed to the client.
I consume these entities in the Silverlight web project via service reference. Then I am using a RIA domain service for code sharing. But I get the following error while trying to load operation:
DomainContext context= new DomainContext();
LoadOperation<Genre> lo = context.Load<Genre>(context.GetGenres());
GetGenres() is a Domain Service operation where it loads all Genres.
[Invoke]
public IEnumerable<Genre> GetGenres()
{
return proxy.GetGenres(); //proxy is wcf proxy.
}
This Query returns a List. Where Genre is the DataContract i
got from the WCFServiceReference.
Actual Error:
The type 'SL.Web.ServiceReference.Genre' cannot be used as type parameter 'TEntity' in the generic type or method
'System.ServiceModel.DomainServices.Client.DomainContext.Load(System.ServiceModel.DomainServices.Client.EntityQuery)'.
There is no implicit reference conversion from
'SL.Web.ChinookServiceReference.Genre' to
'System.ServiceModel.DomainServices.Client.Entity'.
Question is:
Can I do this way or should I have a custom class in Silverlight that maps to the WCF service datacontract and share the custom entity between the Silverlight client and Web project?
Is there a way to share entities from a service reference between Web and client using a DomainService??
The problem is that you have GetGenres marked as an Invoke operation. If you mark it as a query operation and rebuild, I think that you will be in good shape.

Making an interface visible across WCF web services

I would like to declare an interface in my Web Service layer and then have the caller create objects of this interface type via proxy and use them to call the service methods.
However, when I decorate the interface with DataContract attribute, I get an error saying this attribute can only be applied to class, struct and enum. I don't think that ServiceContract attribute makes sense, as the interface I am trying to expose is used only for data transfer purposes. I also noticed that when the interface was decorated with ServiceContract, it wasn't displayed in the proxy class created.
What is the best practice to go about this?
You cannot do that. "DataContract" interface cannot be exposed as part of metadata. Also even if you share the interface (in assembly) your clients will not be able to send their implementation back to your service because receiving side needs real type for deserialized instance.
The service contract is used on the interface, that is the name of the services. The data contract is used on the class, the data that you are sending over.
ServiceContract on the interface
OperationContract on the methods
DataContract on Class
DataMember on properties
See: http://msdn.microsoft.com/en-us/magazine/cc163647.aspx

Adding methods to DataContract objects for WCF

Are DataContracts in WCF nothing more than DTOs? I was reading up about WCF and just had a couple of thoughts. It would be nice if some of the DataContract objects could have methods on them so that the client could do basic things with them before or after sending or retrieving back to the service.
To me this just doesn't seem possible or logical. I could be wrong, I learn new things everyday. So would the next best thing be to treat DataContracts as DTOs and provide libraries for the clients that would create real objects from the DTOs. Objects that would contain methods.
Any guidance would be really appreciated.
Not sure if I correctly understood your answer, so correct me if I'm wrong.
You can create a class library with your DataContracts classes and share the library between the client and server. In this way class marked [DataContract] will have methods (behavior) and [DataMember] fields/properties (state).
When you will pass such objects between client and server via WCF state will be persisted, but since class library is shared you will have methods on both sides.
DTOs that are decorated as DataContract classes are real objects. They can have methods in them, but the methods are not part of the serialization process.
The main time this will cause you issues is when:
you are relying on the generated proxy version of the DataContract objects (like when you have a Silverlight client calling a WCF service, or you are calling a third party service that you have no access to the code or its libraries). The generated proxy versions will not have the methods in them, just the DataMember properties. The way to get round that is to use objects from a shared library (as already mentioned by #Insomniac).
your properties in the DataContract objects are more than just a simple get/set operation, i.e. you may have included some logic to do other operations when a property value is set. In this case even the proxy generated version will not have that logic included. The ways to get round this is to either have the shared library, or have a partial class on the client side that extends the proxy generated class.
Sharing your classes between client and server projects is the way to go. Do not forget to check in your service reference that it tries to reuse types in referenced assemblies. That way, the service reference will not generate proxy classes for the shared objects.
WCF at its core is a message-based system: your client proxy catches the call to a method, wraps up the method and all its parameters into a serialized message, and send that across the network to the service to be processed.
So yes - in the end, all that goes from client to server in WCF is a serialized message - typically in XML format. You cannot serialize behavior or methods with this approach.