6

ユーザーがいくつかの情報を入力し、最終的にチェックボックスで 1 人以上の顧客を選択する必要があるページに取り組んでいます。

顧客のリストはIEnumerable<Customer>、モデルに渡す です。を使用してチェックボックスのリストを作成するにはどうすればよい.CheckBoxFor()ですか?

最後に、少なくとも 1 つのチェックボックスが選択されているかどうかを検証できるようにしたいと考えています。

Request は、ユーザーが入力した情報を保持するオブジェクトです。

<% foreach (var customer in Model.Request.Customers) { %>
   <%= Html.CheckBoxFor(/* customer */) %>
<% } %>

誰かが私を正しい方向に向けることができますか? それとも、私はこれについてすべて間違っていますか?

4

4 に答える 4

3

Html.CheckBoxFor() 拡張メソッドは、ブール型のモデルのプロパティを編集するように設計されています。それを使用して、IEnumerable コレクションからいくつかのオブジェクトを選択します。それは間違っています。

正しい方法:

ビューで

<form action="/Customer/Process">
<% foreach (var customer in Model.Request.Customers)
   { %>
        <input type="checkbox" name="selectedId" value="<%= customer.id %>" />
        <%= customer.name %>
        <br/>
<% } %>
        <input type="submit"/>
</form>

コントローラーで

public string Process(IEnumerable<Guid> selectedId)
{
    if (selectedId == null)
    {
        ModelState.AddModelError("selectedId", "Have to select at least one customer!");

        return View();
    }

    // do something with customers' ids
}
于 2010-08-18T11:34:16.023 に答える
3

カスタム html 拡張クラスを作成し、以下のように CheckBoxFor メソッドをオーバーロードすることができます。このメソッドは、metadata.Model を渡された値 (米国の州など) に評価します。ControllerAction の FormCollection からチェックボックスの値を取得できます。

public ActionResult Edit(FormCollection formCollection) 
{
    // Get the value(s)
    string checkBox = formCollection["State"];

    // perform validation
    ....
}

例では、keyvaluepair ジェネリック リストを想定しています

<% foreach (var element in UnitedStatesDictionary())
{ %>
<%= Html.CheckBoxFor(model => model.State, null, element.Key) %><%= element.Value  %><br />
<% } %>

HtmlExtensions.cs

using System;
using System.Linq;
using System.Linq.Expressions;
using System.Web.Mvc;
using System.Web.Routing;

    public static class HtmlExtensions
    {
        /// <summary>
        /// Checks the box for.
        /// </summary>
        /// <typeparam name="TModel">The type of the model.</typeparam>
        /// <typeparam name="TValue">The type of the value.</typeparam>
        /// <param name="html">The HTML.</param>
        /// <param name="expression">The expression.</param>
        /// <returns>Checkbox</returns>
        public static MvcHtmlString CheckBoxFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
        {
            return CheckBoxFor(html, expression, new RouteDirection());
        }


        /// <summary>
        /// Checks the box for.
        /// </summary>
        /// <typeparam name="TModel">The type of the model.</typeparam>
        /// <typeparam name="TValue">The type of the value.</typeparam>
        /// <param name="html">The HTML.</param>
        /// <param name="expression">The expression.</param>
        /// <param name="htmlAttributes">The HTML attributes.</param>
        /// <returns>Checkbox</returns>
        public static MvcHtmlString CheckBoxFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object htmlAttributes)
        {

            return CheckBoxFor(html, expression, htmlAttributes, "");
        }

        /// <summary>
        /// Checks the box for.
        /// </summary>
        /// <typeparam name="TModel">The type of the model.</typeparam>
        /// <typeparam name="TValue">The type of the value.</typeparam>
        /// <param name="html">The HTML.</param>
        /// <param name="expression">The expression.</param>
        /// <param name="htmlAttributes">The HTML attributes.</param>
        /// <param name="checkedValue">The checked value.</param>
        /// <returns>Checkbox</returns>
        public static MvcHtmlString CheckBoxFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object htmlAttributes, string checkedValue)
        {

            ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
            string htmlFieldName = ExpressionHelper.GetExpressionText(expression);

            TagBuilder tag = new TagBuilder("input");
            tag.Attributes.Add("type", "checkbox");
            tag.Attributes.Add("name", metadata.PropertyName);
            if (!string.IsNullOrEmpty(checkedValue))
            {
                tag.Attributes.Add("value", checkedValue);
            }
            else
            {
                tag.Attributes.Add("value", metadata.Model.ToString());
            }

            if (htmlAttributes != null)
            {
                tag.MergeAttributes(new RouteValueDictionary(htmlAttributes));
            }

            if (metadata.Model.ToString() == checkedValue)
            {
                tag.Attributes.Add("checked", "checked");
            }
            return MvcHtmlString.Create(tag.ToString(TagRenderMode.SelfClosing));
        }
    }

私がそれに取り組んでいる間、コードを完成させるための米国のリストは次のとおりです。

/// <summary>
/// United States dictionary.
/// </summary>
/// <returns>List of United States</returns>
public static List<KeyValuePair<string, string>> UnitedStatesDictionary()
{
    var arrList = new List<KeyValuePair<string, string>>();
    arrList.Add(new KeyValuePair<string, string>("AL", "Alabama"));
    arrList.Add(new KeyValuePair<string, string>("AK", "Alaska"));
    arrList.Add(new KeyValuePair<string, string>("AZ", "Arizona" ));
    arrList.Add(new KeyValuePair<string, string>("AR", "Arkansas" ));
    arrList.Add(new KeyValuePair<string, string>("CA", "California" ));
    arrList.Add(new KeyValuePair<string, string>("CO", "Colorado" ));
    arrList.Add(new KeyValuePair<string, string>("CT", "Connecticut" ));
    arrList.Add(new KeyValuePair<string, string>("DE", "Delaware" ));
    arrList.Add(new KeyValuePair<string, string>("DC", "District Of Columbia" ));
    arrList.Add(new KeyValuePair<string, string>("FL", "Florida" ));
    arrList.Add(new KeyValuePair<string, string>("GA", "Georgia" ));
    arrList.Add(new KeyValuePair<string, string>("HI", "Hawaii" ));
    arrList.Add(new KeyValuePair<string, string>("ID", "Idaho" ));
    arrList.Add(new KeyValuePair<string, string>("IL", "Illinois" ));
    arrList.Add(new KeyValuePair<string, string>("IN", "Indiana" ));
    arrList.Add(new KeyValuePair<string, string>("IA", "Iowa" ));
    arrList.Add(new KeyValuePair<string, string>("KS", "Kansas" ));
    arrList.Add(new KeyValuePair<string, string>("KY", "Kentucky" ));
    arrList.Add(new KeyValuePair<string, string>("LA", "Louisiana" ));
    arrList.Add(new KeyValuePair<string, string>("ME", "Maine" ));
    arrList.Add(new KeyValuePair<string, string>("MD", "Maryland" ));
    arrList.Add(new KeyValuePair<string, string>("MA", "Massachusetts" ));
    arrList.Add(new KeyValuePair<string, string>("MI", "Michigan" ));
    arrList.Add(new KeyValuePair<string, string>("MN", "Minnesota" ));
    arrList.Add(new KeyValuePair<string, string>("MS", "Mississippi" ));
    arrList.Add(new KeyValuePair<string, string>("MO", "Missouri" ));
    arrList.Add(new KeyValuePair<string, string>("MT", "Montana" ));
    arrList.Add(new KeyValuePair<string, string>("NE", "Nebraska" ));
    arrList.Add(new KeyValuePair<string, string>("NV", "Nevada" ));
    arrList.Add(new KeyValuePair<string, string>("NH", "New Hampshire" ));
    arrList.Add(new KeyValuePair<string, string>("NJ", "New Jersey" ));
    arrList.Add(new KeyValuePair<string, string>("NM", "New Mexico" ));
    arrList.Add(new KeyValuePair<string, string>("NY", "New York" ));
    arrList.Add(new KeyValuePair<string, string>("NC", "North Carolina" ));
    arrList.Add(new KeyValuePair<string, string>("ND", "North Dakota" ));
    arrList.Add(new KeyValuePair<string, string>("OH", "Ohio" ));
    arrList.Add(new KeyValuePair<string, string>("OK", "Oklahoma" ));
    arrList.Add(new KeyValuePair<string, string>("OR", "Oregon" ));
    arrList.Add(new KeyValuePair<string, string>("PA", "Pennsylvania" ));
    arrList.Add(new KeyValuePair<string, string>("RI", "Rhode Island" ));
    arrList.Add(new KeyValuePair<string, string>("SC", "South Carolina" ));
    arrList.Add(new KeyValuePair<string, string>("SD", "South Dakota" ));
    arrList.Add(new KeyValuePair<string, string>("TN", "Tennessee" ));
    arrList.Add(new KeyValuePair<string, string>("TX", "Texas" ));
    arrList.Add(new KeyValuePair<string, string>("UT", "Utah" ));
    arrList.Add(new KeyValuePair<string, string>("VT", "Vermont" ));
    arrList.Add(new KeyValuePair<string, string>("VA", "Virginia" ));
    arrList.Add(new KeyValuePair<string, string>("WA", "Washington" ));
    arrList.Add(new KeyValuePair<string, string>("WV", "West Virginia" ));
    arrList.Add(new KeyValuePair<string, string>("WI", "Wisconsin" ));
    arrList.Add(new KeyValuePair<string, string>("WY", "Wyoming" ));
    return arrList;
}
于 2010-08-16T15:24:46.390 に答える
2

そのためにヘルパークラスを使用しました。本当に簡単です。ヘルパー クラスを使用すると、SelectList を使用してヘルパーに配置できます。これは、dropdownfor の場合と同様です。

「Helpers」フォルダーにCheckboxlist.csがあります

    using System;
    using System.Web.Mvc;
    using System.Collections.Generic;
    using System.Text;
    using System.Linq;

    namespace MVC2_NASTEST.Helpers {
        public static class CheckBoxListHelper {

            public static string CheckBoxList(this HtmlHelper helper, string name, IDictionary<string, string> items) {
                return CheckBoxList(helper, name, items, null, null);
            }

            public static string CheckBoxList(this HtmlHelper helper, string name, IDictionary<string, string> items, IDictionary<string, object> checkboxHtmlAttributes) {
                return CheckBoxList(helper, name, items, null, checkboxHtmlAttributes);
            }

            public static string CheckBoxList(this HtmlHelper helper, string name, IDictionary<string, string> items, IEnumerable<string> selectedValues) {
                return CheckBoxList(helper, name, items, selectedValues, null);
            }

            public static string CheckBoxList(this HtmlHelper helper, string name, IDictionary<string, string> items, IEnumerable<string> selectedValues, IDictionary<string, object> checkboxHtmlAttributes) {

                var selectListItems = from i in items
                                      select new SelectListItem {
                                          Text = i.Key,
                                          Value = i.Value,
                                          Selected = (selectedValues != null && selectedValues.Contains(i.Value))
                                      };

                return CheckBoxList(helper, name, selectListItems, checkboxHtmlAttributes);
            }

            public static string CheckBoxList(this HtmlHelper helper, string name, IEnumerable<SelectListItem> items) {
                return CheckBoxList(helper, name, items, null);
            }

            public static string CheckBoxList(this HtmlHelper helper, string name, IEnumerable<SelectListItem> items, IDictionary<string, object> checkboxHtmlAttributes) {
                var output = new StringBuilder();

                foreach (var item in items) {
                    output.Append("<div class=\"fields\"><label>");
                    var checkboxList = new TagBuilder("input");
                    checkboxList.MergeAttribute("type", "checkbox");
                    checkboxList.MergeAttribute("name", name);
                    checkboxList.MergeAttribute("value", item.Value);

                    // Check to see if it's checked
                    if (item.Selected)
                        checkboxList.MergeAttribute("checked", "checked");

                    // Add any attributes
                    if (checkboxHtmlAttributes != null)
                        checkboxList.MergeAttributes(checkboxHtmlAttributes);

                    checkboxList.SetInnerText(item.Text);
                    output.Append(checkboxList.ToString(TagRenderMode.SelfClosing));
                    output.Append("&nbsp; " + item.Text + "</label></div>");
                }

                return output.ToString();
            }
        }
    }

私のコントローラーのコード:

    public static List<SelectListItem> lesgeverList() {
        return lesgeverList(-1);
    }

    public static List<SelectListItem> lesgeverList(int selectedID) {
        return lesgeverList(new int[] { selectedID });
    }

    public static List<SelectListItem> lesgeverList(int[] lg) {
        NASDataContext _db = new NASDataContext();
        var lesg = (from l in _db.Lesgevers
                    where l.LG_Naam != "leeg"
                    orderby l.LG_Naam, l.LG_Vnaam
                    select l).ToSelectList(m => m.LG_Naam + " " + m.LG_Vnaam, m => m.LG_ID.ToString(), m => lg.Contains(m.LG_ID));
        return lesg.ToList();
    }

    //
    // GET: /Projectleiders/Create

    public ActionResult Create(int projID) {
        ViewData["projNaam"] = getProject(projID).Proj_Kortenaam;
        int[] keys = (from p in _db.ProjectleiderProjectens
                      where p.Proj_ID == projID
                      from l in _db.Lesgevers
                      where p.LG_ID == l.LG_ID
                      select l.LG_ID).ToArray();

        ViewData["projleiders"] = MvcApplication.lesgeverList(keys);

        return toegankelijk(projID, null);
    }

    //
    // POST: /Projectleiders/Create

    [HttpPost]
    public ActionResult Create(FormCollection collection, int projID) {

        if (collection["lesgeverlist"] != null) {
            string[] lgevers = collection["lesgeverlist"].Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
            List<ProjectleiderProjecten> lst = new List<ProjectleiderProjecten>();
            foreach (string s in lgevers) {
                ProjectleiderProjecten prl = new ProjectleiderProjecten();
                prl.LG_ID = int.Parse(s);
                prl.Proj_ID = projID;

                int count = (from m in _db.ProjectleiderProjectens
                             where m.LG_ID == prl.LG_ID && m.Proj_ID == prl.Proj_ID
                             select m).Count();

                if (count <= 0) {
                    //deze bestaat nog niet
                    lst.Add(prl);
                }
            }
            //var test = _db.ProjectleiderProjectens.Where(p => p.Proj_ID == projID && !lgevers.Contains(p.LG_ID.ToString())).ToList();

            _db.ProjectleiderProjectens.DeleteAllOnSubmit(_db.ProjectleiderProjectens.Where(p => p.Proj_ID == projID && !lgevers.Contains(p.LG_ID.ToString())));

            _db.ProjectleiderProjectens.InsertAllOnSubmit(lst);
            _db.SubmitChanges();

            return RedirectToAction("Index");
        } else {

            ModelState.AddModelError("lesgeverlist", "Je hebt geen lesgevers geselecteerd");

            ViewData["projleiders"] = MvcApplication.lesgeverList();
            ViewData["projNaam"] = getProject(projID).Proj_Kortenaam;
            return View();
        }
    }

私は誰もが持つべき ToSelectList 拡張機能を使用しています。

public static class VSKOExtensions {
    public static IList<SelectListItem> ToSelectList<T>(this IEnumerable<T> itemsToMap, Func<T, string> textProperty, Func<T, string> valueProperty, Predicate<T> isSelected) {
        var result = new List<SelectListItem>();

        foreach (var item in itemsToMap) {
            result.Add(new SelectListItem {
                Value = valueProperty(item),
                Text = textProperty(item),
                Selected = isSelected(item)
            });
        }
        return result;
    }
}

私の作成ビュー(同時に編集ビューでもある)のコードは非常に単純です

    <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MVC2_NASTEST.Models.ProjectleiderProjecten>" %>
    <%@ Import Namespace="MVC2_NASTEST.Helpers" %>

    <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
        Create
    </asp:Content>

    <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

        <h2>Koppel projectleider voor
            <%= ViewData["projNaam"].ToString() %></h2>

        <% using (Html.BeginForm()) {%>
            <%= Html.ValidationSummary(true) %>

            <fieldset>
                <legend>Fields</legend>

                <div class="editor-label">
                    <%= Html.Label("Lesgevers")%>
                </div>
                <div class="editor-field">
                    <%= Html.CheckBoxList("Lesgeverlist", ViewData["projleiders"] as List<SelectListItem>)%>
                    <%= Html.ValidationMessage("Lesgeverlist")%>
                </div>

                <p>
                    <input type="submit" value="Create" />
                </p>
            </fieldset>

        <% } %>

        <div>
            <%= Html.ActionLink("Back to List", "Index") %>
        </div>

    </asp:Content>

使い方:

すでに選択されているユーザーの DB から値を取得し、ID を取得して、メソッド MvcApplication.lesgeverList(keys) に渡します。

次に、選択リストを取得し、それをビューデータに入れます。選択した人は、開いたときにビューで選択されます。次に、いくつかのボックスを変更して保存すると、コレクションがnullではないかどうかを確認し(何かが選択されている)、返された変数を分割します。これは、SelectListで指定した「値」です。私はそれらをforeachし、それらをintに解析し、解析されたIDでDBからユーザーを取得します。カウントを使用して、_db.ProjectleiderProjectens と呼ばれる「リンクされた」テーブルにそれらが存在するかどうかを確認します

すべてが追加されたら、linq ステートメントを使用して、すべての「選択されていない」ものを一度に削除します

   _db.ProjectleiderProjectens.DeleteAllOnSubmit(_db.ProjectleiderProjectens.Where(p => p.Proj_ID == projID && !lgevers.Contains(p.LG_ID.ToString())));

これはかなり読みやすいと思います。すべてのオブジェクトを削除し、すべてのオブジェクトの ID を取得し、ID の string[] に含まれていないオブジェクトを確認します

それはかなりうまく機能します。さらに質問がある場合は、お尋ねください。

于 2010-08-17T13:10:57.813 に答える
0

クライアント側でjQuery検証を使用してから、サーバー側で自分自身を再確認するには、フォームコレクションに値が入力されていることを確認してください。

forループに問題はありません。

于 2010-08-18T01:01:03.107 に答える