我有一个web应用程序,我想在其中显示测试对象的表单。不同的测试实例可以有不同的模式。我可以很好地显示它,但它不会将表单中的所有数据都填充回我的模型中。
以下是我的模型类:
public class EnterTestData
{
public string StudyId { get; set; }
public Test Test { get; set; }
}
public sealed class Test
{
public string Identity { get; set; }
public string Name { get; set; }
public IEnumerable<TestField> Fields { get; set; }
}
public sealed class TestField
{
public string Identity { get; set; }
public string Name { get; set; }
public string Value { get; set; }
public string Type { get; set; }
}
以下是我的观点的相关部分:
<% Html.BeginForm("PostTestData", "StudiesUserInterface"); %>
<table>
<%
foreach (var testField in Model.Test.Fields)
Html.RenderPartial("UserControls/TestFieldUserControlascx", testField);
foreach (var category in Model.Test.Categories)
{
%>
<tr>
<td colspan="2" style="font-style: italic; text-align: center;">
<%=category.Name %>
</td>
</tr>
<%
foreach (var testField in category.Fields)
Html.RenderPartial("UserControls/TestFieldUserControlascx", testField);
}
%>
<tr>
<td colspan="2" style="text-align: right;">
<input type="submit" name="newsletter" value="Enter Result" />
</td>
</tr>
</table>
<% Html.EndForm(); %>
实际文本框的局部视图:
<tr>
<td>
<%= Model.Name %>
</td>
<td>
<%
switch (Model.Type)
{
case "date":
case "text":
case "number":
%>
<%= Html.TextBox(Model.name, Model.Value) %>
<% break;
default: %><%= Html.Label("Unknown data type") %><% break;
}
%>
</td>
</tr>
更新控制器方法:
public ActionResult EnterTestData(string studyId, string testId)
{
var testDefinition = ServiceKitLocator.GetStudyService().GetTestDefinition(testId);
return View(new EnterTestData { StudyId = studyId, Test = testDefinition });
}
public ActionResult PostTestData(EnterTestData model)
{
//I'm just putting a break point here and checking the model in the debugger for now
return RedirectToAction("Index");
}
问题是Test
在返回到我的控制器时为null。如何填充?为什么它是空的?
我认为问题出在Html.TextBox元素上。如果视图中的模型是"Test"类型是正确的,但在控制器操作中,您希望绑定到"EnterTestData"类型,该类型具有名为"Test"的"Test"属性然后你的文本框应该像一样初始化
Html.TextBox("Test.Name", Model.Value)
重要的部分是name参数。模型绑定器将此名称与您的后期操作中的模型类型的属性相匹配,在您的案例中为"EnterTestData"。
您也可以使用编辑器模板视图。这与您的局部视图相同。在您的项目中,转到Views\Shared\并创建一个名为EditorTemplates的文件夹(如果不存在)。在该文件夹中创建一个局部视图,并将其命名为模板应用于的类/类型。在您的情况下是"TestField.ascx"。实际上,您可以复制并重命名现有的部分视图。在你的主视图中,你必须改变两件事:-使用for而不是foreach-在循环中调用编辑器模板类似:
for(int i = 0; i < Model.Test.Fields.Count(); i++)
Html.EditorFor(Model => Model.Test.Fields[i]);
在模板视图中,您必须更改一件事:-用户TextBoxFor而不是TextBox类似:
Html.TextBoxFor(Model => Model.Value)
我经常使用这种模式。它使绑定复杂模型变得容易。您可以查看生成的HTML