0

我有一个 Web 应用程序,我想在其中显示一个 Test 对象的表单。不同的测试实例可以有不同的模式。我可以很好地显示它,但它不会将表单中的所有数据填充回我的模型中。

这是我的模型类:

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当它回到我的控制器时它是空的。我如何让它被填充?为什么它是空的?

4

1 回答 1

0

我认为问题在于 Html.TextBox 元素。如果视图中的模型是“Test”类型是正确的,但在控制器操作中,您希望绑定到“EnterTestData”类型,该类型具有名为“Test”的“Test”类型属性,那么您的 TextBox 应该被初始化为

Html.TextBox("Test.Name", Model.Value)

重要的部分是名称参数。modelbinder 将此名称与您发布操作中模型类型的属性相匹配,在您的情况下为“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

于 2012-12-09T17:30:54.533 回答