代码之家  ›  专栏  ›  技术社区  ›  Fabian

如何使用带验证的IEnumerable<t>的html.checkbox(list)

  •  6
  • Fabian  · 技术社区  · 14 年前

    我正在开发一个页面,用户需要在其中填写一些信息,最后用复选框选择一个或多个客户。

    客户名单是 IEnumerable<Customer> 我把它传给我的模特。如何使用创建复选框列表 .CheckBoxFor() ?

    最后,我希望能够验证是否至少选中了一个复选框。

    请求是保存用户输入信息的对象。

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

    有人能给我指出正确的方向吗?或者我说的都是错的?

    4 回复  |  直到 11 年前
        1
  •  3
  •   gnome    14 年前

    您可以创建一个自定义的HTML扩展类,并为如下方法重载checkbox。该方法将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 />
    <% } %>
    

    HTML扩展.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;
    }
    
        2
  •  3
  •   Alexander Prokofyev    14 年前

    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
    }
    
        3
  •  2
  •   Stefanvds    14 年前

    我用了一个助手类。真的很简单。使用helper类,您可以使用selectlist并将其放入helper中,就像使用DropDownfor一样。

    在“helpers”文件夹中,我有checkbox list.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>
    

    它是如何工作的:

    我从已经选择的用户的数据库中获取值,获取他们的ID,并将其赋给mvcaplication.lesgeverlist(keys)方法;

    然后我返回选择列表,将其放在视图数据中,当我打开它时,所选人员在我的视图中被选中。然后,当我更改一些框并保存它时,我检查集合是否不为空(因此选择了一些内容),然后我拆分返回的变量,这些变量是您在SelectList中给出的“值”。我通过它们,将它们解析为int,从db中获取用户及其解析ID。通过计数,我查看它们是否存在于“链接”表中,该表称为db.projectleiderprojectens

    当全部添加后,我将使用LINQ语句在1次内删除所有未选中的

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

    我觉得它可读性很好。从中删除所有对象,获取所有对象的ID,并检查哪些对象不在ID的字符串[]中

    我得说,它工作得相当好。如果你还有什么问题,就问吧。

        4
  •  0
  •   Martin Murphy    14 年前

    只需在客户端使用jquery validate,然后在服务器端对自己进行双重检查,只需确保表单集合中填充了一个值。

    你的for循环没有问题。