Monthly Archives: October 2015

Custom Property Binding in ASP.NET MVC

IPropertyBinder.cs:

using System.ComponentModel;
using System.Web.Mvc;

public interface IPropertyBinder
{
    object BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor);
}

PropertyBinderAttribute.cs:

using System;
using System.Web.Mvc;

[AttributeUsage(AttributeTargets.Property)]
public sealed class PropertyBinderAttribute : Attribute
{
    public Type BinderType { get; private set; }

    public PropertyBinderAttribute(Type binderType)
    {
        BinderType = binderType;
    }

    public IPropertyBinder GetBinder()
    {
        return (IPropertyBinder)DependencyResolver.Current.GetService(BinderType);
    }
}

ModelBinderBase.cs:

using System.ComponentModel;
using System.Linq;
using System.Web.Mvc;

public class ModelBinderBase : DefaultModelBinder
{
    protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)
    {
        PropertyBinderAttribute attribute = propertyDescriptor.Attributes
            .OfType<PropertyBinderAttribute>()
            .SingleOrDefault();
        if (attribute == null)
        {
            base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
        }
        else
        {
            propertyDescriptor.SetValue(bindingContext.Model, attribute.GetBinder().BindProperty(controllerContext, bindingContext, propertyDescriptor));
        }
    }
}

Global.asax.cs:

using System;
using System.Web;
using System.Web.Mvc;

public class Global : HttpApplication
{
    protected void Application_Start(object sender, EventArgs e)
    {
        ModelBinders.Binders.DefaultBinder = new ModelBinderBase();
    }
}

To make use of this code, write a custom property binder that implements IPropertyBinder and decorate the corresponding property in your view model with a PropertyBinderAttribute that references your binder’s type.

Trimmed String Binding in ASP.NET MVC

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web.Mvc;

public class TrimmingModelBinder : DefaultModelBinder
{
    protected override void SetProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, object value)
    {
        if (propertyDescriptor.PropertyType == typeof(string))
        {
            if (value != null)
            {
                value = ((string)value).Trim();
                if ((string)value == "")
                {
                    bool convertToNull = true;
                    DisplayFormatAttribute attribute = propertyDescriptor.Attributes
                        .OfType<DisplayFormatAttribute>()
                        .SingleOrDefault();
                    if (attribute != null)
                    {
                        convertToNull = attribute.ConvertEmptyStringToNull;
                    }
                    if (convertToNull)
                    {
                        value = null;
                    }
                }
            }
        }
        base.SetProperty(controllerContext, bindingContext, propertyDescriptor, value);
    }
}