【问题标题】:MVC Complex model binding with inheritance, nested viewModels and partial views具有继承、嵌套视图模型和部分视图的 MVC 复杂模型绑定
【发布时间】:2015-04-14 21:28:25
【问题描述】:

我无法将嵌套模型的值返回到控制器,它们都是空值。

这是简化的架构:

//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
}

这是从控制器接收模型的主视图(简化):

@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)
}

视图 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 *@
}   

从控制器中,我将 RedRunner 或 BlueRunner 传递给 Runner 属性。所有视图模型的所有字段都显示得很好,但是在提交表单时,我只设法获得了 AddContact 值......

如何从 Runner 类中获取其他视图模型的值?

【问题讨论】:

    标签: c# asp.net-mvc entity-framework asp.net-mvc-5


    【解决方案1】:

    问题在于使用部分。每次进入局部时,模型上下文都会发生变化,因此 Razor 为您生成的输入不会考虑完整的属性路径。例如,如果您要在主视图中执行以下操作:

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

    生成的 HTML 类似于:

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

    但是,当使用部分时,您的助手将被称为:

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

    生成的 HTML 类似于:

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

    一旦这被回发,modelbinder 不知道SomeProperty 属于TrainerVM 实例,因此它无法确定将发布的值绑定到哪里,最终得到空值。要继续使用分部但避开此问题,您需要为 ViewData.TemplateInfo.HtmlFieldPrefix 传递一个值(用于正确地为分部中所有字段的名称添加前缀):

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多