简体   繁体   中英

MVC4 Automatically mapped my view model?

I began to create my controller for the parent model listed below. I am using view models for all my views, but before I got around to adding the logic for the Create (Post) action I just hit submit for the hell of it thinking my viewmodel would not map to my model.

To my surprise it actually worked. I am using AutoMapper and have set up all the mappings for the child models to their corresponding models, but not the parent model (as absent in the post result). What is going on here that MVC has allowed such magic to happen?

Model:

public partial class ParentModel
    {
        public int Id { get; set; }
        public int Child1Id { get; set; }
        public int Child2Id { get; set; }
        public int Child3Id { get; set; }
        public int Child4Id { get; set; }
        //other data
        public virtual Child1 Child1 { get; set; }
        public virtual Child2 Child2 { get; set; }
        public virtual Child3 Child3 { get; set; }
        public virtual Child4 Child4 { get; set; }
    }

View Model:

public class ParentCreateViewModel
    {
        //other data
        public Child1ViewModel Child1 { get; set; }
        public Child2ViewModel Child2 { get; set; }
        public Child3ViewModel Child3 { get; set; }
        public Child4ViewModel Child4 { get; set; }
    }

View (Create.cshtml):

@model Project.ViewModels.ParentCreateViewModel
@*EditorTemplates and such*@

Controller (Get):

public ActionResult Create()
    {
        //some list logic
        return View();
    }

Controller (Post - I haven't yet changed it to the ParentCreateViewModel or AutoMapped it back to ParentModel):

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(ParentModel parentModel)
{
    if (ModelState.IsValid)
    {
        db.ParentModels.Add(parentModel);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    //some list logic
    return View(parentModel);
}

My parent model and all child models are persisted correctly to the database. Does MVC do some kind of behind the scene binding? Shouldn't it be expecting a ParentCreateViewModel?

The default model binder binds on name of elements. Since both models would share these properties (and therefore, HTML element names when using editor templates and HTML helpers), it will bind it to the model.

Both of your models will generate form elements like this:

<input type="text" name="Child1_Name" />

..etc. When the form values are posted, the model binder inspects and finds "Child1_Name". The underscore signifies a child class property. So, it doesn't matter which model you choose because Child1.Name is a valid property of both models. So, since you've told the action method you want a ParentModel , the model binder happily applies the value to the Child1.Name property when it's found.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM