Question

I don't have any other way of describing it then how I did it in the title.

I have a view model that looks like this:

public class CreateArtistModel
{        
    public IEnumerable<SelectListItem> Cultures { get; set; }
    public IEnumerable<SelectListItem> Products { get; set; }
    public Artists Artist { get; internal set; }

    /// <summary>
    /// Default constructor
    /// </summary>
    public CreateArtistModel() { }

    /// <summary>
    /// Non-default constructor with 1 parameter, culturelist
    /// </summary>
    /// <param name="cultures">List that can contain all the possible cultures.</param>
    /// <param name="products">List that can contain all possible products.</param>
    public CreateArtistModel(IEnumerable<SelectListItem> cultures, IEnumerable<SelectListItem> products) { Cultures = cultures; Products = products; }

    /// <summary>
    /// Non-default constructor that can have 1 parameter, artist
    /// </summary>
    /// <param name="artist">The artist with its various properties</param>
    public CreateArtistModel(Artists artist) { Artist = artist; }

    /// <summary>
    /// Non-default constructor that can have 2 parameter, a list cultureList and an atist
    /// </summary>
    /// <param name="cultures">List that can contain all the possible cultures.</param>
    /// <param name="products">List that can contain all possible products.</param>
    /// <param name="artist">The artist with its various properties</param>
    public CreateArtistModel(IEnumerable<SelectListItem> cultures, IEnumerable<SelectListItem> products, Artists artist)
    {
        Cultures = cultures;
        Products = products;
        Artist = artist;
    }

    [Required(ErrorMessage = "The artist's first name is required")]
    public string firstname { get; set; }

    [Required(ErrorMessage = "The artist's last name is required")]
    public string lastname { get; set; }

    public Nullable<int> dateOfBirth { get; set; }

    public Nullable<int> dateOfDeath { get; set; }

    [Required(ErrorMessage = "The artist's speciality is required")]
    public string speciality { get; set; }

    public string placeOfBirth { get; set; }
}

My view then uses the properties like this:

@model ArtWebShop.Areas.Admin.Models.CreateArtistModel

@Html.EditorFor(model => model.firstname)
@Html.ValidationMessageFor(model => model.firstname)

Then in my controller I save it like this:

        [HttpPost]
    public ActionResult Create(Artists artist)
    {
        if (!ModelState.IsValid)
        {
            return View(CreateArtistWithListOfProductsAndcultures(artist));
        }

        if (_unitOfWork != null)
        {
            _unitOfWork.ArtistsRepository.Create(artist);
            _unitOfWork.Save();
        }
        return RedirectToAction("Index", "Overview", new { area = "Admin" });
    }

And that works! But I'm not sure why...

I'd like to understand exactly why this works. Why does are the properties in my view model automatically linked to the artist model?

Was it helpful?

Solution

Well the magic is done my Model Binders. The default ASP.Net modelbinder has the capability re-create action parameters from the form post data and\or querystring. So when a POST happens the Modelbinder kicks in and inspects the post data for the encoding and tries to construct the object for your action method. It does mapping based on the parameter - property name matching.

This also means the Modelbinder does care about your Model or ViewModel classes. As long it gets a class type in action parameter, it would try to map the POST (body content) or GET (querystring) parameters to your custom class properties. Your ViewModel infact is just irrelevant here except it help in rendering html form, with INPUT elements which have name matching the model propeties.

You can look at these articles to get indepth understanding on Modelbinders.

http://msdn.microsoft.com/en-us/magazine/hh781022.aspx

http://www.codeproject.com/Articles/159749/ASP-NET-MVC-Model-Binding-Part1

http://www.codeproject.com/Articles/161963/ASP-NET-MVC-Model-Binding-Part-2

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