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.
Related
I have three projects:
WCF Service project (Interface and Implementation)
aspx web project (client) that consumes the WCF Service
class library project that holds my business objects (shared by both WCF project and client)
I have a method in the WCF Service implementation class file that retrieves a generic list of data from SQL (referencing the project that holds the business objects), serialize the data using System.Web.Script.Serialization.JavaScriptSerializer and returns the result as a string.
The web client takes this string and deserializes it back to the appropriate business object (referencing the project that holds the business objects)
This is an intranet app and I want to make sure I am doing this correctly.
My questions are:
Should I be using DataContracts instead of business objects? Not sure when to use DataContracts and when to use the business objects.
If I am using DataContracts, should I not use
System.Web.Script.Serialization.JavaScriptSerializer?
Any clarification would be appreciated.
Of course there is no one answer. I think the question is whether you want to use business objects in the first place, otherwise my fourth point pretty much covers it.
Do use the business objects if they look like the data contracts would, i.e. they are a bunch of public properties and do not contain collections of children/ grandchildren etc.
Don't use the business objects if they contain a bunch of data you don't need. For example populating a grid with hundreds of entities begs for a data contract specific to that grid.
Do use the business objects if they contain validation logic etc that you would otherwise have to duplicate in your web service.
Do use the business objects if you are just going to use the data contracts to fully inflate business objects anyway.
Don't use the business objects if you ever want to consume that service interface from non .net code.
Don't use the business objects if you have to massively configure their serialization.
Don't use the business objects if they need to "know" where they are (web server or app server)
Not your case but: Do use the business objects if you are building a rich client for data entry.
Thats all for now, I'll see if anything more occurs to me. :)
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).
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
I am creating a brand new application, including the database, and I'm going to use Entity Framework Code First. This will also use WCF for services which also opens it up for multiple UI's for different devices, as well as making the services API usable from other unknown apps.
I have seen this batted around in several posts here on SO but I don't see direct questions or answers pertaining to Code First, although there are a few mentioning POCOs. I am going to ask the question again so here it goes - do I really need DTOs with Entity Framework Code First or can I use the model as a set of common entities for all boundaries? I am really trying to follow the YAGNI train of thought so while I have a clean sheet of paper I figured that I would get this out of the way first.
Thanks,
Paul Speranza
There is no definite answer to this problem and it is also the reason why you didn't find any.
Are you going to build services providing CRUD operations? It generally means that your services will be able to return, insert, update and delete entities as they are = you will always expose whole entity or single exactly defined serializable part of the entity to all clients. But once you do this it probably worth to check WCF Data Services.
Are you going to expose business facade working with entities? The facade will provide real business methods instead of just CRUD operations. These buisness methods will get some data object and decompose it to multiple entities in wrapped business logic. Here it makes sense to use specific DTO for every operation. DTO will transfer only data needed for the operation and return only date allowed to the client.
Very simple example. Suppose that your entities keep information like LastModifiedBy. This is probably information you want to pass back to the client. In the first scenario you have single serializable set so you will pass it back to the client and client pass it modified back to the service. Now you must verify that client didn't change the field because he probably didn't have permissions to do that. You must do it with every single field which client didn't have permission to change. In the second scenario your DTO with updated data will simply not include this property (= specialized DTO for your operation) so client will not be able to send you a new value at all.
It can be somehow related to the way how you want to work with data and where your real logic will be applied. Will it be on the service or on the client? How will you ensure that client will not post invalid data? Do you want to restrict passing invalid data by logic or by specific transferred objects?
I strongly recommend a dedicated view model.
Doing this means:
You can design the UI (and iterate on it) without having to wait to design the data model first.
There is less friction when you want to change the UI.
You can avoid security problems with auto-mapping/model binding "accidentally" updating fields which shouldn't be editable by the user -- just don't put them in the view model.
However, with a WCF Data Service, it's hard to ignore the advantage of being able to write the service in essentially one line when you expose entities directly. So that might make the most sense for the WCF/server side.
But when it comes to UI, you're "gonna need it."
do I really need DTOs with Entity Framework Code First or can I use the model as a set of common entities for all boundaries?
Yes, the same set of POCOs / entities can be used for all boundaries.
But a set of mappers / converters / configurators will be needed to adapt entities to some generic structures of each layer.
For example, when entities are configured with DataContract and DataMember attributes, WCF is able to transfer domain objects' state without creating any special classes.
Similarly, when entities are mapped using Entity Framework fluent mapping api, EF is able to persist domain objects' state in database without creating any special classes.
The same way, entities can be configured to be used in any layer by means of the layer infrastructure without creating any special classes.
In my application I am making a service call and getting back populated WCF Data Contract object. I have to display this data in a grid. Is it good practice to bind the data contract to the grid ?
Josh
Is it good practice to bind the data contract to the grid ?
Yes. There is nothing wrong with what you are doing.
Let me elaborate: what you have received back from the WCF service is a standard object (sometimes referred to as a DTO - Data Transfer Object). You have not received a DataContract - you have received an object that used a DataContract to control the serialization process between the WCF service and your client. The DataContract can control or dictate what you get, but once you have that object you are free to treat it as you wish.
Assuming that all of your DTOs are friendly for data binding then shouldn't have a problem binding your WCF DTOs to a grid.
Some scenarios where you might not want to bind directly to your DTOs are:
Your DTOs are not easy to bind with their current definition (e.g. nested objects/properties)
You need to support notification of changes to the binding client (typically done using INotifyPropertyChanged)
You wish to insulate your UI code from changes to the WCF DTOs. This could be because you don't control the DTO definition or you expect frequent changes to the DTO definitions and you don't want to frequently change your UI code. Of course, if the DTO does change then you will have to modify code but you could isolate those changes to a small translation layer.
I'd recommend the use of view models for any data binding or data display (MVVM) on server side (i.e. MVC) and client side (javascrip) rendering.
The main risk of using DTOs returned by domain is that if DTOs are refactored for any reason (i.e. properties are renamed, extracted into other objects or more objects are merged into one) the UI will break and will require update.
DTOs are the contract for what is returned by your domain, whereas the view models are the contract for what the UI requires. The two are controlled by different requirements and although those requirements can be applied to the same set of objects the result is usually a mixture what is just wrong, not to mention that requirements what apply only to UI or domain will trigger changes in the other party.
I.e. views often require data from more DTOs, or different views require a different subset of data from the same DTO and in both cases the DTO should not change only to accomodate what a concrete view requires.
It is also easier to identify what the requirements for a view are if the views have a view model, rather than having the same DTO passed in to more views.