views:

335

answers:

2

Greetings!

I am using a WCF library on an application server, which is referenced by an IIS server (which is therefore the client). I would like to put my validation in a place so that I can just call .Validate() which returns a string array of errors (field too short, missing, etc). The problem is, such functions don't cross the WCF boundary and I really don't want to code the same logic in the WCF service and in IIS/WCF client. Is there a way to use extension methods or something similar so both side can use use a .Validat() method which calls the same code?

Many thanks for any ideas! Steve

A: 

Do you have a problem with sending the data over to the server to be validated? In other words, your service interface actually offers the "Validate" method and takes a data contract full of data, validates it and returns a List where T is some kind of custom ValidationResult data contract that contains all the info you need about validation warnings/errors.

In a service architecture, you can't trust the client, who could theoretically be some other company altogether, to have done proper data validation for you. You always need to do it at the service layer and design for communication of those validation issues back to your client. So if you're doing that work at the server anyway, why not open that logic up to the clients so they can use it directly? Certainly the clients can (should) still do some kind of basic input validation such as checking for null values, empty strings, values out of range, etc, but core business logic checks should be shipped off to the service.

Drew Marsh
Hi Drew, thanks for your response. I had considered something similar - and I appreciated the value of validating server side too. However, the point behind this was to come up with a more creative way to limit the amount of data going through WCF - hence, offering the validation client side first, rather than have them submit it just to fail. If I exposed the validation functions, I would need one for each type of object and it would still have to go over the wire - so ideally, I was hoping there was some way to share the validation code so both could use it.
MrCraze
Well there's no way to share behavior unless you create an assembly that contains your data contracts along with these helper methods and give that out to your clients. It's not the "pure" way to do it from a pure SOA perspective (not gonna help if it's Java/PHP/Ruby on the other side, ya know?), but if this is an internal service and you can control the assembly that the clients use to communicate with your service then you can guarantee that they'll using the latest and greatest validation logic as well.
Drew Marsh
+1  A: 

If you control both sides of the wire, i.e. the server-side (service) and the client-side, then you could do the following:

  • put all your service and data contracts into a shared assembly
  • reference that "Contracts" assembly from both the server and the client
  • manually create the client proxy (by deriving from ClientBase<T> or by creating it from a ChannelFactory<T>) - do not use "Add Service Reference" or svcutil.exe!
  • put all validation logic into a shared assembly
  • reference that shared validation assembly from both projects

If you want to use a shared validation assembly, you must make sure the data types used on your server and client are identical - this can only be accomplished if you also share service and data contracts. Unfortunately, that requires manual creation of the client proxy (which is really not a big deal!).

If you'd use "Add Service Reference", then Visual Studio will inspect the service based on its metadata, and create a new set of client-side objects, which look the same in terms of their fields and all, but they're a separate, distinct type, and thus you wouldn't be able to use your shared validation on both the server-side and the client-side objects.

marc_s