I'm new to the validation application block and trying to use it with wcf...
I have a wcf service that has data objects with validation rules defined with attributes, using the validation application block .
On my client side (WPF), I have a service reference. When I update the service reference the generated classes do not have the validation rules attributes in them.
How can I get the rules from the service?
Am I missing some step, or is it not possible?
When you use Add Service Reference, proxy classes are created for the service. However, this will not retain all of your Validation Attributes but just create properties corresponding to the service metadata. In order to retain the validation rules you will need to share your service and data contracts between WCF and WPF.
To do this move all of your service and data contracts into an assembly. WCF and WPF should both reference this assembly. Then you can create your own proxy class using ClientBase or ChannelFactory.
Since both WCF and WPF are referencing the same classes annotated with the VAB Attributes you can invoke validation in both WCF and WPF using Enterprise Library.
Related
My WCF Service has API to create 'Employee' object which needs to be send to client app. This object has set of methods and properties. Now, client need to access Methods in order to set it's fields (API has few validation logics to set it's fields). How WCF service will send an custom object where client must be able to access methods.
Here the design is, my wcf service will provide a 'template' (from api) to client where in client uses this object methods to set/update fields and will send back to service.
If the objects you send and receive have logic associated to them (not a very good idea), you will need the assembly where those objects are impemented on both sides, since the metadata exposed by wcf only shows fields, and not methods.
I'd split that in two, keep the datacontracts clean and if you need validation logic, you can either do it in the wcf service and return errors to the client, or in the client, but that will extra logic to the client that you'll need to provide.
I'd go with validation logic in the server, and clean datacotracts. It's the best way to ensure your services are interoperable.
Its not a good idea to return any objects from wcf service which contains any functions. Keep the data contract simple by having only fields (properties) , if any additional operation is needed make this available as part of operation contract.
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.
I wrote a couple of simple web methods (as a part of WCF service) that use a couple of (more complex) classes as input/returned parameters. Each web method attributed by [OperationContract], each data class attributed by [DataContract], each data field in the classes attributed by [DataMethod].
On the client side I can call these web methods by adding Service Reference.
All things are fine, but when I create an instance of some of the data classes above on client side, their constructors don't run.
Because it's a little complicate to initialize each instance, every time, I thought there is some way to initialize instances on client side by their own constructors.
Thanks in advance!
Ilan.
Methods exposed on data contracts (including constructors) in your service are only for service applications. Adding service reference will recreated only data structure of your data contract classes because service description is not able to describe logic and logic cannot be serialized.
All classes created with service reference are partial. You can create your own partial class and add your own custom constructors or you can share the assembly with data contracts between your service and client (but it will share all logic added to your data contract classes which is most often what you don't want). Sharing assembly will tightly couple your client and service.
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.
I have a custom data entity (data object) that is exposed via a WCF webservice. The WCF service lives in a web application. I then have a Silverlight application with a service reference to that WCF service. When i add the service reference a proxy is generated, and that includes a version of the custom data entity.
How should i structure my code so that the data entity is declared in one place, and shared amongst the project containing the WCF service and any Silverlight applications that reference it? I want to eliminate the version of the data entity that is generated with the proxy.
There is a good example of how to do this here by Pete Brown. Using that approach you can use the same classes in both the Silverlight client and in the WCF service without having to use the generated objects.
Declare the data entities in the WCF service or a project that the service refereneces, then from the Silverlight project add the entities as links and make sure the "Reuse types in referenced assemblies" checkbox is selected from the Service Reference Settings dialog.
You can put the types in either the Silverlight or WCF side.
I have tried doing things this way and found that using DTOs instead and mapping them to the entities in the Silverlight side to be much cleaner and easier to work with although I did write a bunch of mapping code to get the DTOs into the entities and vice versa.
I´m not quite shure why anybody want to do that. You have to understand that the type you find in the proxy is a projection of the Type you have at Service server site. It´s defined in the *.g.cs files and gets generated new if you update the service reference.
In my opinion it´s the best way to have it declared in a single location, and project it. You need it in two places and it´s single defined.
I may be wrong anyway .....