11

MVCには次のクラスレイアウトがあります。

public class ReportModel 
{
    List<SomeItem> items;
    string value;
    string anotherValue;
}

ここで、このタイプのMVCで厳密に型指定されたビューを作成し、編集可能なテキストフィールドを作成して各値を編集し、foreachループを使用してテキストフィールドにデータを入力して、アイテムのリスト内のアイテムを編集します。

httppostメソッドに送信すると、reportmodelオブジェクトで特異値が正常に返されますが、リストはオブジェクトで返されません。これはどのように行う必要がありますか?

私がhttppostと言うとき、私はMVCがポストバックしているメソッドを指します

[HttpPost]
public ActionResult EditReport(ReportModel report)
{
    // Save the report in here after the update on the UI side
}

someitemのリストを投稿するためのコードを表示

if (Model.items != null && Model.items.Count > 0)
{
    for (int i = 0; i < Model.items.Count; i++)
    {                
        <div class="editrow">
            <div class="edititem">
                <div class="editor-label">
                    @Html.LabelFor(m => m.items.ElementAt(i).propertyOne)
                </div>
                <div class="editor-field">
                    @Html.TextBoxFor(m => m.items.ElementAt(i).propertyOne)
                    @Html.ValidationMessageFor(m => m.items.ElementAt(i).propertyOne)
                </div>
            </div>
            <div class="edititem">
                <div class="editor-label">
                    @Html.LabelFor(m => m.items.ElementAt(i).propertyTwo)
                </div>
                <div class="editor-field">
                    @Html.TextBoxFor(m => m.items.ElementAt(i).propertyTwo)
                    @Html.ValidationMessageFor(m => m.items.ElementAt(i).propertyTwo)
                </div>
            </div>
            <div class="edititem">
                <div class="editor-label">
                    @Html.LabelFor(m => m.items.ElementAt(i).propertyThree)
                </div>
                <div class="editor-field">
                    @Html.TextBoxFor(m => m.items.ElementAt(i).propertyThree)
                    @Html.ValidationMessageFor(m => m.items.ElementAt(i).propertyThree)
                </div>
            </div>
        </div>
    }
}
4

2 に答える 2

17

ラムダ式で使用しないElementAt(1)でください => 入力フィールド名が台無しになります。Kirill が提案したブログ投稿をお読みください。

したがって、インデックス付きアクセスを使用できます。

for (int i = 0; i < Model.items.Count; i++)
{                
    <div class="editrow">
        <div class="edititem">
            <div class="editor-label">
                @Html.LabelFor(m => m.items[i].propertyOne)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(m => m.items[i].propertyOne)
                @Html.ValidationMessageFor(m => m.items[i].propertyOne)
            </div>
        </div>
        <div class="edititem">
            <div class="editor-label">
                @Html.LabelFor(m => m.items[i].propertyTwo)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(m => m.items[i].propertyTwo)
                @Html.ValidationMessageFor(m => m.items[i].propertyTwo)
            </div>
        </div>
        <div class="edititem">
            <div class="editor-label">
                @Html.LabelFor(m => m.items[i].propertyThree)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(m => m.items[i].propertyThree)
                @Html.ValidationMessageFor(m => m.items[i].propertyThree)
            </div>
        </div>
    </div>
}

もちろん、インデクサーがコレクションにアクセスできるようにするために、これは、プロパティがまたはitemsとして宣言されていることを前提としています。である場合は機能しません。したがって、ビュー モデルでこのプロパティのタイプを変更するだけです。List<SomeItem>SomeItem[]IEnumerable<SomeItem>

于 2012-10-03T12:39:45.417 に答える
2

Scott Hanselman のブログ エントリに対する Kirill の言及は正しいですが、あなたはそれを狭く読みすぎています。示されている例では、彼は配列をアクション メソッドに渡していますが、親モデル内にも同じように簡単に含めることができます。同じ概念が適用されます。

ただし、1 つ知っておくべきことは、既定のモデル バインダーはネストされたクラスをインスタンス化しないため、List クラスのインスタンスを作成しないということです。つまり、常に null になります。これを修正するには、コンストラクターで空のリスト クラスをインスタンス化する必要があります。

これは問題の一部にすぎませんが、モデル バインダーがデータをバインドするには、データを正しい方法でフォーマットする必要があります。モデル バインダーがデータをリストとして認識するために必要な形式を提供するため、Scott のブログ投稿の出番です。

これは通常、EditorTemplate を使用し、Html.EditorFor(m => m.Items) を使用してから SomeItem.cshtml EditorTemplate を使用する場合に処理されます。これは、コレクション アイテムの命名の問題を処理します (テンプレートで厳密に型指定されたヘルパーも使用する場合)。

于 2012-10-02T20:23:34.593 に答える