4

私は、ユーザーが 1 人以上の他のユーザーを追加できるようにする管理パネルに取り組んでいます。管理者がアプリケーションに追加する 1 つまたは複数のユーザー ID を入力できるテキスト領域があります。これは、雇用プロセス中に割り当てられたユーザーの ID に対応します。送信すると、アプリケーションはすべての従業員を含むデータベースから名前、電子メールなどを取得し、確認のために画面に表示します。CanWrite画面には、やなどの権限を割り当てるためのチェックボックスもいくつか含まれていますIsAdmin

意見

using (Html.BeginForm())
        {
            <table>
                <tr>
                    <th>
                    </th>
                    <th>
                        @Html.DisplayNameFor(model => model.User.First().ID)
                    </th>
                    <th>
                        @Html.DisplayNameFor(model => model.User.First().Name)
                    </th>
                    <th>
                        @Html.DisplayNameFor(model => model.User.First().Email)
                    </th>
                    <th>
                        @Html.DisplayNameFor(model => model.User.First().CanWrite)
                    </th>
                    <th>
                        @Html.DisplayNameFor(model => model.User.First().IsAdmin)
                    </th>
                </tr>

                @foreach (var item in Model.User)
                {
                    <tr>
                        <td>
                            <input type="checkbox" name="id" value="@item.ID" checked=checked/>
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.ID)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.Name)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.Email)
                        </td>
                        <td>
                            @Html.CheckBoxFor(modelItem => item.CanWrite)
                        </td>
                        <td>
                            @Html.CheckBoxFor(modelItem => item.IsAdmin)
                        </td>
                    </tr>
                }

            </table>
            <input type="submit" />
        }

注: 名前付きのチェックボックスがある理由はID、名前やその他の情報が取得された後にユーザーを追加しないようにするためです。たとえば、追加するつもりのないユーザーが誤って ID のリストに入ってしまった場合などです。

モデル

public class User
{
    public int ID { set; get; }
    public string Name { set; get; }
    public bool IsAdmin { set; get; }
    public bool CanWrite { set; get; }
    public string Email{ set; get; }

}

コントローラ

[HttpPost]
public ActionResult Create(IEnumerable<User> model)
{
    //With this code, model shows up as null
}

User model1 人のユーザーの場合、コントローラー アクションのパラメーターとして使用できることがわかっています。このコードを調整して、複数のユーザーが一度に追加されるようにするにはどうすればよいですか? これは可能ですか?

4

3 に答える 3

1

次のようなことを試してください:

モデル

public class Employee
{
    public IEnumerable<User> Employees { set; get; }
}

public class User
{
    public int ID { set; get; }
    public string Name { set; get; }
    public bool IsAdmin { set; get; }
    public bool CanWrite { set; get; }
    public string Email{ set; get; }
}

意見

@model Employee

@using( Html.BeginForm()
{
    // build HTML table, not much different from yours
}

コントローラ

[HttpPost]
public ActionResult Create(Employee model)
{
    // model will have an IEnumerable property with the User info
}
于 2013-09-25T17:36:37.720 に答える
1

あなたは正しい道を進んでいます、ジェフ。持っているものを少し拡張するだけです。

まず、モデルがnullアクションに含まれる理由は、フォームで入力フィールドに名前が付けられているためです。フィールドは次のようにレンダリングされます。

<input id="item_CanWrite" name="item.CanWrite" type="checkbox" value="true" />
<input name="item.CanWrite" type="hidden" value="false" />

であることに注意してnameくださいitem.CanWrite。ここでの問題は、モデル内のすべてのユーザーをループしているため、基本的にすべての入力フィールドに同じ名前を付けていることです。これにより、MVC はそれぞれを区別できないため、POST されたデータにモデル バインドできなくなりますUser

これを修正するには、呼び出しを に変更してHtml.DisplayFor、MVC がそれぞれUserを個別のエンティティとして処理できるようにする必要があります。これにより、各Userの一連のフィールドに順番に名前を付けることができます。これにより、モデル バインダーはこれらのフィールドに適切にバインドできます。そのようです:

@for (int i = 0; i < Model.Count(); i++)
{
    <tr>
        <td>
            <input type="checkbox" name="id" value="@Model[i].ID" checked=checked/>
        </td>
        <td>
            @Html.DisplayFor(m => m[i].ID)
        </td>
        <td>
            @Html.DisplayFor(m => m[i].Name)
        </td>
        <td>
            @Html.DisplayFor(m => m[i].Email)
        </td>
        <td>
            @Html.CheckBoxFor(m => m[i].CanWrite)
        </td>
        <td>
            @Html.CheckBoxFor(m => m[i].IsAdmin)
        </td>
    </tr>
}

これらのフィールドが HTML としてどのようにレンダリングされるかを確認すると、次のようになっていることがわかります。

<input checked="checked" data-val="true" data-val-required="The CanWrite field is required." name="[0].CanWrite" type="checkbox" value="true" />
<input name="[0].CanWrite" type="hidden" value="false" />
<input checked="checked" data-val="true" data-val-required="The CanWrite field is required." name="[1].CanWrite" type="checkbox" value="true" />
<input name="[1].CanWrite" type="hidden" value="false" />

ご覧のとおり、それぞれUserに個別のインデックスがあります。次のコントローラー メソッドを使用した簡単なテスト セットアップを使用しました。これにより、テスト モデルで正しい数のレコードが取得されました。

[HttpPost]
public ActionResult Index(IEnumerable<User> model)
{
    // Process your data.

    return View(model);
}

ただし、あなたの見解にあるロジックを削除するために、ここでもう 1 つの改善を提案したいと思います。これを行うにはDisplayTemplates、ループの代わりに使用できます。

  1. DisplayTemplatesビューの現在のフォルダー内にフォルダーを作成します (たとえば、ビューが の場合Home\Index.cshtml、フォルダーを作成しますHome\DisplayTemplates)。
  2. モデルに一致する名前で、そのディレクトリに厳密に型指定されたビューを作成します (つまり、この場合、ビューは と呼ばれますUser.cshtml)。
  3. 繰り返されるロジックをビューに配置します。

テンプレートは次のようになります (Userモデルが存在する場所の名前空間を除いて)。

@model User

<tr>
    <td>
        <input type="checkbox" name="id" value="@Model.ID" checked=checked/>
    </td>
    <td>
        @Html.DisplayFor(m => m.ID)
    </td>
    <td>
        @Html.DisplayFor(m => m.Name)
    </td>
    <td>
        @Html.DisplayFor(m => m.Email)
    </td>
    <td>
        @Html.CheckBoxFor(m => m.CanWrite)
    </td>
    <td>
        @Html.CheckBoxFor(m => m.IsAdmin)
    </td>
</tr>

これで、元のビューで、すべてのループを次のように置き換えることができます:

@using (Html.BeginForm())
{
    <table>
        @Html.DisplayForModel()
    </table>
    <input type="submit" value="Submit" />
}

コレクションへのバインドについて詳しく知りたい場合は、別の質問に対する回答を参照してください。

于 2013-09-25T18:29:53.293 に答える