Tuesday 13 December 2011

Automatically trim html controls in a asp.net mvc project

I have noticed over the years that users being users sometimes posts forms on a website that has leading or trailing spaces into the input controls. This I find is especially a problem when the user has copied and pasted an email/website address from a internet page or email. On the surface this might be OK but for me especially for email and website addresses when I display this back in a href then sometimes we get:-
- 'mailto:// email@email.com ' or
- href=' http://www.wildesoft.net '

So what I need to remember is to either a) trim before I send to the database or b) trim after I retrieve from the database. I for one prefer option one, better to keep the database correct rather than fixing output in the UI. But is there a way that we can do this for every html control that is posted? With asp.net MVC we can override the default model binder which performs a trim before the value gets to the action method on a controller.

All you need to do is to add the following class to your mvc project:-
public class TrimModelBinder : DefaultModelBinder
{
  protected override void SetProperty(
      ControllerContext controllerContext,
      ModelBindingContext bindingContext,
      PropertyDescriptor propertyDescriptor, object value)
  {
    if (propertyDescriptor.PropertyType == typeof(string))
    {
      var val = (string)value;
      if (!string.IsNullOrEmpty(val))
        val = stringValue.Trim();

      value = val;
    }

    base.SetProperty(controllerContext, bindingContext, 
        propertyDescriptor, value);
  }
}
Then in your application start up method:-
protected void Application_Start() {
  InitContainer();
  ...
  ModelBinders.Binders.DefaultBinder = new TrimModelBinder();
}
Now when a user keys in a leading or trailing space into any input control then the TrimModel binder kicks in and automatically removes it for you.

The only instance where this may be a problem is when a user has a leading or trailing space on their password.

10 comments:

  1. Nice job! It works very fine.
    Thanks a lot.

    ReplyDelete
  2. Excellent, glad it helps you out. Thanks for your comment

    ReplyDelete
  3. On line 12, what is stringValue? Undefined variable.

    ReplyDelete
    Replies
    1. Sorry was a bit hasty with that comment. Simply changed line 12 to:
      val = value.ToString().Trim();
      and all is well.

      Thanks for the article!

      Delete
  4. What about Password type string Property ? How we bifurcate with other string ?

    ReplyDelete
  5. hi did you read my last point. "The only instance where this may be a problem is when a user has a leading or trailing space on their password."

    ReplyDelete
    Replies
    1. I agree with you however this is helpful for ideal scenario where password field is not present but such application are rare or limited. So how we can take this to next level where password field can eliminate .....

      Delete
    2. 2 options:-

      1. live with it, when user enters password into registration or login space is ALWAYS removed hence user never need to know

      2. move it so each model (class) has a data attribute that trims

      It may be possible to have a data attribute on the password property that the trim ignores.

      HTH but you point is outside this post

      Delete
  6. Thanks for sharing this, but I have a problem using this code: On SetProperty I have this message: "No suitable method found to override". Do you know how fix this?

    Thanks!

    ReplyDelete
  7. what about the case, when the property is list of strings

    ReplyDelete