【发布时间】:2016-10-05 09:42:57
【问题描述】:
我正在使用 Umbraco MVC 来构建我们网页的表格 4。 我有一个 ViewModel,它实际上是另一个 ViewModel 的属性,并使用下面剃刀形式的部分视图填充。无论出于何种原因,绑定后的子视图模型(RequiredHealthInputData,见下文)始终为空!绑定器将成功地将所有表单值绑定到我的主视图模型,但我的子视图模型将保持为空!
(我研究了许多关于复杂类型绑定的类似问题,但我相信,但到目前为止我发现的解决方案(前缀、重命名我的属性以支持路由等)都不起作用。
我有一个 PtjInsurancePickerViewModel.cs(主视图模型),如下所示:
public class PtjInsurancePickerViewModel : BaseViewModel, IValidatableObject
{
[Required]
public string InsuranceNameStr { get; set; } = "-1";
public HealthDeclarationModel RequiredHealthInputData { get; set; }
}
HealthDeclarationModel 也是一个 ViewModel,具有以下值:
public class HealthDeclarationModel : BaseViewModel, IValidatableObject
{
[Display(Name = "Extra comment")]
public string ExtraComments { get; set; }
[Display(Name = "EnsurancePTName")]
public string EnsurancePTName { get; set; }
}
我有一个视图 InsurancePicker.cshtml,格式如下:
@using (Html.BeginUmbracoForm<InsurancePickerSurfaceController>("ProcessSelections"))
{
<h3>Select insurance</h3>
@Html.Partial("../Partials/InsurancePicker/_vsFamilyInsuranceProtection", Model)
<h3>Select extra options</h3>
@Html.Partial("../Partials/_Healthdeclaration", Model.RequiredHealthInputData)
<h3>Send!</h3>
<input type="submit" class="btn btn-success" value="Send!" title="Confirm choices"/>
}
请注意,表单由两个部分组成,一个获取 PtjInsurancePickerViewModel,另一个获取 HealthDeclarationModel,它是 PtjInsurancePickerViewModel 的属性
这是我的 HealthDeclarationModel 的部分内容:
<div class="HealthDeclarationModel-Panel">
<strong>2. Är du fullt arbetsför?</strong>
@Html.DropDownListFor(x => x.EnsurancePTName, Model.YesNoLista, new { @class = "form-control", @id = "EnsurancePTNameSelect" })
@Html.ValidationMessageFor(x => x.EnsurancePTName)
@Html.TextAreaFor(x => x.ExtraComments, new { @class = "form-control", style = "max-width:100%; min-width: 100%;" })
@Html.ValidationMessageFor(x => x.ExtraComments)
</div>
(注意。我在我的部分特殊 ID 中提供输入字段(由 jquery 用于状态管理)。也许这可能是问题的一部分?我尝试使用前缀为模型名称“HealthDeclarationModel .EnsurancePTNameSelect”的 ID 提交” 而不仅仅是“EnsurancePTNameSelect”,但无济于事)
提交函数导致如下方法:
[Authorize(Roles = "Forsakrad")]
public class InsurancePickerSurfaceController : BaseSurfaceController
{
[HttpPost]
public ActionResult ProcessSelections(PtjInsurancePickerViewModel filledModel)
{
//Checks if the very important RequiredHealthInputData submodel is null
if (filledModel.RequiredHealthInputData == null)
{
throw new ApplicationException("Critical data missing!!");
}
else
{
DoImportantStuffWithRequiredHealthInputData(filledModel.RequiredHealthInputData)
}
return CurrentUmbracoPage();
}
}
现在这是我的问题。 RequiredHealthInputData 将始终为空,因为 MVC 绑定器无法将 HealthDeclarationModel 绑定到 PtjInsurancePickerViewModel。 默认活页夹的结果如下所示:
{IndividWebb.Models.PtjInsurancePickerViewModel}
InsuranceNameStr: "0"
HalsodeklarationDataModel: null
但是,表单集合看起来像这样:
controllerContext.HttpContext.Request.Form.AllKeys
{string[17]}
[2]: "InsuranceNameStr"
[9]: "EnsurancePTName"
[12]: "ExtraComments"
14]: "HalsodeklarationDataModel"
(Some results have been excluded)
另请注意,属于 HalsodeklarationDataModel 的输入 EnsurancePTName 具有 id EnsurancePTName 而不是 HalsodeklarationDataModel.EnsurancePTName。
我真的不知道如何进行此操作,甚至不知道如何调试它。 我只是一个自定义助手来验证绑定确实排除了 HalsodeklarationDataModel 中的所有值
【问题讨论】:
-
除非您传递 HtmlFieldPrefix(请参阅 this answer),否则您不能使用部分。您应该为 typeof
HealthDeclarationModel使用自定义EditorTemplate,它确实为模型绑定生成正确的name属性(并注意id属性与它无关 - 它们供 javascript/css 选择器使用) -
要使其成为
EditorTemplate,请将您的部分重命名为HealthDeclarationModel.cshtml并将其移动到/Views/Shared/EditorTemplates文件夹中,然后使用@Html.EditorFor(m => m.RequiredHealthInputData) -
这产生了一个奇怪的结果,我的部分视图正常显示,但现在我的所有控件也打印为我的 html 中的编辑器字段,没有样式。我该如何防止这种情况?我用输入的新代码更新了上面的问题。
-
如果您使用
@Html.EditorFor(m => m.RequiredHalsoInputData),您需要正确命名文件并将其放置在正确的文件夹中(请参阅之前的评论-/Views/Shared/EditorTemplates/HealthDeclarationModel.cshtm)以及它的一个或另一个,而不是两者。如果你使用部分选项,那么前缀是"RequiredHealthInputData",而不是"HalsodeklarationModel"
标签: c# asp.net-mvc razor model-binding