Question

I am quite new to MVC. I am using an interface as a property for my model.

I noticed that my Data Annotation Attributes were being ignored. I also got an error while submitting the form:

Cannot create an instance of an interface.

I soon figured out that I will have to use a custom ModelBinder

I am having hard time figuring what needs to be done inside the CreateModel method of the ModelBinder

I have the following RegistrationModel:

public class RegistrationModel
{
    #region Properties (8) 

    public string Email { get; set; }

    public string FirstName { get; set; }

    public Gender Gender { get; set; }

    public string LastName { get; set; }

    public string Password { get; set; }

    public string PasswordConfirmation { get; set; }

    public IPlace Place { get; set; }

    public string Username { get; set; }

    #endregion Properties 
}

Here is the IPlace interface and implementation:

public interface IPlace
{
    #region Data Members (7) 

    string City { get; set; }

    string Country { get; set; }

    string ExternalId { get; set; }

    Guid Id { get; set; }

    string Name { get; set; }

    string Neighborhood { get; set; }

    string State { get; set; }

    #endregion Data Members 
}

public class Place : IPlace
{
    #region Implementation of IPlace

    public Guid Id { get; set; }

    [StringLength(100, ErrorMessage = "City is too long.")]
    public string City { get; set; }

    [StringLength(100, ErrorMessage = "Country is too long.")]
    public string Country { get; set; }

    [StringLength(255, ErrorMessage = "External ID is too long.")]
    public string ExternalId { get; set; }

    [Required(ErrorMessage = "A name is required.")]
    [StringLength(450, ErrorMessage = "Name is too long.")]
    [DisplayName("Location")]
    public string Name { get; set; }

    [StringLength(100, ErrorMessage = "Neighborhood is too long.")]
    public string Neighborhood { get; set; }

    [StringLength(100, ErrorMessage = "State is too long.")]
    public string State { get; set; }

    #endregion
}
Was it helpful?

Solution

You should try to avoid using interfaces and abstract types in your view models. So in your case if the controller action taking this view model can never have any other implementation of IPlace than Place, than simply replace the interface.

If for some reason you needed it, as you have already found out, you will have to write a custom model binder in which you specify which implementation you want to create. Here's an example.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top