Posted by: Cirilo Meggiolaro | 04/26/2009

Tip of the day #194 – ASP.NET MVC – UI Validation with the IDataErrorInfo interface

Let’s check today how to implement basic input validation on a ASP.NET MVC view using the IDataErrorInfo interface. This is not a new interface. Actually it’s been available since the version 1.x of .NET framework. Checking the elements that the interface defines we are going to find basically two properties:

  • string Error: Gets an error message indicating what is wrong with an object;
  • string this[string columnName]: Gets an error message for a specific property.

Bringing the interface to ASP.NET MVC world we are going to realize something interesting. When you implement it to a class that is a View Type, the indexer defined in the interface will be called for each property when the bind between the input fields and the model properties happens. At this moment you can trigger any kind of validation you want and retrieve an error message if something goes wrong.

How to…

  • Create a new ASP.NET MVC Web Application;
  • Right-click the Controllers folder and select Add > Controller. Name it SupplierController and mark the checkbox to create the skeleton for basic operations such as Create and Details;
  • Right-click the Models folder and select Add > Class. Name it SupplierModelView and click OK;
  • Add three properties to your class to store a numeric identifier, the supplier’s name and a flag that indicates whether the supplier is active or not. The class will be similar to the following:

public class SupplierModelView
{
    public int ID { get; set; }
    public string Name { get; set; }
    public bool Active { get; set; }
}

  • Create a strongly-typed View based on the previous model view that will be used during the input of a new Supplier. To achieve that, put the cursor on the Create action method available on the SupplierController class right-click it and select Add View or just press ctrl + M, V on the keyboard. The AddView dialog is displayed:

Picture 1 - Add View Dialog

Picture 1 - Add View Dialog

  • Mark the option to create a strongly-typed view and from the dropdownlist select the SupplierModelView class we’ve just created. Also select Create from the View content dropdownlist and click Add;
  • Open the SupplierController class and find the Create action method responsible for the Post action (the one that accepts a FormCollection object as parameter);
  • Change its signature to receive an instance of the SupplierModelView class instead;
  • Add a check to the ModelState.IsValid property that defines whether the parameter supplied is valid or not. The action method is similar to the following at this point:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(SupplierModelView supplier)
{
    if (ModelState.IsValid)
    {
        […] Save to the database.

        /// Redirects to the index action.
        return RedirectToAction(“Index”);
    }

    return View();
}

  • If you run the application and navigate to the url http://localhost/Supplier/Create and just hit the Create button the ModelState.IsValid will return true on the action method. It means that nothing is being validated so far;
  • Let’s add our validation to the SupplierViewModel class by implementing the IDataErrorInfo interface. We will need a dictionary that stores the property name and the error message if any. The following code shows our SupplierViewModel with the interface implemented. The code is commented and is self-explanatory:

public class SupplierModelView : IDataErrorInfo
{
    public int ID { get; set; }
    public string Name { get; set; }
    public bool Active { get; set; }

    /// <summary>
    /// Stores the error messages.
    /// </summary>

    private Dictionary<string, string> _errors = new Dictionary<string,string>();

    /// <summary>
    /// Requested just once, returns
    /// a general error message.
    /// </summary>

    public string Error
    {
        get
        {
            return string.Empty;
        }
    }

    public string this[string propertyName]
    {
        get
        {
            /// Validates a specific property.
            Validate(propertyName);

            /// If any error message related to
            /// the property passed as parameter
            /// is found the error message is retrieved

            if (_errors.ContainsKey(propertyName))
                return _errors[propertyName];

            return string.Empty;
        }
    }

    /// <summary>
    /// Validates the content of a property.
    /// If any operation stopper is found
    /// an error message is added to the
    /// dictionary.
    /// </summary>
    /// <param name=”propertyName”>Property name</param>
    
public void Validate(string propertyName)
    {
        switch (propertyName)
        {
            case “Name”:
                if (string.IsNullOrEmpty(this.Name))
                    this._errors[“Name”] = “The supplier name is required.”;
            break;
        default:
            break;
        }
    }
}

  • Run the application and navigate again to the url http://localhost/Supplier/Create and just hit the Create button. This time an error message is shown describing that the supplier name is required and the operation is cancelled. It happens because the property IsValid from the ModelState internally will consider if at least one item is available in the error dictionary based on the indexer implemented via IDataErrorInfo interface:

Picture 2 - Validation result

Picture 2 - Validation result

For more information about UI validation, check the Tip #184


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: