ASP.NET MVC 3 使用Model自定义验证的样式

1.修改jquery.validate.unobtrusive.js

将onError方法修改

 //修改的部分
    ///////////////////////////////////////////////////////////////////




    function onError(error, inputElement) {  // 'this' is the form element
        var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"),
            replaceAttrValue = container.attr("data-valmsg-replace"),
            replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null;
        //add
        var $customErrorTip = container.attr("data-forerrortip");
        container.removeClass("field-validation-valid").addClass("field-validation-error");
        error.data("unobtrusiveContainer", container);
        //add
        var elem = $("#" + inputElement[0].name.replace(".", "_"));//添加提示消息
        if (replace) {
            container.empty();
            //add start
            if (error.html() != "") {
                if ($customErrorTip) {
                    $("#" + $customErrorTip).poshytip("destroy");
                } else {
                    elem.poshytip("destroy");
                }
                var direction = "right";
                //左边+元素宽+提示的文字+提示两边的空白
                if ((elem[0].offsetLeft + elem.width() + error.length * 10 + 20) > $(document).width()) {
                    direction = "left";
                }
                var errorConfig = {
                    content: error,
                    alignTo: 'target',
                    alignX: direction,
                    alignY: 'center',
                    showOn: 'none',
                    bgImageFrameSize: 7,
                    offsetX: 5
                };
                if ($customErrorTip) {
                    $("#" + $customErrorTip).poshytip(errorConfig).poshytip('show');
                } else {
                    elem.filter(':not(.valid)').poshytip(errorConfig).poshytip('show');
                }
            } else {
                if ($customErrorTip) {
                    $("#" + $customErrorTip).poshytip("destroy");
                } else {
                    elem.poshytip("destroy");
                }
            }
            //add end
            //update disable
            //error.removeClass("input-validation-error").appendTo(container);
        }
        else {
            error.hide();
        }
    }



    ///////////////////////////////////////////////////////////////////////////////////

2.Index.cshtml页面

@model MvcApplication1.Models.UserViewModel

@{
    ViewBag.Title = "Index";
    
}
<link href="~/Content/poshytip/tip-yellow/tip-yellow.css" rel="stylesheet" />
<script src="~/Scripts/jquery-1.7.1.min.js"></script>
<script src="~/Content/poshytip/jquery.poshytip.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>

<script type="text/javascript">
    function showTip(objJq, msg) {
        objJq.poshytip('destroy');
        if (!objJq.data("poshytip")) {
            objJq.poshytip({
                showOn: 'none',
                alignTo: 'target',
                alignX: 'right',
                alignY: 'center',
                offsetX: 5,
                className: 'tip-yellow',
                content:msg
            });
            objJq.focus(function () {
                $(this).poshytip('hide');
            });
            objJq.data("poshytip").$tip.click(function () {
                $(this).hide();
            });
        }
        objJq.poshytip('show');
    }
    $(function () {
        $("#btnTest").click(function () {
            if ($("#myfrom").valid()) {
                $.post("@Url.Action("Create","Home")", $("#myfrom").serializeArray(), function (data) {
                    if (data.Status==3) {
                        $(data.Msg).each(function () {
                            var item = $('#' + this.Key);
                            showTip(item, this.Value);
                        });
                    } else {
                        alert(data);
                    }
                });
            }
        });
    });

</script>

@using (Html.BeginForm("Create", "Home", FormMethod.Post, new { id = "myfrom" }))
{
        
    <label>用户名:</label> @Html.TextBoxFor(u => u.UserName)@Html.ValidationMessageFor(u => u.UserName)
    <br />
    <label>性别:</label>@*
     @Html.RadioButtonFor(u=>u.Sex,1,new{ @checked="checked"})@:男*@
    @Html.RadioButtonFor(u=>u.Sex,1)@:男
    @Html.RadioButtonFor(u=>u.Sex,2)@:女 
    <span id="groupRadioErrorSex" style="vertical-align:middle;line-height:70px;">&nbsp;</span>
        @Html.ValidationMessageFor(u => u.Sex,"", new{data_forErrorTip="groupRadioErrorSex" })
    <br />
    <input type="button" value="提交" id="btnTest" />
}

3.HomeController

public class HomeController : Controller
    {
        //
        // GET: /Home/
     

        public ActionResult Index()
        {
            return View(new UserViewModel() { IsEnable = false, UserCode = "aa" });
        }

        [HttpPost]
        public ActionResult Create(UserViewModel model)
        {
            //移除添加了Request属性,却又不需要验证的属性
            ModelState.Remove("UserCode");
            ModelState.Remove("UserPwd");
            ModelState.Remove("County");
            if (!ModelState.IsValid)
            {
                //服务器端自定义添加错误验证
                ModelState.AddModelError("UserName", "您输入的账号已被使用");
                return Json(new { Status = 3, Msg = ModelState.GetErrorsDict() });
            }
            return Json("ok");
        }

        /// <summary>
        /// 远程验证用户名
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        public ActionResult GetUser(string username)
        {
            return Json(!username.ToLower().Equals("admin"),JsonRequestBehavior.AllowGet);//返回True表示通过验证,返回False表示不通过验证
        }
    }

    public static class HelperExtensions
    {

        public static List<KeyValuePair<string, string>> GetErrorsDict(this ModelStateDictionary modelState)
        {
            var errorList = (from item in modelState
                             where item.Value.Errors.Any()
                             select new KeyValuePair<string, string>(item.Key, item.Value.Errors[0].ErrorMessage)).ToList();

            return errorList;
        }
    }

4.UserViewModel

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Mvc;

namespace MvcApplication1.Models
{
    public class UserViewModel
    {
        

        /// <summary>
        /// Id
        /// </summary>
        public int Id { get; set; }
        /// <summary>
        /// FK-用户级别ID
        /// </summary>
        [Required(AllowEmptyStrings = false, ErrorMessage = "请选择用户等级")]
        public int LevelId { get; set; }
        /// <summary>
        /// 用户类型  详见文档
        /// </summary>
        public int Type { get; set; }
        /// <summary>
        /// 用户编号
        /// </summary>
        [Required()]
        public string UserCode { get; set; }
        /// <summary>
        /// 用户名
        /// </summary>
        [Required(ErrorMessage = "用户名必需填写")]
        [MobileOrEmail(ErrorMessage="输入手机号或邮箱")]
        [StringLength(50, ErrorMessage = "用户名最大不能超过50个字符")]
        [Remote("GetUser", "Home", ErrorMessage = "该姓名已存在")]   
        public string UserName { get; set; }
        /// <summary>
        /// 密码
        /// </summary>
        [Required(ErrorMessage = "密码不能为空")]
        public string UserPwd { get; set; }
        /// <summary>
        /// 确认密码
        /// </summary>
        public string ConfirmUserPwd { get; set; }
        /// <summary>
        /// 第三方绑定会员ID
        /// </summary>
        public string ThirdSiteUserId { get; set; }
        /// <summary>
        /// 真实姓名
        /// </summary>
        public string TrueName { get; set; }
        /// <summary>
        /// 昵称
        /// </summary>
        public string NickName { get; set; }
        /// <summary>
        /// 头像
        /// </summary>
        public string UserAvatar { get; set; }
        /// <summary>
        ////// </summary>
        public string Province { get; set; }
        /// <summary>
        ////// </summary>
        public string City { get; set; }
        /// <summary>
        /// 区县
        /// </summary>
        [Required(ErrorMessage="不能为空")]
        [System.ComponentModel.DataAnnotations.Compare("City")]
        public string County { get; set; }
        /// <summary>
        /// 地址
        /// </summary>
        public string Address { get; set; }
        /// <summary>
        /// 邮编
        /// </summary>
        public string Zip { get; set; }
        /// <summary>
        /// 电话
        /// </summary>
        public string Tel { get; set; }
        /// <summary>
        /// 手机
        /// </summary>
        [RegularExpression(@"^1[3|4|5|8][0-9]d{8}$", ErrorMessage = "手机格式错误")]
        public string Mobile { get; set; }
        /// <summary>
        /// 邮箱
        /// </summary>
        public string Email { get; set; }
        /// <summary>
        /// 性别
        /// </summary>
        [Required(ErrorMessage="请选择性别")]
        public string Sex { get; set; }
        /// <summary>
        /// 出生日期
        /// </summary>
        public Nullable<System.DateTime> Birthday { get; set; }
        /// <summary>
        /// 是否启用
        /// </summary>
        public bool IsEnable { get; set; }

        public SelectList UserLevelList { get; set; }
        public IList<SelectListItem> ProvinceList { get; set; }

        
    }

    /// <summary>
    /// 自定义验证属性,手机号或者邮箱 
    /// </summary>
    public class MobileOrEmailAttribute : RegularExpressionAttribute, IClientValidatable
    {
        public MobileOrEmailAttribute()
            : base(RegexHelper.MobileOrEmailPattern) { }

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            var rule = new ModelClientValidationRule
            {
                ValidationType = "regex",
                ErrorMessage = ErrorMessage,
            };

            rule.ValidationParameters.Add("pattern", Pattern);
            yield return rule;
        }
    }

    public static class RegexHelper
    {
        public static readonly string SlugPattern = @"(^[a-z0-9])([a-z0-9-]+)*([a-z0-9])$";
        public static readonly Regex SlugRegex = new Regex(SlugPattern);

        public static readonly string SlugWithSegmentsPattern = @"^(?!-)[a-z0-9-]+(?<!-)(/(?!-)[a-z0-9-]+(?<!-))*$";
        public static readonly Regex SlugWithSegmentsRegex = new Regex(SlugWithSegmentsPattern);

        public static readonly string IpAddressPattern = @"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$";
        public static readonly Regex IpAddressRegex = new Regex(IpAddressPattern);

        public static readonly string MobilePattern = @"^1[3|4|5|8][0-9]d{8}$";
        public static readonly Regex MobileRegex = new Regex(MobilePattern);

        // 密码必需由英文字母、数字或特殊符号组成 6~16个字符,区分大小写
        public static readonly string PasswordPattern = @"^[w~!@#$%^&*()_+|{}:""<>?`-=\[];',./]{6,16}$";
        public static readonly Regex PasswordRegex = new Regex(PasswordPattern);

        public static readonly string EmailPattern = @"^([a-zA-Z0-9_-.]+)@(([[0-9]{1,3}" +
                                                    @".[0-9]{1,3}.[0-9]{1,3}.)|(([a-zA-Z0-9-]+" +
                                                    @".)+))([a-zA-Z]{2,4}|[0-9]{1,3})(]?)$";
        public static readonly Regex EmailRegex = new Regex(EmailPattern);

        public static readonly string UrlPattern = @"^(https?://)?([da-z.-]+).([a-z.]{2,6})([/w .-]*)*/?$";
        public static readonly Regex UrlRegex = new Regex(UrlPattern);

        public static readonly string NumberPattern = @"^-?(?:d+|d{1,3}(?:,d{3})+)(?:.d+)?$";
        public static readonly Regex NumberRegex = new Regex(NumberPattern);

        public static readonly string MobileOrEmailPattern = string.Format("({0}|({1}))", MobilePattern, EmailPattern);
    }
}
原文地址:https://www.cnblogs.com/yxlblogs/p/3611438.html