Using Validation Application Block with WSSF

Topics: Service Factory Modeling Edition Forum
Jan 8, 2008 at 10:53 PM
I'm currently building a web service using WSSF and I'm trying to integrate the Validation Application Block from the Enterprise Library. It's been pretty straightforward, but I ran into a problem. To report a validation fault I need to stick a FaultContract attribute on my operation, typeof ValidationFault. But from what I've seen my Faults have to be part of my project (in my data contract diagram), I can't reference the one in the VAB library and have the attribute generated. I could put the attribute in manually post generation, but it'll get wiped out next iteration and I'll forget, so I'd like to avoid that if possible. Suggestions? Thanks.
Developer
Jan 9, 2008 at 3:25 PM
You may create a partial class (same as the generated) but with the VAB attribute so it will not be wiped out with new code gens.
Jan 9, 2008 at 6:37 PM


charlyfriend wrote:
You may create a partial class (same as the generated) but with the VAB attribute so it will not be wiped out with new code gens.

I gave that a shot and it's not going to work. The docs say (and experimenting proves) that "if you want the client to receive relevant validation failure information, you must modify the service contract." What I observed is that when I modify the contract (interface) the generated proxy contains a ValidationFault class; if I don't modify the contract, it isn't there, and all I can catch is a general exception sans details.

Modifying the contract in a custom partial interface implementation won't work as, in order to attach an attribute, I'd have to declare the method, and I can't declare it in custom code and generated code.
Developer
Jan 11, 2008 at 1:49 PM
You can have a FaultContract defined in your DC model and then add a partial class that derives from ValidationFault like this:

using System;
using WcfSerialization = global::System.Runtime.Serialization;
using Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WCF;
 
namespace Wcf.FaultContracts
{
	public partial class FaultContract1 : ValidationFault
	{
	}
}
This assumes that you have a FaultContract element named "FaultContract1" and you may place this class outside the GeneratedCode folder.
This solution should work, otherwise you may still update the "Service Contract DSL\Dsl\TextTemplates\WCF\CS\ServiceContract.tt" file.
Feb 11, 2008 at 10:00 PM


charlyfriend wrote:
You can have a FaultContract defined in your DC model and then add a partial class that derives from ValidationFault like this:

using System;
using WcfSerialization = global::System.Runtime.Serialization;
using Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WCF;
 
namespace Wcf.FaultContracts
{
	public partial class FaultContract1 : ValidationFault
	{
	}
}
This assumes that you have a FaultContract element named "FaultContract1" and you may place this class outside the GeneratedCode folder.
This solution should work, otherwise you may still update the "Service Contract DSL\Dsl\TextTemplates\WCF\CS\ServiceContract.tt" file.



I understand your suggestion here and it will definitely help me out. I do have another related question though.

Today I posted another question to the Service Factory Modeling Edition (SFME) forum that is related to the question I'm about to ask. Briefly, my other post asks if the SFME modeler's use of message contracts for operation requests and responses implies that message contracts should always be used. If not, how do you use the modeler to specify a primitive type or a data contract in an operation? I understand that I may be missing something here regarding the use of the tool.

If I want to validate an incoming request message containing simple types and/or data contracts, how do I use the VAB to accomplish this task? If I take the attribute approach, I need to decorate the members of the message contract that I want to validate. Even though it is a partial class, I can't add an attribute to an existing property using a partial class. If I use the configuration file approach, I can't get at the properties of the message contract that I want to validate.

As I said in my other post, I hope I am missing something.

Thanks,
Brian
Feb 11, 2008 at 11:39 PM
Hi Brian,

I'm not an expert, but since I got through this VAB stuff successfully I can share what I learned. First, I didn't use the attribute approach for the reason you listed -- I can't add attributes thru the partial class. So I went with the config and I'm pleased with the results.

Validating message parameters is fairly straightforward and if you use the Enterprise Library editor it's pretty painless, except for the dialog box for picking the object to validate out of pretty much every .Net object on your machine. But once you identify the object, you add a rule, and within the rule add the properties to validate and the validation rule(s) to apply to each property. If the message contains a data contract and you want to validate those members you have to use an object validator on the property that is the data contract (in the message) and then add that (data contract) type into the config, with a rule, properties to validate, etc. Hope this helps.
Feb 13, 2008 at 2:20 AM


mikewiebel wrote:
Hi Brian,

I'm not an expert, but since I got through this VAB stuff successfully I can share what I learned. First, I didn't use the attribute approach for the reason you listed -- I can't add attributes thru the partial class. So I went with the config and I'm pleased with the results.

Validating message parameters is fairly straightforward and if you use the Enterprise Library editor it's pretty painless, except for the dialog box for picking the object to validate out of pretty much every .Net object on your machine. But once you identify the object, you add a rule, and within the rule add the properties to validate and the validation rule(s) to apply to each property. If the message contains a data contract and you want to validate those members you have to use an object validator on the property that is the data contract (in the message) and then add that (data contract) type into the config, with a rule, properties to validate, etc. Hope this helps.


Thanks Mike. I didn't think I could access the data contract inside the message. Or maybe I should say that I didn't know how.

Thanks again for the information.

-Brian
May 20, 2009 at 2:22 PM

Hi All,

Has someone found a solution to add the [FaultContract(typeof(ValidationFault))] attribute for a service contract operation without modifying generated classes (service contract interface)?

 

Thanks, Pavel

Developer
May 20, 2009 at 3:19 PM

If you try the config approach for VAB, then you may avoid the attribute scenario and therefore you will not need to do "tricks" on the service contract or update the template files.

You will find documentation in VAB on how to use the configurarion (metadata) approach. There is also the PIAB that will allow you to add other cross cutting concerns other than validation.

May 20, 2009 at 3:53 PM

I am using the config approach. How can I get a relevant validation failure information in this case (i.e. FaultException<ValidationFault> instead of the general FaultException)?

Developer
May 20, 2009 at 6:05 PM

You may find in the VAB Hands-on Lab Lab#13, a sample on how to use the WCF validation–integration feature of the application block.

You can use the provided starter solutions so you may complete the labs in the order you prefer.

May 21, 2009 at 6:59 AM
Edited May 21, 2009 at 7:38 AM

The Lab#13 requires specifying the [FaultContract(typeof(ValidationFault))] for the service operation to explicitly handle the FaultException for the ValidationFault in the client code.  In our case the service interface is generated by WSSF without the validation attribute for an operation. If you manually add the attribute, the next code generation removes it.

The question is how to connect a service operation with the ValidationFault.

Developer
May 22, 2009 at 1:14 PM

You can follow the suggestion above regarding deriving a Fault element (i.e. FaultContract1) from ValidationFault in your custom partial class so the generated code from element FaultContract1 won;t overwrite your custom partial class that derives from ValidationFault.

Tha way you will get the correct attribute on your operation defined in your SerivceContract. In this case, the attribute may end up with something like [FaultContract(typeof(FaultContract1))]  but that should work since your FaultContract1 now derives from ValidationFault in your custom partial class. 

May 22, 2009 at 2:43 PM

Adding the [FaultContract(typeof(FaultContract1))] attribute to an operation makes possible to catch a FaultException that contains a specific FaultContract, i.e. the FaultContract1.

But VAB generates the FaultException<ValidationFault>.  To catch this exception ValidationFault must derive from FaultContract1 in this case instead of the other way round.

Developer
May 26, 2009 at 11:34 AM

You are right. I wold suggest to take a look at the EntLib extensions here: http://www.codeplex.com/EntLibExtensionsWSSF that may give you validation using these extensions and also a more generic approach using Policy extensions here: http://www.codeplex.com/wssfcontrib/Release/ProjectReleases.aspx?ReleaseId=17476