0

Test オブジェクトのフォームを表示したい 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、コントローラーに戻ったときに null になることです。どうすればデータが入力されるようになりますか? なぜヌルなのですか?

4

1 に答える 1

0

問題は Html.TextBox 要素だと思います。ビューのモデルが「Test」のタイプであることが正しい場合、コントローラーアクションで「Test」という名前の「Test」タイプのプロパティを持つ「EnterTestData」のタイプにバインドする場合、TextBox は次のように初期化する必要があります

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

重要な部分は name パラメータです。モデルバインダーは、この名前をポストアクションのモデルタイプのプロパティと一致させます。この場合、「EnterTestData」です。

エディター テンプレート ビューを使用することもできます。これは、部分ビューと同じです。プロジェクトで Views\Shared\ に移動し、存在しない場合は EditorTemplates という名前のフォルダーを作成します。このフォルダーで部分ビューを作成し、テンプレートのクラス/タイプのような名前を付けます。あなたの場合は「TestField.ascx」です。実際には、既存の部分ビューをコピーして名前を変更できます。メイン ビューでは、次の 2 つの点を変更する必要があります。

for(int i = 0; i < Model.Test.Fields.Count(); i++)
            Html.EditorFor(Model => Model.Test.Fields[i]);

テンプレート ビューでは、1 つのことを変更する必要があります: - TextBox の代わりに TextBoxFor ユーザー:

Html.TextBoxFor(Model => Model.Value)

私はこのパターンをよく使います。複雑なモデルを簡単にバインドできます。生成された HTML を見ることができます。

于 2012-12-09T17:30:54.533 に答える