Creating Custom Data Source Parameters

Posted by: Aaron Goldenthal 8/9/2009 10:58 PM

I’m a fan of using the data source controls to simplify data access.  While there’s a reasonable set of Parameters that come with the framework, it’s easy to quickly get to a point where you want functionality that doesn’t automatically come from one of these parameters.  You can always use the Parameter and update the value programmatically, but you can end up with a lot of logic repeated in various Inserting/Updating/Deleting events.  Luckily, creating a custom data source Parameter to encapsulate this logic is very easy.

There’s a good article on 4Guys on Creating Custom Parameter Controls, which is where I learned this technique.  I’m going to go through a couple of examples quickly, feel free to refer to the 4Guys article for a more thorough discussion.

To implement a custom Parameter control you essentially need to do three things:

  • Provide an override for the Evaluate method.  This method returns the value of the Parameter.
  • Provide an override for the Clone method.  This method is used by the Visual Studio designer to make a deep copy of the Parameter.
  • Add any properties required to evaluate your Parameter.

To illustrate this, I’m going to walk through two custom Parameters that I use frequently: IdentityParameter and AppSettingParameter.

IdentityParameter

The IdentityParameter returns the name of the logged in user, specifically from HttpContext.Current.User.Identity.Name.  We’ll start with a basic skeleton for the IdentityParameter, which derives from Parameter.

   1: public class IdentityParameter : Parameter
   2: {
   3:     public IdentityParameter()
   4:     {
   5:     }
   6: }

For the IdentityParameter, I wanted the option to either include or exclude the domain name of the user since I have different applications that use both options.  So, we’ll add one property to the Parameter.

   1: [DefaultValue(true)]
   2: public bool IncludeDomain
   3: {
   4:     get
   5:     {
   6:         object o = ViewState["IncludeDomain"];
   7:         if (o == null)
   8:             return true;
   9:         else
  10:             return Convert.ToBoolean(o);
  11:     }
  12:     set
  13:     {
  14:         ViewState["IncludeDomain"] = value;
  15:     }
  16: }

All of this is pretty standard for a control property – the value is stored in ViewState so it persists between posts, and a default of true is specified.

Now, on to evaluating the value of the control.  The Evaluate method is passed two parameters – a reference to the current HttpContext, and a reference to the control that the Parameter object belongs to (SqlDataSource, ObjectDataSource, etc).

   1: protected override object Evaluate(HttpContext context, Control control)
   2: {
   3:     if ((context == null) || (context.User == null))
   4:         return null;
   5:     else
   6:     {
   7:         if (IncludeDomain)
   8:             return context.User.Identity.Name;
   9:         else
  10:         {
  11:             string name = context.User.Identity.Name;
  12:             return name.Substring(name.IndexOf("\\") + 1);
  13:         }
  14:     }
  15: }

We start by checking that the HttpContext and User are not null since these are required to obtain the Identity.  Then we simply return the name value as is, or with the domain stripped off, based on the value of the IncludeDomain property.

Finally, we need to override the Clone method.  With that, we’ll add a second constructor that is passed the current parameter.

   1: protected IdentityParameter(IdentityParameter original) : base(original)
   2: {
   3:     IncludeDomain = original.IncludeDomain;
   4: }
   5:  
   6: protected override Parameter Clone()
   7: {
   8:     return new IdentityParameter(this);
   9: }
  10:  

The new constructor simply calls the base constructor and copies any new properties (in this case IncludeDomain).  The Clone method returns a new IdentityParameter copied from the current parameter.

That’s all there is to it.  The IdentityParameter can now be added to any Parameter collection (with intellisense).

   1: <InsertParameters>
   2:     <adg:IdentityParameter Name="UserID" Type="String" />
   3: </InsertParameters>

AppSettingParameter

The AppSettingParameter returns the value of the AppSettings collection with the specified key.  Again we’ll start with a basic skeleton for the AppSettingParameter, which derives from Parameter.

   1: public class AppSettingParameter : Parameter
   2: {
   3:     public AppSettingParameter()
   4:     {
   5:     }
   6: }

For the AppSettingParameter, a key is required to access the appropriate value from the AppSettings collection, so we’ll add one property to the Parameter.

   1: public string Key
   2: {
   3:     get
   4:     {
   5:         return ViewState["Key"] as string;
   6:     }
   7:     set
   8:     {
   9:         ViewState["Key"] = value;
  10:     }
  11: }

Again, all of this is pretty standard for a control property, so we’ll move on the Evaluate method.

   1: protected override object Evaluate(HttpContext context, Control control)
   2: {
   3:     if (String.IsNullOrEmpty(this.Key))
   4:     {
   5:         throw new InvalidOperationException("A Key must be specified for an AppSettingParameter.");
   6:     }
   7:     else
   8:     {
   9:         return WebConfigurationManager.AppSettings[this.Key];
  10:     }
  11: }

Since we’re not using the HttpContext, we don’t need to check that it’s null, we simply check that a Key is specified and return the value from AppSettings.

Finally, we need to override the Clone method.  Again, we’ll add a second constructor that is passed the current parameter.

   1: protected AppSettingParameter(AppSettingParameter original) : base(original)
   2: {
   3:     Key = original.Key;
   4: }
   5:  
   6: protected override Parameter Clone()
   7: {
   8:     return new AppSettingParameter(this);
   9: }

The AppSettingParameter can now be added to any Parameter collection (with intellisense).

   1: <InsertParameters>
   2:     <adg:AppSettingParameter Name="Color" Type="String" Key="Color" />
   3: </InsertParameters>

The download below includes the complete source code as well as an example using both of these parameters.

Download sample website: CustomParameters.zip (171 kb)

Tags: ,
Categories: Data Controls
E-mail | Kick it! | DZone it! | del.icio.us Permalink | Comments (1) | Post RSSRSS comment feed

Comments (1) -


France assurance auto 
6/16/2012 7:53 AM
assurance auto
Wonderful, totally agree with you

Pingbacks and trackbacks (1)+