前端和后端的双重验证

ASP.NET MVC和WebForm 轻松实现前端和后端的双重验证 jquery.validate+ValidationSugar

上次不足的改进

可能上一个贴子给大家带来很多误解,所以我这次把DEMO完善了两个版本 【ASP.NET WEBFROM】和【 ASP.NET MVC】

修改了一些BUG,并且修改了一些细了

在上个贴子里有人说,看了response.write就全身不舒服,所以也就写了基于异步提交的例子

功能介绍

ValidationSugar.cs 负责后台验证和前端 form 元素的 验证 属性绑定

ValidationSugar.js 对 jquery.validate在进行了一个封装来负责前端的验证

注意:ValidationSugar.cs

现在可以支持

1、HTML5默认验证功能

2、jquery.validate

3、webform demo1里面的一个HTML5+CSS3的验证

其它的前端验证可以自已去扩展

后台:

前台:

1、先引用4个脚本:


1

2

3

4

<script src="/Content/jquery-validation-1.13.1/lib/jquery-1.9.1.js" type="text/javascript"></script>

<script src="/Content/jquery-validation-1.13.1/dist/jquery.validate.js"></script>

<script src="/Content/ValidationSugar.js" type="text/javascript"></script>

<script src="/Content/jquery-validation-1.13.1/lib/jquery.form.js" type="text/javascript"></script>

  

2、脚本调用就这么简单


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

<script type="text/javascript">

     $(function () {

         var factory = new validateFactory($("form"));

         factory.init();

         $("#btnSubmit").click(function () {

             //异步方式

             factory.ajaxSubmit(function () {

                 $("form").ajaxSubmit({

                     type: "post",

                     url: "/home/post",

                     dataType:"json",

                     success: function (msg) {

                         alert(msg.Message)

                     }

                 })

             });

         });

     });

 </script>

  

3、HTML代码

DEMO下载地址:http://git.oschina.net/sunkaixuan/ValidationSuarMVC (包含WEBFROM)

因为才写了2天难免会有没有考虑到的地方,我在以后工作中慢慢更新的,谢谢观看。

封装代码:

ValidationSugar.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace SyntacticSugar
{
    /// <summary>
    /// ** 描述:可以方便实现前后端双验证,基于jquery
    /// ** 创始时间:2015-6-4
    /// ** 修改时间:-
    /// ** 作者:sunkaixuan
    /// ** 使用说明:http://www.cnblogs.com/sunkaixuan/p/4550580.html
    /// ** git: http://git.oschina.net/sunkaixuan/SyntacticSugar
    /// </summary>
    public class ValidationSugar
    {

        private static List<ValidationOption> ValidationOptionList = new List<ValidationOption>();

        /// <summary>
        /// 前台注入
        /// </summary>
        /// <param name="pageKey"></param>
        /// <param name="itemList"></param>
        public static string GetInitScript(string pageKey, List<OptionItem> itemList)
        {
            //初始化后不在赋值
            if (ValidationOptionList.Any(it => it.PageKey == pageKey))
            {
                ValidationOptionList.RemoveAll(it => it.PageKey == pageKey);
            }

            ValidationOption option = new ValidationOption();
            string uk = Guid.NewGuid().ToString().Replace("-", "");//唯一函数名
            string script = @"<script>
var bindValidation{1}=function(name,params){{
     var selectorObj=$(""[name=‘""+name+""‘]"").last();
     selectorObj.after(""<span class=\""form_hint\"">""+params.tip+""</span>"");
     if(params.pattern!=null)
     selectorObj.attr(""pattern"",params.pattern);
     if(params.placeholder!=null)
     selectorObj.attr(""placeholder"",params.placeholder);
     if(params.isRequired==true)
     selectorObj.attr(""required"",params.isRequired);
}}
{0}</script>";
            StringBuilder itemsCode = new StringBuilder();
            foreach (var item in itemList)
            {
                switch (item.Type)
                {
                    case OptionItemType.Mail:
                        item.Pattern = @"^[\\w-]+(\\.[\\w-]+)*@[\\w-]+(\\.[\\w-]+)+$";
                        break;
                    case OptionItemType.Int:
                        item.Pattern = @"^\\d{1,11}$";
                        break;
                    case OptionItemType.Double:
                        item.Pattern = @"^\\d{1,11}$";
                        break;
                    case OptionItemType.IdCard:
                        item.Pattern = @"^(\\d{15}$|^\\d{18}$|^\\d{17}(\\d|X|x))$";
                        break;
                    case OptionItemType.Date:
                        item.Pattern = @"^(((1[8-9]\\d{2})|([2-9]\\d{3}))([-\\/])(10|12|0?[13578])([-\\/])(3[01]|[12][0-9]|0?[1-9])$)|(^((1[8-9]\\d{2})|([2-9]\\d{3}))([-\\/])(11|0?[469])([-\\/])(30|[12][0-9]|0?[1-9])$)|(^((1[8-9]\\d{2})|([2-9]\\d{3}))([-\\/])(0?2)([-\\/])(2[0-8]|1[0-9]|0?[1-9])$)|(^([2468][048]00)([-\\/])(0?2)([-\\/])(29)$)|(^([3579][26]00)([-\\/])(0?2)([-\\/])(29)$)|(^([1][89][0][48])([-\\/])(0?2)([-\\/])(29)$)|(^([2-9][0-9][0][48])([-\\/])(0?2)([-\\/])(29)$)|(^([1][89][2468][048])([-\\/])(0?2)([-\\/])(29)$)|(^([2-9][0-9][2468][048])([-\\/])(0?2)([-\\/])(29)$)|(^([1][89][13579][26])([-\\/])(0?2)([-\\/])(29)$)|(^([2-9][0-9][13579][26])([-\\/])(0?2)([-\\/])(29))|(((((0[13578])|([13578])|(1[02]))[\\-\\/\\s]?((0[1-9])|([1-9])|([1-2][0-9])|(3[01])))|((([469])|(11))[\\-\\/\\s]?((0[1-9])|([1-9])|([1-2][0-9])|(30)))|((02|2)[\\-\\/\\s]?((0[1-9])|([1-9])|([1-2][0-9]))))[\\-\\/\\s]?\\d{4})(\\s(((0[1-9])|([1-9])|(1[0-2]))\\:([0-5][0-9])((\\s)|(\\:([0-5][0-9])\\s))([AM|PM|am|pm]{2,2})))?$";
                        break;
                    case OptionItemType.Mobile:
                        item.Pattern = @"^[0-9]{11}$";
                        break;
                    case OptionItemType.Telephone:
                        item.Pattern = @"^(\\(\\d{3,4}\\)|\\d{3,4}-|\\s)?\\d{8}$";
                        break;
                    case OptionItemType.Fax:
                        item.Pattern = @"^[+]{0,1}(\\d){1,3}[ ]?([-]?((\\d)|[ ]){1,12})+$";
                        break;
                    case OptionItemType.Regex:
                        item.Pattern = item.Pattern.Replace(@"\", @"\\");
                        break;
                }
                itemsCode.AppendFormat("bindValidation{0}(‘{1}‘,{{   tip:‘{2}‘,pattern:‘{3}‘,placeholder:‘{4}‘,isRequired:{5} }})", uk, item.FormFiledName, item.Tip, item.Pattern, item.Placeholder, item.IsRequired ? "true" : "false");
                itemsCode.AppendLine();
            }
            option.Script = string.Format(script, itemsCode.ToString(), uk);
            script = null;
            itemsCode.Clear();
            option.PageKey = pageKey;
            option.ItemList = itemList;
            ValidationOptionList.Add(option);
            return (option.Script);

        }

        /// <summary>
        /// 后台验证
        /// </summary>
        /// <param name="pageKey"></param>
        /// <param name="errorMessage">json格式</param>
        /// <returns></returns>
        public static bool PostValidation(string pageKey, out string errorMessage)
        {
            bool isSuccess = true;
            errorMessage = string.Empty;
            if (!ValidationOptionList.Any(c => c.PageKey == pageKey))
            {
                throw new ArgumentNullException("ValidationSugar.PostValidation.pageKey");
            }
            var context = System.Web.HttpContext.Current;
            var itemList = ValidationOptionList.Where(c => c.PageKey == pageKey).Single().ItemList;
            var successItemList = itemList.Where(it => (it.IsRequired && !string.IsNullOrEmpty(context.Request[it.FormFiledName]) || !it.IsRequired)).Where(it =>
            {
                if (it.IsMultiselect == true)
                {
                    var errorList = context.Request[it.FormFiledName].Split(‘,‘).Where(itit =>
                    {
                        var isNotMatch = !Regex.IsMatch(itit, it.Pattern.Replace(@"\\", @"\"));
                        return isNotMatch;

                    }).ToList();
                    return errorList.Count == 0;
                }
                else
                {
                    return Regex.IsMatch(context.Request[it.FormFiledName], it.Pattern.Replace(@"\\", @"\"));
                }
            }
                ).ToList();
            isSuccess = (successItemList.Count == itemList.Count);
            if (!isSuccess)
            {
                errorMessage = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(itemList);
            }
            return isSuccess;
        }

        private class ValidationOption
        {
            public string PageKey { get; set; }
            public string Script { get; set; }
            public List<OptionItem> ItemList { get; set; }

        }

        public enum OptionItemType
        {
            Mail = 0,
            Int = 2,
            Double = 3,
            IdCard = 4,
            Date = 5,
            /// <summary>
            /// 移动电话
            /// </summary>
            Mobile = 6,
            /// <summary>
            /// 座机
            /// </summary>
            Telephone = 7,
            Fax = 8,
            /// <summary>
            /// 没有合适的,请使用正则验证
            /// </summary>
            Regex = 1000

        }
        /// <summary>
        /// 验证选项
        /// </summary>
        public class OptionItem
        {
            /// <summary>
            /// 验证类型
            /// </summary>
            public OptionItemType Type { get; set; }
            /// <summary>
            /// 正则
            /// </summary>
            public string Pattern { get; set; }
            /// <summary>
            /// 是否必填
            /// </summary>
            public bool IsRequired { get; set; }
            /// <summary>
            /// 表单字段名(name或者id)
            /// </summary>
            public string FormFiledName { get; set; }
            /// <summary>
            /// 水印
            /// </summary>
            public string Placeholder { get; set; }
            /// <summary>
            /// 提醒
            /// </summary>
            public string Tip { get; set; }
            /// <summary>
            /// 是多选吗? 默认false
            /// </summary>
            public bool IsMultiselect { get; set; }

        }
    }
}


1

validationSagur.js:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

//基于validate验证

//作者:sunkaixuan

//时间:2015-6-5

var validateFactory = function (form) {

    this.init = function () {

        addMethod();

        bind();

    }

    this.submit = function () {

        if (form.data("validateFactory")) {

            form.data("validateFactory").form();

        }

    }

    this.ajaxSubmit = function (rollback) {

        if (form.data("validateFactory")) {

            if (form.valid()) {

                if (rollback != null) {

                    rollback();

                }

            }

        }

    }

    function addMethod() {

        form.find("[pattern]").each(function () {

            var th = $(this);

            var pattern = GetPattern(th);

            var methodName = GetMdthodName(th);

            $.validator.addMethod(methodName, function (value, element, params) {

                return this.optional(element) || new RegExp(pattern).test(value);

            }, GetTip(th));

        });

    }

    function bind() {

        var rules = {};

        var messages = {};

        form.find("[pattern]").each(function () {

            var th = $(this);

            var methodName = GetMdthodName(th);

            var name = GetName(th);

            rules[name] = {};

            rules[name][methodName] = true;

            if (GetIsRequired(th)) {

                rules[name].required = true;

                messages[name] = {};

                messages[name].required = "不能为空!";

            }

        });

        var v = form.validate({

            onfocusout: function (element) {

                $(element).valid();

            },

            onkeyup: function (element) {

                $(element).valid();

            },

            rules: rules,

            messages: messages,

            debug: false,

            errorPlacement: function (error, element) {

                if (element.is(":radio,:checkbox")) {

                    element.parent().append(error);

                } else {

                    element.after(error);

                }

            }

        });

        form.data("validateFactory", v);

    }

    function GetMdthodName(ele) {

        return ele.attr("name") + "ValidateMethod";

    }

    function GetName(ele) {

        return ele.attr("name");

    }

    function GetPattern(ele) {

        return ele.attr("pattern");

    }

    function GetTip(ele) {

        return ele.next().text();

    }

    function GetIsRequired(ele) {

        if (ele.attr("required")) {

            return true;

        } else {

            return false;

        }

    }

};

  

分类: Git

时间: 2024-10-23 10:15:07

前端和后端的双重验证的相关文章

ASP.NET MVC和WebForm 轻松实现前端和后端的双重验证 jquery.validate+ValidationSugar

上次不足的改进 可能上一个贴子给大家带来很多误解,所以我这次把DEMO完善了两个版本 [ASP.NET WEBFROM]和[ ASP.NET MVC] 修改了一些BUG,并且修改了一些细了 在上个贴子里有人说,看了response.write就全身不舒服,所以也就写了基于异步提交的例子 功能介绍 ValidationSugar.cs 负责后台验证和前端 form 元素的 验证 属性绑定 ValidationSugar.js 对 jquery.validate在进行了一个封装来负责前端的验证 注意

前端加后端验证倒计时答题功能实现

思路 前端页面控制答题的开始,请求后台,后台记录开始的时间(发出请求的当前时间),再加上倒计时时间,得出结束时间. 后端返回给前端剩余的时间,前端通过Jquery实现倒计时的动态效果. 当倒计时结束,禁止答题,当用户刷新页面时,比较请求时间与结束时间,如果前者小于后者,答题继续,否则反之. 其中,答题时间.开始时间.结束时间,均保存在内存中. 实现(SpringMVC+Jquery) 后端: 1 /** 2 * Copyright 2016 Zhengbin's Studio. 3 * All

前端和后端

舞台是展示自己最华丽的一面,那么,后台则是很多工作人员所运转. 一个大舞台,需要的是前端和后端,那么前端是什么,后端是什么? 我们抛开技术不说,举个例子吧! 比如一个大型的演唱会,如果没有一个好的歌手,没有好听的歌,不过光靠歌手还不行,还需要舞台,这个舞台需要谁来支撑呢?没错,就是后面的工作人员,没有他们,就没有这样顺利的演唱会. 如果前端是歌手,那么后端则是工作人员,这样就很好理解了,我们前端是干什么的.但是光靠展示和设计出漂亮的网页还不行,还需要和后端好好配合才能做好,所以这个博文会列举出后

文件上传之前端和后端

明天又是星期一.发现周末的时间过得真快啊.光阴似子弹,嗖的一下,两天就没了. 文件上传是web开发中很常见的场景,比如填写个人信息的时候传一两张自己美美哒照片,比如上传一张个性的头像.有时候需要上传一个压缩包,文档啥的.作为程序员嘛,自然免不了要想办法让这些美照啊,文件啊顺利的到达服务器. 今天我来写一段最简单的文件上传.至于简单到什么程度,那我先介绍一下稍微复杂的文件上传吧. 1.web2.0时代,用户体验是web开发必须考虑的问题,文件上传自然不能跳转,所以,类Ajax的方式上传文件是现代网

IC设计前端到后端的流程和eda工具。

IC前端设计(逻辑设计)和后端设计(物理设计)的区分:以设计是否与工艺有关来区分二者:从设计程度上来讲,前端设计的结果就是得到了芯片的门级网表电路. 前端设计的流程及使用的EDA工具如下: 1.架构的设计与验证:按照要求,对整体的设计划分模块. 架构模型的仿真可以使用Synopsys公司的CoCentric软件,它是基于System C的仿真工具. 2.HDL设计输入:设计输入方法有:HDL语言(Verilog或VHDL)输入.电路图输入.状态转移图输入. 使用的工具有:Active-HDL,而

现代软件工程_团队项目_阿尔法阶段_前端及后端新增功能_v1.0.1_2017.11.29

前端及后端新增功能v1.0.2 本篇文章的后端功能由php实现,可在阿里云服务器上查看源代码 一.实现功能简介: 注册新用户 登录 检验是否登录 完善我的信息 发布我的自习 显示已有自习列表 翻页查看更多自习 二.具体实现 注册新用户 前端页面为regestered.html 1.表单信息 账号account 密码password 确认密码confirmPassword 昵称nickname 手机号码cellphonNumber 科大邮箱ustcEmail 验证码verificationCode

对一个前端AngularJS,后端OData,ASP.NET Web API案例的理解

依然chsakell,他写了一篇前端AngularJS,后端OData,ASP.NET Web API的Demo,关于OData在ASP.NET Web API中的正删改查没有什么特别之处,但在前端调用API时,把各种调用使用$resouce封装在一个服务中的写法颇有借鉴意义. 文章:http://chsakell.com/2015/04/04/asp-net-web-api-feat-odata/源码:https://github.com/chsakell/odatawebapi 首先是领域模

前端MVC学习总结——AngularJS验证、过滤器

前端MVC学习总结--AngularJS验证.过滤器 目录 一.验证 二.过滤器 2.1.内置过滤器 2.1.1.在模板中使用过滤器 2.1.2.在脚本中调用过滤函数 2.2.自定义过滤器 三.指令(directive) 3.1.支持AngularJS功能的指令 3.1.1.应用与模块(ng-app) 3.1.2.控制器(ng-Controller) 3.1.3.包含(ng-Include) 3.1.4.不绑定(ngNonBindable) 3.2.扩展表单元素的指令 3.2.1.ng-opti

前端和后端如何合作

我们的流程是这样的,后台提供数据接口,或接口文档. 然后我们前台进行razor模板的数据逻辑嵌套或html,css,js整个流程的开发. 缺点是:工作量是满大的,优点是,所有前端view层的东西都是可控的. 坑是比较多的, 比如数据出现问题时,没有一个经验丰富的前端或后端进行联调, 有问题短时间内是解决不了的. 一般跟后台合作分为这几种模式:1. 只产出html页面,然后交给后端来处理数据.这种的好处是工作量比较少,公司没有专门的前端岗位时可以实行这种办法.但这种的缺点也是显而易见的,后端人员工