Database entity exposed as object in WCF service - wcf

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

Related

WCF Custom Class Arguments

I have a WCF method which takes an argument that is a custom class, say,
void MyWCFMethod(MyCustomClass MethodArgument)
In the above, MyCustomClass has a number of constructor overloads. The service has a reference to the class but not the client. I want to allow the client to use the other overloads but the default constructor is the only one that seems to be allowed. Is there a way to do this?
You can certainly do this, but I think it is important to know why the Data Transfer Objects (DTOs) do not expose logic over the service reference.
The WSDL\XSD metadata that is used in order to generate the client proxy to access the WCF Service only describes the web service by the operations exposed and the datatypes exchanged.
Specifically, XSD only describes the structure of your DTOs and not the logic - that is why there is only the default constructor and public properties/fields available on the client proxy.
So the solution is to put all of your custom classes exchanged between the client and service in a separate shared library. This way both sides of the wire have access to the additional logic (like your parameterized constructors) that you could not obtain via WSDL\XSD.
I guess - no!
As I understand MyCustomClass is data contract and marked by [DataContract] attribute.
So WCF runtime will use DataContractSerializer (by default) to deserialize data from received message to the instance of object.
So where can DataContractSerializer get additional parameters for your specific constructors?
Instance of data contract must have public parameter-less constructor to be instantiated.
But maybe you can write own serializer (but keep in mind that DataContractSerializer cannot be inherited)... and provide additional data to constructor. But if you can get that information somewhere just do it in public parameter-less constructor of your data contract.
So I guess you are doing something wrong. Try to specify what is the goal to pass data in constructor in your case. Maybe your app can use some another solution.

Validating parameters with WCF, Unity and VAB

I am developing an application that exposes a WCF service using the Message/Response pattern for service methods. The application is using Unity 2.0 for dependency injection and the Validation Application Block from MS Patterns & Practices. I've already gotten Unity tied into WCF using a custom HttpModule I picked up from several website a while back and everything works great.
In my service interface I have a method such as:
DoSomethingResponse DoSomething(DoSomethingRequest request)
I can easily attach VAB attributes to the service contract to verify that 'request' is never null but I also want to validate the contents of the request object.
To do this, I inject the validator into the DoSomethingRequest constructor and include an internally scoped IsValid property which handles interacting with the VAB validator. Unfortunately, this constructor doesn't get called because WCF deserializes the object and constructors aren't used.
Without getting into the merits of having the request object be a simple DTO versus having some server-side business logic, is there a way to cleanly inject dependencies into an object passed into WCF service as an argument?
If I'm understanding your issue correctly, you have properties on DoSomethingRequest that are instances of some other classes (data contracts) and you want to validate your data contracts as well? Is there some reason you can't just apply validation attributes to your data contract classes as well? This is the approach I've used when using WCF with VAB integration and it's worked out quite nicely.
So it turns out that adding the validation attributes to my DataContract actually works with no additional code. Unfortunately, it doesn't work if validation is defined in the app's config file (app.config or web.config).
As a result, I've stripped out the constructor injection and IsValid property on my DataContract (request object) which makes it more of an annotated DTO which I think is preferred anyway. I only wish that it would work the same with the XML configuration.

Request and Response objects and WCF versioning

I'm in the process of designing my first "proper" WCF service and I'm trying to get my head around how to best handle versioning of the service.
In older ASMX web services, I would create aMethodNameRequest and MethodNameResponse object for each web service method.
A request object would really just be a POCO wrapper around what would typically be in the method parameters. A response object might typically inherit from a base response object that has information about any errors.
Reading about WCF and how the IExtensibleDataObject, FaultContractAttribute and Namespacing works, it seems that I can revert back to using standard parameters (string, int etc) in my method names, and if the service is versioned, then ServiceContract inheritance can provide this versioning.
I've been looking into http://msdn.microsoft.com/en-us/library/ms731060.aspx and linked articles in that, but I was just looking for a bit of clarification.
Am I correct in thinking that dispensing with the Request/Response objects is more ideal for WCF versioning?
EDIT: I just found this article which suggests using explicit request/response object: http://www.dasblonde.net/2006/01/05/VersioningWCFServiceContracts.aspx
I don't agree that dispensing with Request/Response objects is that way to go.
There are obvious benefits of coding with messages:
you can reuse them, which avoids pass 5 ints and 3 strings to a number of different methods.
the properties are named and so can be reliably understood, whereas a parameter that is passed by value through multiple tiers could be confused, and so on.
they can be proper objects rather than just data containers, if you choose - containing private methods, etc
But you are really asking about versioning. Don't forget that you can version the messages within your service contracts. The classes in assembly can have the same name provided they are in different namespaces (e.g. v1.Request and v2.Request), and they can both implement a required interface or inherit from some base object.
They also need to be versioned for your service consumer, which can be done with xml namespaces; I've typically put the service contracts (the operations) in a namespace like http://myapp.mydomain/v1 and the messages (the request and response objects) in http://myapp.mydomain/v1/messages.
One gotcha with this approach is that if you have an operation, call it Submit, in the http://myapp.mydomain/v1 namespace then by convention / default the soap objects SubmitRequest and SubmitResponse will also exist in the same namespace (I don't remember what the run-time exception is but it confused me for a while). The resolution is to put message objects in another namespace as I've described above.
See "Versioning WCF Services: Part I" and "Versioning WCF Services: Part II".

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.

Returning NHibernate mapping classes from WCF services

I have a server that handles the database access and a client that consumes the information. The communication from the client to the server is through a WCF service.
When the NHibernate POCO is returned from the service are all the objects in the object graph serialized? If so, is there a way to change it?
I'm also thinking of not returning the NHibernate POCO and instead return an object with only the essential information.
What do you do in these cases?
Use data-transfer objects to move the data from the server to the client. Your business (domain model) objects should not necessarily be exposed outside the core of the application, but should be considered a protected asset.
You can use AutoMapper to automate the translation from business objects to data-transfer objects.
Yeah, you probably want a DTO for this. It's usually considered better to not pass your data objects to the outside world, but also passing hibernate objects directly out of a service can give you some weird behavior, especially if you have lazily loaded collections.