原文:MVC验证13-2个属性至少输入一项

有时候,我们希望2个属性中,至少有一个是必填,比如:

using Car.Test.Portal.Extension;
 
namespace Car.Test.Portal.Models
{
    public class Person
    {
        public int Id { get; set; }
        public string Telephone { get; set; }
        public string Address { get; set; }
    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

如果让Telephone和Address属性中,有一个是必填项,需要自定义特性。

 

□ 自定义AtLeastOneAttribute特性,派生于ValidationAttribute类,并实现IClientValidatable接口

using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Web.Mvc;
 
namespace Car.Test.Portal.Extension
{
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
    public sealed class AtLeastOneAttribute : ValidationAttribute, IClientValidatable
    {
        public string PrimaryProperty { get; private set; }
        public string SecondaryProperty { get; private set; }
 
        public AtLeastOneAttribute(string primaryProperty, string secondProperty)
        {
            PrimaryProperty = primaryProperty;
            SecondaryProperty = secondProperty;
        }
 
        public override string FormatErrorMessage(string name)
        {
            return string.Format(CultureInfo.CurrentCulture, this.ErrorMessageString, PrimaryProperty, SecondaryProperty);
        }
 
        public override bool IsValid(object value)
        {
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value);
            object primaryValue = properties.Find(PrimaryProperty, true /* ignoreCase */).GetValue(value);
            object secondaryValue = properties.Find(SecondaryProperty, true /* ignoreCase */).GetValue(value);
            if (primaryValue != null || secondaryValue != null)
            {
                return true;
            }
            else
            {
                return false;
            }
            //return (primaryValue != null || secondaryValue != null);
 
            //稍稍改动以下还可以比较2个属性是否相等
            //if (!primaryValue.Equals(secondaryValue))
            //    return true;
            //else
            //    return false;
        }
 
        public System.Collections.Generic.IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            string errorMessage = FormatErrorMessage("");
            ModelClientValidationRule rule = new ModelClientValidationRule()
            {
                ValidationType = "atleastone",
                ErrorMessage = errorMessage
            };
            rule.ValidationParameters.Add("primary", this.PrimaryProperty);
            rule.ValidationParameters.Add("secondary", this.SecondaryProperty);
            yield return rule;
        }
    }
}
 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

□ 把自定义特性AtLeastOneAttribute打到类上

using Car.Test.Portal.Extension;
 
namespace Car.Test.Portal.Models
{
    [AtLeastOne("Telephone", "Address",ErrorMessage = "Telephone和Address至少填一项~~")]
    public class Person
    {
        public int Id { get; set; }
        public string Telephone { get; set; }
        public string Address { get; set; }
    }
}
 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

□ PersonController

    public class PersonController : Controller
    {
        public ActionResult Index()
        {
            return View(new Person());
        }
 
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Index(Person person)
        {
            if (ModelState.IsValid)
            {
                //TODO:
                return Content("ok");
            }
            else
            {
                return View(person);
            }
        }
    }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

□ Person/Index.cshtml

需要把自定义的特性注册到jquery相关类库中。

@model Car.Test.Portal.Models.Person
 
<body>
    <script src="~/Scripts/jquery-1.10.2.js"></script>
    <script src="~/Scripts/jquery-migrate-1.2.1.min.js"></script>
    <script src="~/Scripts/jquery.validate.min.js"></script>
    <script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
    @*<script src="~/Scripts/atleastone.js"></script>*@
    <style type="text/css">
        .validation-summary-errors {
            color: red;
        }
    </style>
    <script type="text/javascript">
        jQuery.validator.addMethod("atleastone", function (value, element, params) {
            var primaryProperty = params.primary;
            var secondaryProperty = params.secondary;
 
            if (primaryProperty.length > 0 || secondaryProperty.length > 0) {
                return true;
            } else {
                return false;
            }
        });
 
        jQuery.validator.unobtrusive.adapters.add("atleastone", ["primary", "secondary"], function (options) {
            options.rules["atleastone"] = {
                primary: options.params.primary,
                secondary: options.params.secondary
            };
            options.messages["atleastone"] = options.message;
        });
        
    </script>
    
    @using (Html.BeginForm()) {
        @Html.AntiForgeryToken()
        @Html.ValidationSummary(true)
       
    
        <fieldset>
            <legend>Person</legend>
    
            <div class="editor-label">
                @Html.LabelFor(model => model.Telephone)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.Telephone)
                @Html.ValidationMessageFor(model => model.Telephone)
            </div>
    
            <div class="editor-label">
                @Html.LabelFor(model => model.Address)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.Address)
                @Html.ValidationMessageFor(model => model.Address)
            </div>
    
            <p>
                <input type="submit" value="Create" />
            </p>
        </fieldset>
    }
 
</body>
</html>
 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

□ 效果

MVC验证13-2个属性至少输入一项的更多相关文章

  1. ASP.NET MVC验证框架中关于属性标记的通用扩展方法

    http://www.cnblogs.com/wlb/archive/2009/12/01/1614209.html 之前写过一篇文章<ASP.NET MVC中的验证>,唯一的遗憾就是在使 ...

  2. MVC验证05-自定义验证规则、验证2个属性值不等

    原文:MVC验证05-自定义验证规则.验证2个属性值不等 本文体验2个属性值不等.即当一个属性输入值,另外一个属性输入的值不能和第一个属性值相等.相关文章包括: MVC验证01-基础.远程验证   M ...

  3. MVC验证12-使用DataAnnotationsExtensions对整型、邮件、最小值、文件类型、Url地址等验证

    原文:MVC验证12-使用DataAnnotationsExtensions对整型.邮件.最小值.文件类型.Url地址等验证 本文体验来自http://dataannotationsextension ...

  4. MVC验证04-自定义验证规则、日期范围验证

    原文:MVC验证04-自定义验证规则.日期范围验证 本文体验范围验证.与本文相关的包括: MVC验证01-基础.远程验证   MVC验证02-自定义验证规则.邮件验证   MVC验证03-自定义验证规 ...

  5. Asp.net MVC验证哪些事(2)-- 验证规则总结以及使用

    上篇文章Asp.net MVC验证那些事(1)-- 介绍和验证规则使用中,介绍了Asp.net MVC中的验证功能以及如何使用.这里将对MVC中内置的验证规则进行总结. 一,查找所有验证规则 上篇文章 ...

  6. jQuery Validate 表单验证插件----在class属性中添加校验规则进行简单的校验

    一.下载插件包. 网盘下载:https://yunpan.cn/cryvgGGAQ3DSW  访问密码 f224 二.jQuery表单验证插件----添加class属性形式的校验 <!DOCTY ...

  7. MVC验证11-对复杂类型使用jQuery异步验证

    原文:MVC验证11-对复杂类型使用jQuery异步验证 本篇体验使用"jQuery结合Html.BeginForm()"对复杂类型属性进行异步验证.与本篇相关的"兄弟篇 ...

  8. MVC验证09-使用MVC的Ajax.BeginForm方法实现异步验证

    原文:MVC验证09-使用MVC的Ajax.BeginForm方法实现异步验证 MVC中,关于往后台提交的方法有: 1.Html.BeginForm():同步 2.Ajax.BeginForm():异 ...

  9. MVC验证10-到底用哪种方式实现客户端服务端双重异步验证

    原文:MVC验证10-到底用哪种方式实现客户端服务端双重异步验证 本篇将通过一个案例来体验使用MVC的Ajax.BeginForm或jQuery来实现异步提交,并在客户端和服务端双双获得验证.希望能梳 ...

随机推荐

  1. [Unity3D]Unity3D游戏开发《反对》说到游戏(上)——目标跟踪

    朋友,大家好.我是秦培,欢迎关注我的博客.我的博客地址blog.csdn.net/qinyuanpei. 首先博主要自我反省,过了这么久才来更新博客,这段时间主要是在忙着写期末的作业,所以博主基本上没 ...

  2. ios新开发语言swift 新手教程

    http://gashero.iteye.com/blog/2075324 视频教程:http://edu.51cto.com/lesson/id-26464.html

  3. Android L SDK -- 一些有趣的新功能

    一些普通的就不提了,自己查看最新的文档就可以 文档地址 Task locking 功能:让我们在使用一个应用时,能够免受通知(消息)的打搅. 怎样使用:当我们在应用中激活任务锁模式.我们接收到的通知( ...

  4. .Net程序猿乐Android发展---(10)框架布局FrameLayout

    帧布局FrameLayout中全部的控件都在界面的左上側,后绘制的空间会覆盖之前的控件.布局内控件以层叠方式显示,用在游戏开发方面可能多些. 1.层叠展示                 以下这个样例 ...

  5. Fizz-Buzz-Whizz

    Fizz-Buzz-Whizz ThoughtWorks测试 问题描述: 1. 你首先说出三个不同的特殊数,要求必须是个位数,比如3.5.7. 2. 让所有学生拍成一队,然后按顺序报数. 3. 学生报 ...

  6. ssh连接失败,排错经验(转)

    一.场景描述 ssh连接服务器,发现连接失败,但是对应服务器的ip能够ping通. 场景: [root@yl-web ~]# ssh root@10.1.101.35 ssh_exchange_ide ...

  7. 编写爬虫程序的神器 - Groovy + Jsoup + Sublime(转)

    写过很多个爬虫小程序了,之前几次主要用C# + Html Agility Pack来完成工作.由于.NET FCL只提供了"底层"的HttpWebRequest和"中层& ...

  8. [ACM] ZOJ 3816 Generalized Palindromic Number (DFS,暴力枚举)

    Generalized Palindromic Number Time Limit: 2 Seconds      Memory Limit: 65536 KB A number that will ...

  9. 关于java socket(转)

    1. 关于new Socket()中参数的理解 Server端: 调用ServerSocket serverSocket = new ServerSocket(1287,2);后Server端打开了指 ...

  10. 探索Scala(1)-- 运算符重载

    Scala语言运算符重载全然是语法层面的小把戏,本文记录我对Scala语言运算符重载的一些理解. 方法调用语法糖 调用方法时,Scala同意省略点号和圆括号,如以下代码所看到的: 把运算符映射成单词 ...