Monday, 21 January 2013

ASP.NET MVC Model Binding for Base Classes

In ASP.NET MVC, sometimes there is a need to have several model classes inheriting from a base model class. When all child classes share a common property from the base class, then it is useful to use model binders to bind a value to the shared properties.

Using ASP.NET MVC 4.0, in below snippets, the ProfileModelBase is the base class for AboutModel and BasicInfoModel classes.
    public class ProfileModelBase
    {
        public string UserName { get; set; }
    }

    public class AboutModel : ProfileModelBase
    {
        public string About { get; set; }
    }

    public class BasicInfoModel : ProfileModelBase
    {
        public DateTime Birthday { get; set; }

        public string FirstName { get; set; }

        public string LastName { get; set; }
    }

One solution to do the "Don't Repeat Yourself (DRY)" for above code is to use a model binder to assign a value to the UserName property using below code:

    public class ProfileModelBinder : DefaultModelBinder
    {
        protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            var userProfileBase = bindingContext.Model as ProfileModelBase;
            if (userProfileBase != null)
            {
                userProfileBase.UserName = controllerContext.HttpContext.User.Identity.Name;
            }

            base.OnModelUpdated(controllerContext, bindingContext);
        }
    }

In above code, I am using OnModelUpdate event to set the value of the UserName property. Using this model binder, our model classes will be:

    [ModelBinder(typeof(ProfileModelBinder))]
    public class AboutModel : ProfileModelBase
    {
        public string About { get; set; }
    }

    [ModelBinder(typeof(ProfileModelBinder))]
    public class BasicInfoModel : ProfileModelBase
    {
        public DateTime Birthday { get; set; }

        public string FirstName { get; set; }

        public string LastName { get; set; }
    }

That's it! No more repeating code.

Enjoy model binding!

5 comments:

  1. Men, you save the day for me, thanks!

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. What if I have base class and classes that derive from it and I bind on child classes but still need common data that is bound only in base class?


    ReplyDelete
  4. Thanks for sharing this valuable information, keep posting such good stuff.

    ReplyDelete