Modelbinding a interface property
<p>I'm using MVC.NET 5.2.3 and try to post a model to a controller where the model contains several interfaces. This causes .NET to throw this exception:</p>

<blockquote>
  <p>Cannot create an instance of an interface</p>
</blockquote>

<p>I understand that it's because I use interfaces in my model (ITelephone). My models are as such:</p>

<pre><code>public class AddContactPersonForm
{
    public ExternalContactDto ExternalContact { get; set; }
    public OrganizationType OrganizationType { get; set; }
}

public class ExternalContactDto
{
    public int? Id { get; set; }
    public string Name { get; set; }
    public string Title { get; set; }
    public IList&lt;ITelephone&gt; TelephoneNumbers { get; set; }
}

public interface ITelephone
{
    string TelephoneNumber { get; set; }
}

public class TelephoneDto : ITelephone
{
    public string TelephoneNumber { get; set; }
}
</code></pre>

<p>It works fine if I use the TelephoneDto class instead of the ITelephone interface.</p>

<p>I understand that I need to use a ModelBinder, which is fine. But I really just want to say what kind of instance the modelbinder should create, instead of mapping the entire model manually.</p>

<p>The answer @jonathanconway gave in this question is close to what I want to do.</p>

<p><a href="https://stackoverflow.com/questions/2186969/custom-model-binder-for-a-property/12683210#12683210">Custom model binder for a property</a></p>

<p>But I really would like to combine this with the simplicity of simply telling the defaultbinder what type to use for a specific interface. Sort of the same way you can use the KnownType-attribute. The defaultbinder obviously knows how to map the model as long as it knows which class it should create.</p>

<p><strong>How can I tell the DefaultModelBinder what class it should use to deserialize the interface and then bind it? It currently crashes because the model that is posted (AddContactPersonForm) contains a "complex" model (ExternalContactDto) which has the interface ITelephone.</strong></p>

<p>This is what I got so far.</p>

<pre><code>public class ContactPersonController : Controller
{

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult AddContactPerson([ModelBinder(typeof(InterfaceModelBinder))] AddContactPersonForm addContactPersonForm)
    {
        // Do something with the model.
        return View(addContactPersonForm);
    }
}

public class InterfaceModelBinder : DefaultModelBinder
{
    protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext,
        PropertyDescriptor propertyDescriptor)
    {

        var propertyBinderAttribute = TryFindPropertyBinderAttribute(propertyDescriptor);
        if (propertyBinderAttribute != null)
        {
            // Never occurs since the model is nested.
            var type = propertyBinderAttribute.ActualType;
            var model = Activator.CreateInstance(type);
            bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() =&gt; model, type);

            base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
            return;
        }

        // Crashed here since because:
        // Cannot create an instance of an interface. Object type 'NR.Delivery.Contract.Models.ITelephone'.
        base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
    }

    private InterfaceBinderAttribute TryFindPropertyBinderAttribute(PropertyDescriptor propertyDescriptor)
    {
        return propertyDescriptor.Attributes
          .OfType&lt;InterfaceBinderAttribute&gt;()
          .FirstOrDefault();
    }
}

public class ExternalContactDto
{
    public int? Id { get; set; }
    public string Name { get; set; }
    public string Title { get; set; }
    [InterfaceBinder(typeof(List&lt;TelephoneDto&gt;))]
    public IList&lt;ITelephone&gt; TelephoneNumbers { get; set; }
}

public class InterfaceBinderAttribute : Attribute
{
    public Type ActualType { get; private set; }

    public InterfaceBinderAttribute(Type actualType)
    {
        ActualType = actualType;
    }
}
</code></pre>