简体   繁体   English

MVC Complex模型绑定与继承,嵌套viewModels和部分视图

[英]MVC Complex model binding with inheritance, nested viewModels and partial views

I don't manage to get the values of my nested models back to the controller, they are all nulls. 我无法将嵌套模型的值恢复到控制器,它们都是空值。

Here is the simplified architecture: 这是简化的架构:

//The viewModel being passed to the view
public class RunnerIndexViewModel
{
    public RegisterViewModel User { get; set; }

    public TrainerViewModel TrainerVM { get; set; }

    public RunnerBase Runner { get; set; }

    [Display(Name = "AddContact", ResourceType = typeof(MyRessources))]
    public bool AddContact { get; set; }
}

public class RegisterViewModel
{
    // various simple type properties here
}

public class TrainerViewModel
{
    // various properties here
    public Unit unit { get; set; }

    public List<SelectListItem> ListStatut { get; set; }
}

public abstract partial class RunnerBase
{
    // entity framework class with associations
}

public class RedRunner : RunnerBase
{
    // entity framework class with associations
}

public class BlueRunner : RunnerBase
{
    // entity framework class with associations
}

Here is the main view that receives the model from the controller (simplified): 以下是从控制器接收模型的主视图(简化):

@model Web.Models.Fournisseurs.FournisseurIndexViewModel

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    @Html.Partial("PartialTrainer", Model.TrainerVM)
    @Html.Partial("PartialRunner", Model.Runner as RedRunner)
    @Html.Partial("PartialUser", Model.User)
}

The views PartialTrainer and PartialUser have nothing special, so here is the PartialRunner view that takes the base class from entity framework: PartialTrainer和PartialUser的观点没什么特别之处,所以这里是从实体框架中获取基类的PartialRunner视图:

@model RunnerBase

@* Show Various fields from RunnerBase ... *@

@if (Model is RedRunner)
{
    @* show properties specific to RedRunner *@
}
else if (Model is BlueRunner)
{
    @* show properties specific to BlueRunner *@
}   

From the controller I either pass a RedRunner or a BlueRunner to the Runner property. 从控制器我将RedRunner或BlueRunner传递给Runner属性。 All fields for all viewModels show up well but when submitting the form, I only manage to get the AddContact value... 所有viewModel的所有字段都显示良好,但在提交表单时,我只设法获取AddContact值...

How can I get the value of my other viewmodels and the one from the Runner class? 如何获取其他视图模型的值以及Runner类中的值?

The problem is with using partials. 问题在于使用partials。 Each time you go into the a partial, the model context changes, so the inputs that Razor generates for you are not taking the full property path into account. 每次进入部分时,模型上下文都会发生变化,因此Razor为您生成的输入不会考虑完整的属性路径。 For example, if you were to do the following in your main view: 例如,如果要在主视图中执行以下操作:

@Html.EditorFor(m => m.TrainerVM.SomeProperty)

The resulting HTML would be akin to: 生成的HTML类似于:

<input type="text" name="TrainerVM.SomeProperty" />

However, when using a partial, your helper would be called as: 但是,当使用partial时,您的助手将被称为:

@Html.EditorFor(m => m.SomeProperty)

And the resulting HTML would be akin to: 生成的HTML将类似于:

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

Once this gets posted back, the modelbinder doesn't know that SomeProperty belongs to the TrainerVM instance so it can't determine where to bind the posted value, and you end up with nulls. 一旦这个被贴后背,将ModelBinder的不知道SomeProperty属于TrainerVM实例,因此它不能确定在哪里张贴的值绑定,和你结束了零点。 To continue to use partials but side-step this problem, you'll need to pass a value for ViewData.TemplateInfo.HtmlFieldPrefix (which is used to properly prefix the names of all the fields in the partial): 要继续使用partials而不是侧面解决此问题,您需要传递ViewData.TemplateInfo.HtmlFieldPrefix的值(用于正确添加部分中所有字段的名称):

@Html.Partial("PartialTrainer", Model.TrainerVM, new ViewDataDictionary(ViewData)
{
    TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "TrainerVM" }
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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