Not getting the Behaviour of PIAB

Topics: Policy Injection Application Block, Validation Application Block
Nov 25, 2010 at 5:28 AM

I have added the following configuration through configuration tool.

 

<validation>
      <type name="BOResumeTracker.RecruiterLoginInformationBO" assemblyName="BOResumeTracker, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
          <ruleset name="Validation Ruleset">
              <properties>
                  <property name="RecruiterID">
                      <validator type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.NotNullValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                          messageTemplateResourceType="" name="Not Null Validator" />
                  </property>
                  <property name="FirstName">
                      <validator type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.NotNullValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                          name="Not Null Validator" />
                  </property>
                  <property name="OfficeEmailID">
                      <validator type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.NotNullValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                          name="Not Null Validator" />
                  </property>
                  <property name="MiddleName">
                      <validator type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.NotNullValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                          messageTemplateResourceType="" name="Not Null Validator" />
                  </property>
              </properties>
          </ruleset>
      </type>
      <type name="BALResumeTracker.RecruiterLogionInformationBL" assemblyName="BALResumeTracker, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  </validation>
  <policyInjection>
      <policies>
          <add name="My Policy">
              <matchingRules>
                  <add type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.MatchingRules.PropertyMatchingRule, Microsoft.Practices.EnterpriseLibrary.PolicyInjection, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                      name="Property Matching Rule">
                      <matches>
                          <add match="BOResumeTracker.RecruiterLoginInformationBO.FirstName"
                              ignoreCase="true" />
                          <add match="BOResumeTracker.RecruiterLoginInformationBO.LastName"
                              ignoreCase="true" />
                          <add match="BOResumeTracker.RecruiterLoginInformationBO.MiddleName"
                              ignoreCase="true" />
                      </matches>
                  </add>
                  <add type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.MatchingRules.MethodSignatureMatchingRule, Microsoft.Practices.EnterpriseLibrary.PolicyInjection, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                      match="AddRecruiterInformation" ignoreCase="true" name="Method Signature Matching Rule">
                      <parameters>
                          <parameter name="obj" typeName="BOResumeTracker.RecruiterLoginInformationBO, BOResumeTracker, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
                      </parameters>
                  </add>
                  <add type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.MatchingRules.MemberNameMatchingRule, Microsoft.Practices.EnterpriseLibrary.PolicyInjection, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                      name="Member Name Matching Rule">
                      <matches>
                          <add match="AddRecruiterInformation" ignoreCase="true" />
                      </matches>
                  </add>
              </matchingRules>
              <handlers>
                  <add type="Microsoft.Practices.EnterpriseLibrary.Validation.PolicyInjection.ValidationCallHandler, Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                      ruleSet="Validation Ruleset" specificationSource="Both" name="Validation Call Handler" />
              </handlers>
          </add>
      </policies>
  </policyInjection>

 

And i defined a object of my BO through Policy Injection Factory by creating a proxy like :

 

RecruiterLoginInformationBO obj = PolicyInjection.Wrap<RecruiterLoginInformationBO>(RecruiterBO);

 

So as the Middle Name Propery is Null so it should throw an exception on creating a object but it is not doing that???

 

I want to validate some properties and method's at the time of Object creation and calling methods. So how could i do that???

Nov 25, 2010 at 6:01 AM

First, matching rules are all evaluated before the call handlers are applied and those matching rules should all evaluate to true.  Thus in you case, it won't be able to intercept anything since you combined all the matching rules for the property and methods in a single policy.  You should separate them into three (3) policies.  Next, call handlers are applied during gettting/setting a property value and calling the method you configured to be intercepted.  Thus, when you this line of code executes

RecruiterLoginInformationBO obj = PolicyInjection.Wrap<RecruiterLoginInformationBO>(RecruiterBO);

the validation call handler won't get fired even if your existing RecruiterBO object has invalid values for its properties.  One limitation of PIAB is that it can't intercept constructors so it's not possible to have a call handler execute during object creation.   They only get fired when getting/setting properties and during method call.

 

Sarah Urmeneta
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

Nov 25, 2010 at 6:42 AM

I have already done that and getting a proxy object. But when i am getting or setting the property it is not throwing an exception. But when i am validating it explicitly it is giving me the result. So how this can be possible if i am using a proxy object it should validate the property when the value is fetched through get method or assigned to set method.

 

                RecruiterLoginInformationBO obj = PolicyInjection.Create<RecruiterLoginInformationBO>();
                obj.FirstName = "Jaspal Singh Ahluwalia";
                obj.MiddleName = string.Empty; 
                ValidationResults result = Validation.Validate(obj, "Validation Ruleset");

 

I hae changed the configuration as:

<validation>
      <type name="BOResumeTracker.RecruiterLoginInformationBO" defaultRuleset=""
          assemblyName="BOResumeTracker, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
          <ruleset name="Validation Ruleset">
              <properties>
                  <property name="FirstName">
                      <validator type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.StringLengthValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                          upperBound="5" messageTemplate="String is Out of Range" name="String Length Validator" />
                  </property>
                  <property name="MiddleName">
                      <validator type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.NotNullValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                          messageTemplateResourceType="" name="Not Null Validator" />
                  </property>
              </properties>
          </ruleset>
      </type>
  </validation>
  <policyInjection>
      <policies>
          <add name="My Policy">
              <matchingRules>
                  <add type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.MatchingRules.PropertyMatchingRule, Microsoft.Practices.EnterpriseLibrary.PolicyInjection, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                      name="Property Matching Rule">
                      <matches>
                          <add matchOption="GetOrSet" match="FirstName" ignoreCase="true" />
                          <add matchOption="GetOrSet" match="MiddleName" ignoreCase="true" />
                      </matches>
                  </add>
              </matchingRules>
              <handlers>
                  <add type="Microsoft.Practices.EnterpriseLibrary.Validation.PolicyInjection.ValidationCallHandler, Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                      ruleSet="Validation Ruleset" specificationSource="Configuration"
                      order="1" name="Validation Call Handler" />
              </handlers>
          </add>
      </policies>
  </policyInjection>

 

From this configuration i am getting the proxy object but when i am assigning the values to

 

FirstName and lastName it is not throwing the exception.

 

Why it is so????

Nov 25, 2010 at 7:02 AM
Edited Nov 25, 2010 at 7:03 AM

Ah, I forgot one more thing regarding on how the Property Matching Rule works.  Please see my first reply in this thread.



 

Sarah Urmeneta
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

Nov 25, 2010 at 7:12 AM

Sarah I have done all the things. I am getting a proxy object. But it is not validating as i am setting the values or getting the values.

it should throw an error as i will set the FirstName and crosses the string length limit but its not doing that.

 

So what should i do???

Nov 25, 2010 at 7:17 AM

Did you read my explanation in the link I posted?  You don't get the expected validation errors because the "Validation Ruleset" rule set is configured for the RecruiterLoginInformationBO type.  The Property Matching Rule expects a rule set configured for the type it matches which in your case is of type string.  What you could do is configure a rule set for each property of type string and adding the necessary validators.  I gave a sample config for this in the link to the thread I mentioned previously.

 

Sarah Urmeneta
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

Nov 25, 2010 at 8:01 AM

I have added the Validation Rule for String Also and specified the rule set in the PIAB but its not still working.

 

Following is the configuration:

 

<validation>
      <type name="BOResumeTracker.RecruiterLoginInformationBO" defaultRuleset=""
          assemblyName="BOResumeTracker, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
          <ruleset name="Validation Ruleset">
              <properties>
                  <property name="FirstName">
                      <validator type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.StringLengthValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                          upperBound="5" messageTemplate="String is Out of Range" name="String Length Validator" />
                  </property>
                  <property name="MiddleName">
                      <validator type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.NotNullValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                          negated="true" messageTemplateResourceType="" name="Not Null Validator" />
                  </property>
              </properties>
          </ruleset>
      </type>
      <type name="System.String" defaultRuleset="StringLengthRuleSet"
          assemblyName="mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
          <ruleset name="StringLengthRuleSet">
              <properties>
                  <property name="FirstName">
                      <validator type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.StringLengthValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                          upperBound="5" messageTemplate="String Lenght Is Out of Range"
                          name="String Length Validator" />
                  </property>
                  <property name="MiddleName">
                      <validator type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.NotNullValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                          messageTemplate="Middle Name Should Not be Null." name="Not Null Validator" />
                  </property>
              </properties>
          </ruleset>
      </type>
  </validation>
  <policyInjection>
      <policies>
          <add name="My Policy">
              <matchingRules>
                  <add type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.MatchingRules.PropertyMatchingRule, Microsoft.Practices.EnterpriseLibrary.PolicyInjection, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                      name="Property Matching Rule">
                      <matches>
                          <add matchOption="Set" match="FirstName" ignoreCase="true" />
                          <add matchOption="Set" match="MiddleName" ignoreCase="true" />
                      </matches>
                  </add>
              </matchingRules>
              <handlers>
                  <add type="Microsoft.Practices.EnterpriseLibrary.Validation.PolicyInjection.ValidationCallHandler, Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                      ruleSet="StringLengthRuleSet" specificationSource="Configuration"
                      order="0" name="Validation Call Handler" />
              </handlers>
          </add>
      </policies>
  </policyInjection>

 

Now tell me what should i do. And I am setting the propert as:


                RecruiterLoginInformationBO obj = PolicyInjection.Create<RecruiterLoginInformationBO>();
                obj.FirstName = "Jaspal Singh Ahluwalia";
                obj.MiddleName = string.Empty;
                ValidationResults result = Validation.Validate(obj, "StringLengthRuleSet");

 

So how should i do that .....??????

Nov 25, 2010 at 8:14 AM

That's because you configured the FirstName and MiddleName as properties for the type System.String in the StringLengthRuleSet but String has no such properties.  In my example in the other thread, I configured the validators for the ToString method.  Here's how yours should be like:

<validation>
<type name="System.String" defaultRuleset="FirstNameRuleSet"
   assemblyName="mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
       <ruleset name="FirstNameRuleSet">
             <methods>
                  <method name="ToString">
                      <validator type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.StringLengthValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                          upperBound="5" messageTemplate="String Lenght Is Out of Range"
                          name="String Length Validator" />
                  </method>
             </methods>
      </ruleset>
      <ruleset name="MiddleNameRuleSet">
	     <methods>
                  <method name="ToString">
		      <validator type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.NotNullValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                          messageTemplate="Middle Name Should Not be Null." name="Not Null Validator" />

		  </method>
	     </methods>
      </ruleset>
</type>
</validation>

You need then to define two policies in the policyInjection section: one for the FirstName property, another one for the MiddleName property.

Sarah Urmeneta
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

Nov 25, 2010 at 8:59 AM
Edited Nov 25, 2010 at 9:09 AM

Thank you Sarah its working now.

 

I have another query that how we can validate a method through this.

This has been already posted on the link given below:

http://entlibcontrib.codeplex.com/Thread/View.aspx?ThreadId=234855

 

Or we can say that how we can validate the parameters passed in the method. The parameter can be a BO.

 

Can you send me a example.

Nov 25, 2010 at 9:18 AM

I think you're already on the right track based on the first version of the config you posted aside from the fact that you should separate each matching rule for each method you want to intercept on different policies.  For example if have a RecruitementService class which has a AddRecruiterInformation method:

public class RecruitementService : MarshalByObject
{
        public void AdddRecruiterInformation(RecruiterLoginInformationBO recruiterLogin)
        {
                  //some codes here
        }
}

and you want to validate the recruiterLogin parameter, you can define a Member Name Matching Rule in a policy like this:

<add name="My Policy">
    <matchingRules>
     <add type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.MatchingRules.MemberNameMatchingRule, Microsoft.Practices.EnterpriseLibrary.PolicyInjection, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
      name="Member Name Matching Rule">
      <matches>
       <add match="AddRecruiterInformation" ignoreCase="true" />
      </matches>
     </add>
    </matchingRules>
    <handlers>
     <add type="Microsoft.Practices.EnterpriseLibrary.Validation.PolicyInjection.ValidationCallHandler, Microsoft.Practices.EnterpriseLibrary.Validation, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
      ruleSet="Validation Rule Set" specificationSource="Both" name="Validation Call Handler" />
    </handlers>
</add>
 

Hope this helps.

 

Sarah Urmeneta
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

Nov 25, 2010 at 9:19 AM

And Sarah As the code works but how will i get the message that i have given in the message template as i am catching the exception in Catch Block.

Nov 25, 2010 at 9:22 AM

Ok sarah but can you just post a sample code for validating a Method on the link given below:

 

http://entlibcontrib.codeplex.com/Thread/View.aspx?ThreadId=234855

Nov 25, 2010 at 9:41 AM

In your previous post, you mentioned that the code works, but in your latest post, you're asking for a sample code.  You only need to create the instance of the class using PolicyInjection.Create or PolicyInjection.Wrap and call the method.  Validation will automatically be performed just like what you did in your FirstName and MiddleName properties.

On how to get the validation message, catch for an ArgumentValidationException rather than the generic Exception type.  The validation errors can be found in the ValidationResults property.

try
{
     RecruitmentService service = PolicyInjection.Create();
     service.AddRecruiterInformation(recruiterInformation);
}
catch(ArgumentValidationException argValEx)
{
     //iterate through the argValEx.ValidationResults property
}

 

Sarah Urmeneta
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

Nov 25, 2010 at 10:05 AM

Thanks Sarah, it started working.

 

Can you just solve the other problem also?

Nov 25, 2010 at 10:08 AM

Which one?  If you're pertaining to the thread in the entlib contrib, my understanding is you want to validate method parameters and that's exactly what my previous answers were about. 

BTW, please create a new thread for different topics.

 

Sarah Urmeneta
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

Nov 25, 2010 at 10:14 AM

That is a different thread and the link is given below:

 

http://entlibcontrib.codeplex.com/Thread/View.aspx?ThreadId=234855

Nov 25, 2010 at 10:30 AM

My understanding is that the answer I've given here is also  the answer to that thread.  Do you  need me to specifically post my answer in that thread?  Or if it's a different question, which is not obvious to me, please create a new discussion for that in a new thread in this forum.

 

Sarah Urmeneta
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com