Posts tagged ‘Extension Methods’

Extension Methods: Improving the quality of Life


Extension methods, such a simple idea that can totally make the small things in your application or at least the un-DRY portions of it cleaner.

AddModelError and Multiple ValidationResults

Here is a simple example (taken from a custom model binder):

foreach( var validationResult in validationResults )
{
  bindingContext.ModelState
    .AddModelError( validationResult.MemberNames.FirstOrDefault(), validationResult.ErrorMessage );
}

not too bad, but when working in a block of code where you might have a few instances of it you tend to see the noise a little bit.

How about a little reduction and also centralize some logic so your entire code base can leverage it?

bindingContext.ModelState.AddModelErrors(validationResults);

Now that everything you thought was upright in the world is all in question, ok, not really – not even close. In fact we’ve only saved three lines of code where such things are being used but I would argue if you try to keep small things like this in mind that over time your code base will start to reap the benefits.

Here is how I implemented the extension method. Your mileage may vary.

public static class ModelStateExtensions
{
    public static void AddModelErrors(this ModelStateDictionary values, IEnumerable<ValidationResult> validationResults)
    {
        foreach (var validationResult in validationResults)
            values.AddModelError(validationResult.MemberNames.FirstOrDefault(), validationResult.ErrorMessage);
    }
}
DataAnnotations and the Validator class

Another area that might not be Asp.net MVC specific is if you are using the DataAnnotaions directly on your models and you use the static Validator class to validation the model. In this case the TryValidateObject is being used for the bool that is returned from the operation.

ValidationContext validationContext = new ValidationContext( someEditModel, null, null );
List<ValidationResult> validationResults = new List<ValidationResult>();
bool isValid = Validator.TryValidateObject( someEditModel, validationContext, validationResults );
if( !isValid )
{
  //do something maybe ...
  bindingContext.ModelState.AddModelErrors(validationResults);
}

I think I prefer this a little more

List<ValidationResult> validationResults = someEditModel.ValidateAnnotations();
if( validationResults.Count() > 0 )
  bindingContext.ModelState.AddModelErrors(validationResults);

Where ValidateAnnotations is implemented as follows. Also you if you prefer to change the where this can be used you can change the accessibility or change what this method extends to limit it’s exposure.

public static class ValidationExtensions
{
    public static List<ValidationResult> ValidateAnnotations<T>(this T value) where T : class
    {
        if(value == null) return new List<ValidationResult>();

        var validationContext = new ValidationContext(value, null, null);
        var validationResults = new List<ValidationResult>();
        Validator.TryValidateObject(value, validationContext, validationResults, true);
        return validationResults;
    }
}

Hopefully these two little nuggets will help someone out. Both of these are just a means to end, where I think that end is a transformation to a code base even beyond simple changes like this. After all it is all about the journey not the destination.

Asp.net MVC Session State Extension Method

There are a few implementations of the conical wizard out there using Asp.net MVC.  SessionsI’m working on a project where we are needing one such wizard and we’re trying out using session state, not session skate, to keep the models that make up the larger data set persisted for the user until the final submission.

This will allow the user to go back to any of the stages and edit the information if needed.  There are are options but for now we’re testing driving this approach.

Inspired (dang near a complete duplicate) by Donn Felker’s ASP.NET MVC TempData Extension Methods I created one that uses HttpSessionStateBase.

    public static class SessionStateExtensions
    {
        public static void Put<T>(this HttpSessionStateBase httpSession, T value) where T : class
        {
            httpSession[typeof (T).FullName] = value;
        }

        public static void Put<T>(this HttpSessionStateBase httpSession, string key, T value) where T : class
        {
            httpSession[typeof (T).FullName + key] = value;
        }

        public static T Get<T>(this HttpSessionStateBase httpSession) where T : class
        {
            var o = (T) httpSession[typeof (T).FullName];
            return o == null ? null : o;
        }

        public static T Get<T>(this HttpSessionStateBase httpSession, string key) where T : class
        {
            var o = (T) httpSession[typeof (T).FullName + key];
            return o == null ? null : o;
        }
    }