Search code examples
c#asp.net-mvcmodelbindersmodel-bindingcustom-model-binder

How to make a custom string object modelbind in MVC?


I created a custom string object, but it does not modelbind when I post it back to the server. Is there an attribute I'm missing on the class or something?

This is the custom string class below:

public class EMailAddress
{
    private string _address;
    public EMailAddress(string address)
    {
        _address = address;
    }
    public static implicit operator EMailAddress(string address)
    {
        if (address == null)
            return null;
        return new EMailAddress(address);
    }
}

Solution

  • In order for the object to be correctly bound by the default model binder it must have a default parameterless constructor:

    public class EMailAddress
    {
        public string Address { get; set; }
    }
    

    if you want to use models as the one you showed you will need to write a custom model binder to handle the conversion:

    public class EmailModelBinder : DefaultModelBinder
    {
        public override object BindModel(
            ControllerContext controllerContext, 
            ModelBindingContext bindingContext
        )
        {
            var email = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
            if (email != null)
            {
                return new EMailAddress(email.AttemptedValue);
            }
            return new EMailAddress(string.Empty);
        }
    }
    

    which will be registered in Application_Start:

    ModelBinders.Binders.Add(typeof(EMailAddress), new EmailModelBinder());
    

    and used like this:

    public class HomeController : Controller
    {
        public ActionResult Index(EMailAddress email)
        {
            return View();
        }
    }
    

    Now when you query /Home/[email protected] the action parameter should be properly bound.

    Now the question is: do you really want to write all this code when you can have a view model as the one I showed initially?