我有一个视图模型,它有另一个子模型来渲染局部视图(下图)。
public class ExamResultsFormViewModel
{
public PreliminaryInformationViewModel PreliminaryInformation { get; set; }
public string MemberID { get; set; }
public string MemberName { get; set; }
public int PatientID { get; set; }
public string ConfirmationID { get; set; }
public bool IsEditable { get; set; }
#region Select Lists
public SelectList ProviderOptions { get; set; }
#endregion
}
public class PreliminaryInformationViewModel
{
public string ProviderName { get; set; }
public string ProviderID { get; set; }
public string ServiceLocation { get; set; }
}
此InitialInformationViewModel视图模型还用作另一个视图模型中的子模型,因为此初步信息可以在不同页面更新。
因此,我将此初步信息创建为单独的部分,并包含在其他页面中。
@{Html.RenderPartial("_PreliminaryInformation", Model.PreliminaryInformation);}
在部分内部
@model Web.Models.Preliminary.PreliminaryInformationViewModel
<div>
@Html.TextBoxFor(x => x.DateOfService })
</div>
但问题是在提交期间,由于HTML名称属性始终呈现为原因,因此初步模型始终为null
但是当我将父模型传递给部分时,如下所示。
@model Web.Models.Exam.ExamResultsFormViewModel
<div>
@Html.TextBoxFor(x => x.PreliminaryInformation.DateOfService })
</div>
现在HTML元素生成为
<input type = 'text' name='PreliminaryInformation.DateOfService.DateOfService' id='PreliminaryInformation.DateOfService'>
并且在提交期间它会正确绑定。
我理解MVC根据name属性值绑定元素值,但第二个实现需要我为每个页面创建一个多部分,我不喜欢。
到目前为止,我找不到使用第一个实现的解决方案,是否可以在第一次实现提交期间使初步信息模型值绑定。
答案 0 :(得分:34)
我知道它有点晚了,但它可能对某人有帮助
如果您有复杂的模型,您仍然可以使用以下方法将其传递给部分:
@Html.Partial("_YourPartialName", Model.Contact, new ViewDataDictionary()
{
TemplateInfo = new TemplateInfo()
{
HtmlFieldPrefix = "Contact"
}
})
我已经定义了带有属性的模型&#34;联系&#34;。现在HtmlFieldPrefix做的是为每个模型添加属性绑定&#34;因此模型绑定器可以找到父模型&#34;
有关于它的博文:http://www.cpodesign.com/blog/bind-partial-view-model-binding-during-submit/
.NET Core 2绑定
在.NET Core 2和MVC中,上面的答案不起作用,该属性不再可设置。
解决方案如何非常相似。
@{ Html.ViewData.TemplateInfo.HtmlFieldPrefix = "Contact"; }
@await Html.PartialAsync("_YourPartialName", Model.Contact)
在您提交模型后,它将再次绑定。
希望有所帮助
答案 1 :(得分:6)
您需要为PreliminaryInformationViewModel
创建一个编辑器模板来替换部分视图,然后使用Html.EditorFor( m => m.PreliminaryInformation )
进行调用。参考this solution。创建模板应该像将部分视图移动到Views / Shared / EditorTemplates目录一样简单。 Html.EditorFor(...)
会根据您作为模型传入的类型自动使用此模板(在本例中为PreliminaryInformationViewModel
)
答案 2 :(得分:5)
您可以将HtmlFieldPrefix添加到局部视图的顶部:
i
这与@cpoDesign描述的方法相同,但这意味着如果需要,可以在部分视图中保留前缀。
答案 3 :(得分:3)
我也遇到了这个问题。我将使用您的代码解释我的解决方案。我从这开始:
@{
Html.RenderPartial("_PreliminaryInformation", Model.PreliminaryInformation);
}
对应于http帖子的操作正在寻找父模型。 http帖子正确地提交了表单,但是在子部分中没有对父部分的引用。来自子部分的提交值被忽略,相应的子属性保持为空。
我创建了一个接口IPreliminaryInfoCapable,其中包含子类型的定义,如下所示:
public interface IPreliminaryInfoCapable
{
PreliminaryInformationViewModel PreliminaryInformation { get; set; }
}
我让我的父模型实现了这个接口。我的局部视图然后使用顶部的界面作为模型:
@model IPreliminaryInfoCapable
最后,我的父视图可以使用以下代码将自身传递给子部分:
@{
Html.RenderPartial("ChildPartial", Model);
}
然后子部分可以使用子对象,如下所示:
@model IPreliminaryInfoCapable
...
@Html.LabelFor(m => m.PreliminaryInformation.ProviderName)
etc.
所有这些都可以在http发布时正确地填充父模型到相应的操作。
答案 4 :(得分:0)
快速提示:调用EditorFor方法时,可以将模板名称设置为Html.EditorFor方法的参数。或者,命名约定可以是你的朋友;只需确保您的编辑器模板文件名与模型属性类型
完全相同即。 model属性类型'CustomerViewModel'=&gt; 'CustomerViewModel.cshtml'编辑模板。
答案 5 :(得分:0)
请对您的部分页面进行以下更改。所以它将伴随您的父模型
//Parent Page
@{Html.RenderPartial("_PreliminaryInformation", Model.PreliminaryInformation);}
//Partial Page
@model Web.Models.Preliminary.PreliminaryInformationViewModel
@using (Html.BeginCollectionItem("PreliminaryInformation", item.RowId, true))
{
<div>
@Html.TextBoxFor(x => x.DateOfService })
</div>
}
答案 6 :(得分:0)
对于.net core 2和mvc,请使用如下操作:
{this.state.isLoggedIn ?
(
<Route
path='/home'
render={() => <HomePage onLogout={this.onLogout} />}
/>
)
:
(
<Route exact path='/' component={() => <LoginPage onLogin={this.onLogin} />}/>
)
}