Shouldn’t validating a checkbox be easier than this?

by Michael Ciba 6. April 2011 08:51

 

Well it's been a while since I have done a post but with changing jobs recently and life in general getting in the way I just couldn’t seem to find the time. However, now I have a spare five minutes I thought I would fire off a post :)

So what's the post about? Validating a checkbox web control. Now I know your reading this thinking that's easy all you need is a custom validator and a event handler in your code behind and job done? Well in most cases yes I would agree with you. However, my latest project (a legacy application) uses code generation to create the vast majority of the ASP.NET pages and user controls. Therefore it’s difficult for me to include anything other than the standard set of ASP.NET validators or something which inherits off the “BaseValidator” and get it working correctly in the XSLT templates generating the code. Because of this I decided to create my own validator for the checkbox web control.

So how do we get started? Well first off you need to inherit off the “BaseValidator” and then override the required "EvaluateIsValid" method. Once done you can then write some simple logic to ensure your checkbox has been checked. As shown below.

   1:  public class CheckBoxValidator : BaseValidator
   2:  {
   3:      protected override bool EvaluateIsValid()
   4:      {
   5:          var controlValue = this.GetControlValidationValue(this.ControlToValidate);
   6:          bool checkBoxValue;
   7:          var hasBeenParsed = bool.TryParse(controlValue, out checkBoxValue);
   8:   
   9:          var result = hasBeenParsed && checkBoxValue;
  10:          return result;
  11:      }
  12:  }

 

So is that it all done? Well no because the out of the box checkbox control is missing an important thing. The "ValidationProperty" attribute. This attribute is used within the base validator to work out which property on the control being validated should to used when getting the control validation value. In order to solve this problem you will need to create your own version of the checkbox control by inheriting from it and adding the required attribute as shown below.

   1:  [ValidationProperty("Checked")]
   2:  public class ValidationCheckBox : CheckBox
   3:  {
   4:  }

 

Ok so now we have our own custom checkbox and checkbox validator we can finally validate those lovely checkboxes. However, if you recall from a bit earlier I said this is a legacy application and although it is to a large degree generated for me I'm not sure I really want to find all the places where a standard checkbox web control should be switched out for my super custom one. So what's the answer? Tag mapping.

Now tag mapping if you haven't heard of it before enables you to define within the web.config that tag "A" should instead be mapped to tag "B". You can see below how I used it to always return my custom checkbox whether a standard asp.net checkbox should be used.

  1: <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID">
  2:   <tagMapping>
  3:     <add tagType="System.Web.UI.WebControls.CheckBox" mappedTagType="Demo.Web.Code.Controls.ValidationCheckBox" />
  4:   </tagMapping>
  5: </pages>
Now that’s done I don’t have to change a single line of code to get my new checkbox control in place and get my validations working. One finial point though or really a question is why haven’t Microsoft just created this type of validator and given it to me straight out of the box? Yes I know I could change the checkbox to some radio buttons to achieve a similar thing, but sometimes I don’t get the finial say in the design of a page and this type of validator would come in handy I think for a lot of people.
Tags:
Categories: ASP.NET | C# | VS2010 | IIS

Bob the builder

by Michael Ciba 5. November 2010 22:43

I recently started a new project which is very focused on having good test coverage which is great goal to have.  However, looking through their tests I started to notice a lot of setup code which was very similar and looked a lot like the following:

   1: [TestMethod]
   2: public void WhenTheAddressRepositoryIsAskedToAPersistAddressesItShouldCorrectlyPersistThoseAddresses()
   3: {
   4:     // Arrange
   5:     var addressesToPersist = new List<Address>();
   6:  
   7:     var address = new Address
   8:                           {
   9:                               AddressLine1 = Guid.NewGuid().ToString(),
  10:                               AddressLine2 = Guid.NewGuid().ToString(),
  11:                               AddressLine3 = Guid.NewGuid().ToString(),
  12:                               AddressLine4 = Guid.NewGuid().ToString(),
  13:                               City = Guid.NewGuid().ToString(),
  14:                               County = Guid.NewGuid().ToString(),
  15:                               CountryCode = Guid.NewGuid().ToString(),
  16:                               Postcode = Guid.NewGuid().ToString()
  17:                           };
  18:     addressesToPersist.Add(address);
  19:  
  20:     var address1 = new Address
  21:                            {
  22:                                AddressLine1 = Guid.NewGuid().ToString(),
  23:                                AddressLine2 = Guid.NewGuid().ToString(),
  24:                                AddressLine3 = Guid.NewGuid().ToString(),
  25:                                AddressLine4 = Guid.NewGuid().ToString(),
  26:                                City = Guid.NewGuid().ToString(),
  27:                                County = Guid.NewGuid().ToString(),
  28:                                CountryCode = Guid.NewGuid().ToString(),
  29:                                Postcode = Guid.NewGuid().ToString()
  30:                            };
  31:     addressesToPersist.Add(address1);
  32:  
  33:     var addressRepository = new AddressRepository();
  34:     
  35:     // Act
  36:     addressRepository.Persist(addressesToPersist);
  37:     var actualPersistedAddresses = addressRepository.GetAll();
  38:     
  39:     // Assert
  40:     Assert.IsNotNull(actualPersistedAddresses);
  41:     Assert.AreEqual(2, actualPersistedAddresses.Count);
  42: }

Now the above code isn’t all that bad in a single test but what happens when you start to write more tests?  Well you could copy and paste the code for creating addresses from test to test which will certainly work but you end up with a lot of very similar code which you have to maintain going forward and update whenever a new address property is added or removed.  All this sounds like a lot of work plus it goes against the DRY principle.  DRY for those of you who don’t know means “Don’t Repeat Yourself”.  The principle encourages that duplication within an application is removed as every line of  code written has to be maintained and each line of code can cause bugs. More importantly the principle is about having a single source of knowledge within a system and then using that source to generate instances of that knowledge. In this case the instances of knowledge would be the address objects which are being created within each unit test.  The question then is how do we create something which we can use as the source of that knowledge?

Enter the builder

That single source of knowledge within the project I’m working on is provided by using the object builder pattern. Using this pattern we can have a single and consistent approach to creating the entities within tests and the ability to easily extend those entities within our domain and test data. We can also chain the builders together to create complex test data very quickly.

So how do you create a builder? Well below is my implementation of an address builder to get you going.

   1: public class AddressBuilder : BuilderBase<AddressBuilder, Address>
   2: {
   3:     private int id;
   4:     private string addressLine1 = GetUniqueValueFor();
   5:     private string addressLine2 = GetUniqueValueFor();
   6:     private string addressLine3 = GetUniqueValueFor();
   7:     private string addressLine4 = GetUniqueValueFor();
   8:     private string city = GetUniqueValueFor();
   9:     private string countryCode = "GB";
  10:     private string postCode = "SE1 9EU";
  11:     private string county = "London";
  12:  
  13:     public AddressBuilder WithId(int id)
  14:     {
  15:         this.id = id;
  16:         return this;
  17:     }
  18:    
  19:     public AddressBuilder WithAddressLine1(string addressLine1)
  20:     {
  21:         this.addressLine1 = addressLine1;
  22:         return this;
  23:     }
  24:  
  25:     public AddressBuilder WithAddressLine2(string addressLine2)
  26:     {
  27:         this.addressLine2 = addressLine2;
  28:         return this;
  29:     }
  30:  
  31:     public AddressBuilder WithAddressLine3(string addressLine3)
  32:     {
  33:         this.addressLine3 = addressLine3;
  34:         return this;
  35:     }
  36:  
  37:     public AddressBuilder WithAddressLine4(string addressLine4)
  38:     {
  39:         this.addressLine4 = addressLine4;
  40:         return this;
  41:     }
  42:  
  43:     public AddressBuilder WithCity(string city)
  44:     {
  45:         this.city = city;
  46:         return this;
  47:     }
  48:  
  49:     public AddressBuilder WithCountry(string countryCode)
  50:     {
  51:         this.countryCode = countryCode;
  52:         return this;
  53:     }
  54:  
  55:     public AddressBuilder WithPostCode(string postCode)
  56:     {
  57:         this.postCode = postCode;
  58:         return this;
  59:     }
  60:  
  61:     public AddressBuilder WithCounty(string county)
  62:     {
  63:         this.county = county;
  64:         return this;
  65:     }
  66:  
  67:     public override Address Build()
  68:     {
  69:         var address = new Address
  70:                           {
  71:                               Id = this.id,
  72:                               AddressLine1 = this.addressLine1,
  73:                               AddressLine2 = this.addressLine2,
  74:                               AddressLine3 = this.addressLine3,
  75:                               AddressLine4 = this.addressLine4,
  76:                               City = this.city,
  77:                               CountryCode = this.countryCode,
  78:                               County = this.county,
  79:                               Postcode = this.postCode
  80:                           };
  81:  
  82:         return address;
  83:     }
  84: }

As you can see the code behind the builder is really very simple with default values assigned to the properties which can then be explicitly set using the “With” methods on the builder. When I’m using builders I also like to add a base for them which provides default behaviour.

   1: public abstract class BuilderBase<TBuilder, TBuild> where TBuilder : BuilderBase<TBuilder, TBuild>
   2: {
   3:     /// <summary>
   4:     /// Builds this instance.
   5:     /// </summary>
   6:     /// <returns></returns>
   7:     public abstract TBuild Build();
   8:  
   9:     /// <summary>
  10:     /// Builds the many.
  11:     /// </summary>
  12:     /// <param name="number">The number.</param>
  13:     /// <returns></returns>
  14:     public List<TBuild> BuildMany(int number)
  15:     {
  16:         var result = new List<TBuild>();
  17:  
  18:         for (int i = 0; i < number; i++)
  19:         {
  20:             var builtItem = this.Build();
  21:             result.Add(builtItem);
  22:         }
  23:  
  24:         return result;
  25:     }
  26:  
  27:     /// <summary>
  28:     /// Gets the unique value for.
  29:     /// </summary>
  30:     /// <returns></returns>
  31:     protected static string GetUniqueValueFor()
  32:     {
  33:         return Guid.NewGuid().ToString();
  34:     }
  35: }

So now we have the address builder this put it all together to create our new and improved unit test.

   1: [TestMethod]
   2: public void WhenTheAddressRepositoryIsAskedToAPersistAddressesItShouldCorrectlyPersistThoseAddresses()
   3: {
   4:     // Arrange
   5:     var addressesToPersist = new AddressBuilder().BuildMany(2);
   6:     var addressRepository = new AddressRepository();
   7:     
   8:     // Act
   9:     addressRepository.Persist(addressesToPersist);
  10:     var actualPersistedAddresses = addressRepository.GetAll();
  11:     
  12:     // Assert
  13:     Assert.IsNotNull(actualPersistedAddresses);
  14:     Assert.AreEqual(2, actualPersistedAddresses.Count);
  15: }

As you can see the duplicate code for creating each address is now gone and we have a nice simple method for creating as many address as we want using the “BuildMany” method provided by the base builder. Well that’s it for now. The complete source code for this example can be found at http://cid-468e9f9e14e99f80.office.live.com/self.aspx/.Public/Blog.Builders.zip

Trouble using the AdvancedFilterSet with the “whenCreated” active directory property

by Michael Ciba 25. April 2010 06:19

Over the last couple of days on my current project I have been working with the new account management API found in .NET 3.5 for communicating with active directory. This API is a massive improvement over the features provided by the older directory services and really does make creating, deleting, updating and finding users a lot simpler (for more information checkout http://msdn.microsoft.com/en-us/library/bb299745%28v=VS.100%29.aspx).

As part of the work I needed to provide the ability to find users based on the date they were created so following the approach on MSDN (see http://msdn.microsoft.com/en-us/library/bb384372.aspx) I extended the “AdvancedFilters” class and added my own method for setting a filter for a query using the active directory property “whenCreated”. I should say this property stores the date and time a user is created with AD. Now the code shown below is what I first came up with and it looks like it will do the job right?

  1: public class SearchFilter : AdvancedFilters
  2: {
  3:     /// <summary>
  4:     /// Initializes a new instance of the <see cref="SearchFilter"/> class.
  5:     /// </summary>
  6:     /// <param name="p"></param>
  7:     public SearchFilter(Principal p) : base(p)
  8:     {
  9:     }
 10: 
 11:     public void Created(DateTime? created, MatchType matchType)
 12:     {
 13:        if (!created.HasValue) return;
 14:          AdvancedFilterSet("whenCreated", created.Value, typeof(DateTime), matchType);
 15:     }
 16: }
 17: 

Well sadly no. As it turns out the “whenCreated” property in AD is stored as a string in the generalised time format (see http://msdn.microsoft.com/en-us/library/ms680924%28VS.85%29.aspx). Because of this telling the advanced filter set that it’s a date just doesn’t work and you will find as I did no results are returned. So how do you get this to work then? Well all we need to do is update our “Created” method a bit so the advanced filter set thinks it is dealing with a string and then just pass in the date in the correct generalised date format which is “yyyyMMddHHmmss.0Z”.

[Updated code which now correctly sets the type and formats it]
  1: public void Created(DateTime? created, MatchType matchType)
  2: {
  3:    const string WhenCreatedDateFormat = "yyyyMMddHHmmss.0Z";
  4: 
  5:    if (!created.HasValue) return;
  6:    AdvancedFilterSet(ClientUser.WhenCreatedPropertyName,
  7:    created.Value.ToUniversalTime().ToString(WhenCreatedDateFormat), typeof (string), matchType);
  8: }

Once you do this your query filter will spring into life and happily return you results. Well that’s it for now.

Tags:
Categories: C# | AD

Dependency Injection in SharePoint with Ninject

by Michael Ciba 20. April 2010 07:46

 

A while ago I was having a discussion with one of my fellow developers at EMC Consulting about SharePoint and getting dependency injection working with it. Well finally after a few weeks I have found the time to produce a quick example of just how easy it is to get dependency injection working in SharePoint using a great tool called Ninject. You can find additional information about Ninject at http://ninject.org/. So this get started!
First off Ninject works by providing you with something it calls a kernel which it uses for returning an instance of a specific type. You can think about the kernel as a big brother to the factory pattern we all know and love. Because the kernel is so important the first things you need to do to get Ninject working in SharePoint is create an instance of a kernel and a simple way to do this in SharePoint is through the use of a HttpModule.

1:  public class SharePointNinjectHttpModule: IHttpModule, IDisposable
2:  {
3:         private readonly HttpApplication _httpApplication;
4: 
5:         public void Init(HttpApplication context)
6:         {
7:             if (context == null)
8:                 throw new ArgumentException("context");
9: 
10:             if(FrameworkHelper.Kernel == null)
11:             {
12:                 FrameworkHelper.Kernel = GetKernel();
13:             }
14:         }
15: 
16:         public void Dispose()
17:         {
18:             if(_httpApplication == null) return;
19:             _httpApplication.Dispose();
20:         }
21: 
22:         #region Private methods
23:         
24:         /// <summary>
25:         /// Gets the kernel.
26:         /// </summary>
27:         /// <returns></returns>
28:         private static IKernel GetKernel()
29:         {           
30:             IKernel result = new StandardKernel();
31:             result.Bind<IWarrior>().To<Samurai>();
32:             result.Bind<IWeapon>().To<Sword>();
33:             return result;
34:         }
35: 
36:         #endregion
37: }



As you can see from the code the module is very simple and straightforward and all it does is create an instance of the kernel and sets it's bindings so Ninject knows which instance of a type to return when a request for “IWarrior” or “IWeapon” is made. Remember that you will need to add an entry to the “httpModules” section of your web.config (see below) which in a real world application would be done using the SPWebConfigModification class. However, as this is just a demo I have added it by hand to save myself sometime.

1: <add name="SharePointNinjectHttpModule" type="Blog.IOC.Source.HttpModules.SharePointNinjectHttpModule,Blog.IOC, Version=1.0.0.0, Culture=neutral, PublicKeyToken=bf2ebb07a9bc44ba" />



Now to allow Ninject to actually do it's dependency injection magic there are a few things you must do. The first of these is to modify the “AssemblyInfo.cs” file for all of your projects (well the ones using Ninject at least) so they will allow partially trusted callers. If you don't do this then a security exception is thrown when you inject your object into the Ninject kernel.

1: using System.Security;
2: 
3: [assembly: AllowPartiallyTrustedCallers]



The next thing you need to do is inject the actual instance of the object you want Ninject to apply dependency injection to into the kernel you created. The way I did this was to create a number of base classes which inherit from commonly used items in SharePoint like Web Parts, User Controls and Application Pages. Then within the constructor for each base class I inject the instance of that object into the Ninject kernel.


This is the web part base class:

1: public abstract class WebPartBase : Microsoft.SharePoint.WebPartPages.WebPart
2: {
3:       protected WebPartBase()
4:       {
5:           FrameworkHelper.Kernel.Inject(this);
6:       }
7: }



This is the application page base class:

1: public class LayoutsBase : LayoutsPageBase
2: {
3:         protected LayoutsBase()
4:         {
5:             FrameworkHelper.Kernel.Inject(this);
6:         }
7: }



And finally the user control base class:

1: public abstract class UserControlBase : UserControl
2: {
3:         protected UserControlBase()
4:         {
5:             FrameworkHelper.Kernel.Inject(this);
6:         }
7: }



You can see all the bases classes shown below in the “Blog.IOC” project.

Blog.IOC.BaseClasses


Once you have done this Ninject will work and happily inject any dependencies you have marked up with the “[Inject]” attribute into your objects.

1: [Inject]
2: public IWarrior Warrior { get; set; }


So does this all work you ask? Well yes indeed it does and to prove it below is the code for a very simple application page which inherits off “LayoutsBase” and a screen shot of it’s rendered output.


[ Notice the use of the inject attribute on the Warrior property so Ninject knows this is something it is responsible for ]

1: public class BlogCustomApplicationPage : LayoutsBase
2: {
3:         protected Literal litWarrior;
4: 
5:         [Inject]
6:         public IWarrior Warrior { get; set; }
7: 
8:         protected override void OnLoad(EventArgs e)
9:         {
10:             base.OnLoad(e);
11: 
12:             SetUpWarrior();
13:         }
14: 
15:         private void SetUpWarrior()
16:         {
17:             litWarrior.Text = Warrior.Name;
18:         }
19: }



[ The fully rendered output ]
ApplicationPage


The full source code for the dependency injection example using Ninject can be download from: http://cid-468e9f9e14e99f80.skydrive.live.com/self.aspx/.Public/Blog.IOC.zip

PS. In order to get all this working you will need Visual Studio 2008, WSPBuilder and SharePoint 2007 enjoy :-)

Categories: ASP.NET | Ninject | Sharepoint