• MVC生成CheckBoxList并对其验证


    通过扩展方法,可以让CheckBox水平排列,生成CheckBoxList,正如"MVC扩展生成CheckBoxList并水平排列"一文。但,如何对生成的CheckBoxList验证呢?比如要求至少勾选一项:
    1

     

    □ 思路

    在强类型视图页中,@Html.EditorFor(model => model.属性, "模版名称", new{ ...路由数据...}),模版名称对应Views/Shared/EditorTemplates/CheckBoxList.cshtml部分视图,路由数据用来传递生成CheckBoxList所需要的一切,并在CheckBoxList.cshtml中显示错误信息,最后CheckBoxList的生成交给扩展方法。


    □ Model

        public class Course
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }

    using System.ComponentModel.DataAnnotations;

    namespace MvcApplication1.Models
    {
        public class Student
        {
            [Display(Name = "姓名")]
            [Required(ErrorMessage = "必填")]
            [StringLength(100, ErrorMessage = "最大长度100")]
            public string Name { get; set; }

            [Display(Name = "所选课程")]
            [Required(ErrorMessage = "至少选择一个课程")]
            public string Courses{ get; set; }
        }
    }

     

    □ 在_Layout.cshtml中启用客户端异步验证

        @Scripts.Render("~/bundles/jquery")
        @Scripts.Render("/bundles/jqueryval") //启用客户端异步验证
        @RenderSection("scripts", required: false)

     

    □ Home/Index.cshtml

    @using MvcApplication1.Infrastructure.Enums
    @model MvcApplication1.Models.Student
     
    @{
        ViewBag.Title = "Index";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
     
    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()
        @Html.ValidationSummary(true)
     
        <fieldset>
            <legend>Student</legend>
            <div class="editor-label">
                @Html.LabelFor(model => model.Name)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.Name)
                @Html.ValidationMessageFor(model => model.Name)
            </div>
            
            <div class="editor-label">
                @Html.LabelFor(model => model.Courses)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.Courses, "CheckBoxList", new
                {
                    TagName = "Courses",
                    CheckBoxItems = ViewBag.Course,
                    Position = Position.Horizontal,
                    Numbers = 3
                })
            </div>
            
            <p>
                <input type="submit" value="创建"/>
            </p>
        </fieldset>
    }
     

    其中,用到了有关CheckBoxList水平或垂直排列的一个枚举:

    namespace MvcApplication1.Infrastructure.Enums
    {
        public enum Position
        {
            Horizontal,
            Vertical
        }
    }  

    生成CheckBoxList的路由数据,以及模版名称:

                @Html.EditorFor(model => model.Courses, "CheckBoxList", new
                {
                    TagName = "Courses",
                    CheckBoxItems = ViewBag.Course,
                    Position = Position.Horizontal,
                    Numbers = 3
                })

     

    □ Views/Shared/EditorTemplates/CheckBoxList.cshtml

    @using MvcApplication1.Infrastructure.Enums
    @{
        var required = false;
        object validationMessage = string.Empty;
     
        //获取客户端验证属性
        var validationAttributes = Html.GetUnobtrusiveValidationAttributes(""); 
        if (validationAttributes.ContainsKey("data-val") && validationAttributes.ContainsKey("data-val-required"))
        {
            required = true;
            if (!validationAttributes.TryGetValue("data-val-required", out validationMessage))
            {
                validationMessage = "This field is required.";
            }
            validationAttributes.Add("required","required");
        }
     
        var tagName = ViewData["TagName"] == null ? "CheckBoxList" : (string)ViewData["TagName"];
        var checkboxItems = ViewData["CheckBoxItems"] == null ? new List<SelectListItem>() : (IEnumerable<SelectListItem>)ViewData["CheckBoxItems"];
        var position = ViewData["Position"] == null ? Position.Horizontal : (Position)ViewData["Position"];
     
        var numbers = 0;
        if (ViewData["Numbers"] == null)
        {
            numbers = 1;
        }
        else if (!int.TryParse(ViewData["Numbers"].ToString(), out numbers))
        {
            numbers = 1;
        }
        else
        {
            numbers = (int)ViewData["Numbers"];
        }
    }
     
    @Html.CheckBoxList(
    tagName,
    checkboxItems,
    new RouteValueDictionary(validationAttributes),
    position,
    numbers)
     
    @if (required)
    {
        <span class="field-validation-valid" data-valmsg-for="@(tagName)" data-valmsg-replace="false">
            @validationMessage
        </span>
    }
     

     

    □ 生成CheckBoxList的扩展方法

    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using MvcApplication1.Infrastructure.Enums;
     
    namespace System.Web.Mvc
    {
        public static class CheckBoxListExtensions
        {
            #region 水平方向
            /// <summary>
            /// CheckBoxList
            /// </summary>
            /// <param name="htmlHelper">HTML helper</param>
            /// <param name="name"></param>
            /// <param name="listInfo"></param>
            /// <param name="htmlAttributes"></param>
            /// <param name="number">每行显式的个数</param>
            /// <returns></returns>
            public static MvcHtmlString CheckBoxList(this HtmlHelper htmlHelper,
                string name,
                IEnumerable<SelectListItem> listInfo,
                IDictionary<string, object> htmlAttributes,
                int number)
            {
                if (string.IsNullOrEmpty(name))
                {
                    throw new ArgumentException("必须给CheckBoxList一个name值", "name");
                }
                if (listInfo == null)
                {
                    throw new ArgumentNullException("listInfo", "List<SelectListItem> listInfo不能为null");
                }
     
                var selectListItems = listInfo as SelectListItem[] ?? listInfo.ToArray();
                if (!selectListItems.Any())
                {
                    throw new ArgumentException("List<SelectListItem> listInfo 至少有一组资料", "listInfo");
                }
     
                var sb = new StringBuilder();
                var lineNumber = 0;
                foreach (var info in selectListItems)
                {
                    lineNumber++;
                    var builder = new TagBuilder("input");
                    if (info.Selected)
                    {
                        builder.MergeAttribute("checked", "checked");
                    }
                    builder.MergeAttributes(htmlAttributes);
                    builder.MergeAttribute("type", "checkbox");
                    builder.MergeAttribute("value", info.Value);
                    builder.MergeAttribute("name", name);
                    builder.MergeAttribute("id", string.Format("{0}_{1}", name, info.Value));
                    sb.Append(builder.ToString(TagRenderMode.Normal));
     
                    var labelBuilder = new TagBuilder("label");
                    labelBuilder.MergeAttribute("for", string.Format("{0}_{1}", name, info.Value));
                    labelBuilder.InnerHtml = info.Text;
                    sb.Append(labelBuilder.ToString(TagRenderMode.Normal));
     
                    if (number == 0 || (lineNumber % number == 0))
                    {
                        sb.Append("<br />");
                    }
                }
                return MvcHtmlString.Create(sb.ToString());
            }
     
            public static MvcHtmlString CheckBoxList(this HtmlHelper htmlHelper,
                string name,
                IEnumerable<SelectListItem> listInfo)
            {
                return htmlHelper.CheckBoxList(name, listInfo, (IDictionary<string, object>) null, 0);
            }
            #endregion
     
            #region 垂直方向
     
            public static MvcHtmlString CheckBoxListVertical(this HtmlHelper htmlHelper,
                string name,
                IEnumerable<SelectListItem> listInfo,
                IDictionary<string, object> htmlAttributes,
                int columnNumber = 1)
            {
                if (string.IsNullOrEmpty(name))
                {
                    throw new ArgumentException("必须给CheckBoxList的name属性赋值", "name");
                }
                if (listInfo == null)
                {
                    throw new ArgumentNullException("listInfo", "List<SelectListInfo> listInfo不能为null");
                }
     
                var selectListItmes = listInfo as SelectListItem[] ?? listInfo.ToArray();
                if (!selectListItmes.Any())
                {
                    throw new ArgumentException("List<SelectListItem> listInfo不能为null","listInfo");
                }
     
                var dataCount = selectListItmes.Count();
                var rows = Convert.ToInt32(Math.Ceiling(Convert.ToDecimal(dataCount)/Convert.ToDecimal(columnNumber)));
                if (dataCount <= columnNumber || dataCount - columnNumber == 1)
                {
                    rows = dataCount;
                }
     
                var wrapBuilder = new TagBuilder("div");
                wrapBuilder.MergeAttribute("style","float:left; line-height:25px; padding-right:5px;");
                var wrapStart = wrapBuilder.ToString(TagRenderMode.StartTag);
                var wrapClose = string.Concat(wrapBuilder.ToString(TagRenderMode.EndTag),
                    " <div style="clear:both;"></div>");
                var wrapBreak = string.Concat("</div>", wrapBuilder.ToString(TagRenderMode.StartTag));
     
                var sb = new StringBuilder();
                sb.Append(wrapStart);
     
                var lineNumber = 0;
                foreach (var info in selectListItmes)
                {
                    var builder = new TagBuilder("input");
                    if (info.Selected)
                    {
                        builder.MergeAttribute("checked","checked");
                    }
                    builder.MergeAttributes(htmlAttributes);
                    builder.MergeAttribute("type","checkbox");
                    builder.MergeAttribute("value", info.Value);
                    builder.MergeAttribute("name", name);
                    builder.MergeAttribute("id", string.Format("{0}_{1}",name, info.Value));
                    sb.Append(builder.ToString(TagRenderMode.Normal));
     
                    var labelBuilder = new TagBuilder("label");
                    labelBuilder.MergeAttribute("for", string.Format("{0}_{1}", name, info.Value));
                    labelBuilder.InnerHtml = info.Text;
                    sb.Append(labelBuilder.ToString(TagRenderMode.Normal));
     
                    lineNumber++;
     
                    if (lineNumber.Equals(rows))
                    {
                        sb.Append(wrapBreak);
                        lineNumber = 0;
                    }
                    else
                    {
                        sb.Append("<br />");
                    }
                }
                sb.Append(wrapClose);
                return MvcHtmlString.Create(sb.ToString());
            }
            #endregion
     
            #region 水平或垂直方向
     
            public static MvcHtmlString CheckBoxList(this HtmlHelper htmlHelper,
                string name,
                IEnumerable<SelectListItem> listInfo,
                IDictionary<string, object> htmlAttributes,
                Position position = Position.Horizontal,
                int number = 0)
            {
                if (string.IsNullOrEmpty(name))
                {
                    throw new ArgumentException("必须给CheckBoxList的name属性赋值","name");
                }
                if (listInfo == null)
                {
                    throw new ArgumentNullException("listInfo", "List<SelectListItem> listInfo不能为null");
                }
                var selectListItems = listInfo as SelectListItem[] ?? listInfo.ToArray();
                if (!selectListItems.Any())
                {
                    throw new ArgumentException("List<SelectListItem> listInfo至少要一组资料","listInfo");
                }
     
                var sb = new StringBuilder();
                var lineNumber = 0;
                switch (position)
                {
                    case Position.Horizontal:
                        foreach (var info in selectListItems)
                        {
                            lineNumber++;
                            sb.Append(CreateCheckBoxItem(info, name, htmlAttributes));
     
                            if (number == 0 || (lineNumber%number == 0))
                            {
                                sb.Append("<br />");
                            }
                        }
                        sb.Append("<br />");
                        break;
                    case Position.Vertical:
                        var dataCount = selectListItems.Count();
                        var rows = Convert.ToInt32(Math.Ceiling(Convert.ToDecimal(dataCount)/Convert.ToDecimal(number)));
                        if (dataCount <= number || dataCount - number == 1)
                        {
                            rows = dataCount;
                        }
     
                        var wrapBuilder = new TagBuilder("div");
                        wrapBuilder.MergeAttribute("style","float:left; line-height:25px; padding-right:5px;");
                        var wrapStart = wrapBuilder.ToString(TagRenderMode.StartTag);
                        var wrapClose = string.Concat(wrapBuilder.ToString(TagRenderMode.EndTag), " <div style="clear:both;"></div>");
                        var wrapBreak = string.Concat("</div>", wrapBuilder.ToString(TagRenderMode.StartTag));
                        sb.Append(wrapStart);
     
                        foreach (var info in selectListItems)
                        {
                            lineNumber++;
                            sb.Append(CreateCheckBoxItem(info, name, htmlAttributes));
     
                            if (lineNumber.Equals(rows))
                            {
                                sb.Append(wrapBreak);
                                lineNumber = 0;
                            }
                            else
                            {
                                sb.Append(wrapClose);
                            }
                        }
                        sb.Append(wrapClose);
                        break;
                }
                return MvcHtmlString.Create(sb.ToString());
            }
     
            internal static string CreateCheckBoxItem(SelectListItem info, string name,
                IDictionary<string, object> htmlAttributes)
            {
                var sb = new StringBuilder();
                var builder = new TagBuilder("input");
                if (info.Selected)
                {
                    builder.MergeAttribute("checked","checked");
                }
                builder.MergeAttributes(htmlAttributes);
                builder.MergeAttribute("type", "checkbox");
                builder.MergeAttribute("value", info.Value);
                builder.MergeAttribute("name", name);
                builder.MergeAttribute("id", string.Format("{0}_{1}", name, info.Value));
                sb.Append(builder.ToString(TagRenderMode.Normal));
     
                var labelBuilder = new TagBuilder("label");
                labelBuilder.MergeAttribute("for", string.Format("{0}_{1}", name, info.Value));
                labelBuilder.InnerHtml = info.Text;
                sb.Append(labelBuilder.ToString(TagRenderMode.Normal));
     
                return sb.ToString();
            }
            #endregion
        }
    }
     

     

    □ HomeController

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using MvcApplication1.Infrastructure.Services;
    using MvcApplication1.Models;
     
    namespace MvcApplication1.Controllers
    {
        public class HomeController : Controller
        {
            private readonly  CourseService service = new CourseService();
     
            private List<SelectListItem> coursesSelectListItems
            {
                get
                {
                    var courses = this.service.GetCourses();
                    var items = new List<SelectListItem>();
                    foreach (var c in courses)
                    {
                        items.Add(new SelectListItem()
                        {
                            Value = c.Id.ToString(),
                            Text = c.Name
                        });
                    }
                    return items;
                }
     
            }
     
            public ActionResult Index()
            {
                ViewBag.Course = this.coursesSelectListItems;
                return View();
            }
     
            [HttpPost]
            [ValidateAntiForgeryToken]
            public ActionResult Index(Student stu)
            {
                ViewBag.Course = this.coursesSelectListItems;
                if (ModelState.IsValid)
                {
                    return View();
                }
                return View(stu);
            }
     
        }
    }
     

     

    □ CouseService.cs

    using System.Collections.Generic;
    using MvcApplication1.Models;
     
    namespace MvcApplication1.Infrastructure.Services
    {
        public class CourseService
        {
            public IEnumerable<Course> GetCourses()
            {
                return new List<Course>()
                {
                    new Course(){Id = 1, Name = "语文"},
                    new Course(){Id = 2, Name = "数学"},
                    new Course(){Id = 3, Name = "哲学"},
                    new Course(){Id = 4, Name = "英语"},
                    new Course(){Id = 5,Name = "法语"},
                    new Course(){Id = 6, Name = "物理"},
                    new Course(){Id = 7, Name = "化学"},
                    new Course(){Id = 8, Name = "工程"}
                };
            }
        }
    }            
     


    参考资料:
    ASP.NET MVC - CheckBoxList与ValidationMessage

  • 相关阅读:
    在eclipse创建android project,最后一步点击finish没反应
    有哪些可以将网页另存图片的chrome插件?功能类似网页截图
    极品家丁—优酷全网独播喜剧
    如何安装chrome扩展?比如json-handle插件如何安装
    安装用户脚本的福音:Tampermonkey(油猴)
    多微博账号同时发微博的插件--fawave
    正能量-真正男子汉2
    如何看待优酷广告?
    秋雨连绵思晚天
    如何用Postman组装Request并且查看Response
  • 原文地址:https://www.cnblogs.com/darrenji/p/3741037.html
Copyright © 2020-2023  润新知