6

というクラスがCategoryModelあり、そのプロパティの 1 つは同じタイプのオブジェクトのリストです。CategoryModel.CategoriesタイプもそうですList<CategoryModel>

カテゴリ インデックス ページでは、各カテゴリのエディタを表示して、ユーザーが専用のページに移動しなくてもカテゴリ名を変更できるようにします。そのようです:

<ul id="categories>
    @Html.EditorFor(model => model.Categories)
</ul>

のエディター テンプレートはCategoryModel次のようになります。

<li class="folder">
    @using (Html.BeginForm("Edit", "Category", new { id = Model.Key }, FormMethod.Post, new { @class = "ajaxoff"})) {
        @Html.ValidationSummary(true)
        @Html.HiddenFor(model => model.Key)
        @Html.HiddenFor(model => model.ParentKey)
        @Html.HiddenFor(model => model.Sequence)
        @Html.HiddenFor(model => model.IncludeDeleted)

        @Html.TextBoxFor(model => model.Name, null, new { @class = "catName" })
        @Html.ValidationMessageFor(model => model.Name)

        <input type="submit" value="Save" class="icon save" />
    }
</li>

Edit私が抱えている問題は、フォームの送信が次のアクションに正しくバインドされないことCategoryControllerです:

[HttpPost]
public ActionResult Edit(CategoryModel category)
{
    // At this point all properties in category are null
}

非表示のフィールドとテキスト ボックスの名前を確認すると、現在のカテゴリでの位置に基づいてラベルが付けられます (例: Categories[0].Name)。ただし、専用の編集ビューを作成すると、フィールド名に従って単純に名前が付けられます (例: Name)。

コントローラを変更して、カテゴリのリストを受け入れるようにしました:

[HttpPost]
public ActionResult Edit(List<CategoryModel> categories)
{
    var category = categories.First();
}

これは、最初のカテゴリを送信した場合に機能しますが、他のカテゴリは送信しません (これらの場合Categoriesは null です)。

また、次のようにして、EditorFor の表示方法を変更しようとしました。

<ul id="categories>
    @foreach (var cat in Model.Categories)
    {
        @Html.EditorFor(model => cat);
    }
</ul>

これにより、フィールド名が各カテゴリで同じになるように変更されます (たとえば、すべてのカテゴリ名が と呼ばれますcat.Name)。これは正しい方向への一歩だと思います。

では、コントローラーに正しくバインドするにはどうすればよいでしょうか? 親カテゴリ全体を送信してから各サブカテゴリを保存することもできますが、これは 1 つの変更を送信するには非常に非効率的な方法のように思えます。

4

2 に答える 2

6

これを行う方法を発見しました。Html.EditorForプロパティを指定できるオーバーロードがありhtmlFieldNameます (以下の例の 3 番目のパラメーター)。

@foreach (var cat in Model.Categories)
{
    @Html.EditorFor(model => cat, null, "");
}

これにより、プレフィックスなしですべてのフィールド名がレンダリングされ、単一のカテゴリを正常に送信できます。

于 2013-07-12T14:22:03.770 に答える
0

Edit アクションは CategoryModel カテゴリを受け入れるため、右バインディングのモデル プレフィックスをリセットする必要があります。このためには、次のように HtmlHelper の独自の拡張メソッドを作成する必要があります。

public class BeginHtmlScope : IDisposable
    {
        private readonly TemplateInfo templateInfo;
        private readonly string previousHtmlFieldPrefix;

        public BeginHtmlScope(TemplateInfo templateInfo, string htmlFieldPrefix)
        {
            this.templateInfo = templateInfo;

            previousHtmlFieldPrefix = templateInfo.HtmlFieldPrefix;
            templateInfo.HtmlFieldPrefix = htmlFieldPrefix;
        }

        public void Dispose()
        {
            templateInfo.HtmlFieldPrefix = previousHtmlFieldPrefix;

        }
    }
    public static class MyHtmlExtensions
    {
        public static IDisposable BeginHtmlScope(this HtmlHelper html, string htmlFieldPrefix)
        {
            return new BeginHtmlScope(html.ViewData.TemplateInfo, htmlFieldPrefix);
        }
    }

そして、エディタ テンプレート内で使用します。

@using (Html.BeginHtmlScope(""))
{
   <li class="folder">
    @using (Html.BeginForm("Edit", "Category", new { id = Model.Key }, FormMethod.Post, new { @class = "ajaxoff"})) {
        @Html.ValidationSummary(true)
        @Html.HiddenFor(model => model.Key)
        @Html.HiddenFor(model => model.ParentKey)
        @Html.HiddenFor(model => model.Sequence)
        @Html.HiddenFor(model => model.IncludeDeleted)

        @Html.TextBoxFor(model => model.Name, null, new { @class = "catName" })
        @Html.ValidationMessageFor(model => model.Name)

        <input type="submit" value="Save" class="icon save" />
    }
</li>

}
于 2013-07-12T13:14:35.480 に答える