热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

通过扩展方法链式方法为MVC3视图添加验证

.Net3.0添加了一个语法糖就是扩展方法,其实扩展方法的本质就是对类的静态方法的调用,虽然扩展方法只是改变了我们写代码的方式,但是如果我

.Net 3.0 添加了一个语法糖就是扩展方法,其实扩展方法的本质就是对类的静态方法的调用,虽然扩展方法只是改变了我们写代码的方式,但是如果我们使用得当,可以给我们带来巨大的编码效率的提升。对于C#扩展方法的使用,我就不细说了,贴段代码说明扩展方法的使用,大家就会回忆起来。

1 public static class Extensions
2 {
3 public static string EndWith(this string str)
4 {
5 return str + "@";
6 }
7 }

对于这段非常简单的代码,相信大家应该会很明白,可以看到扩展方法的使用,就是在一个静态类中定义一个静态方法,在方法参数中添加this。

那么使用扩展方法就更加的简单了。以下代码片段就是扩展方法对于string的扩展,会在页面上显示@

1 string str = "";
2 Response.Write(str.EndWith());

扩展方法不是本次课题的重点,本次课题的重点是说明如何利用扩展方法来链式的对MVC 3中的页面进行验证。对于Mvc的验证,有很多种方式,其中

我们经常使用的就是Model的验证,这是最直接最有效的我们操作的方式,可以对一个字段进行多个条件的验证。但是这种验证方式有一个弊端,就是我

们不能在页面上直接看到对该字段进行了哪些验证,除非我们去Model层查看,但是通常一个项目是分项目组的,我们不一定负责开发Model层,所以这

就会遇到一个沟通的问题。我们都知道,程序员的沟通成本是很高的。

现在提供另一种进行页面验证的方式,这种方式也可以对一个页面元素进行多个条件的验证,并且是在客户端进行的。要使用这个验证,我们必须了解一

个jquery的插件,那就是jquery.validation.js文件,这个是对元素进行验证的js文件。

还有一个我们必须了解的知识点就是?Mvc 3的Razor 视图直接继承自哪个类?相信很多朋友都会毫不犹豫的说是ViewPage,当然这不能说是错的,因

为Mvc 2 确实是继承自ViewPage基类,但是在Razor 视图下,是继承自WebViewPage类的,如果你的扩展方法扩展的是ViewPage,那么对不起,你

在页面上是无法看到这个扩展方法的,除非继承自WebViewPage。希望大家扩展页面方法的时候注意一下类的继承问题。

说了准备工作,那么我们切入正题,先贴出来代码,然后我们再逐渐的分析。

1 namespace MvcWeb.Extensions
2 {
3 public class JqueryHelper
4 {
5 public ViewContext ViewContext { get; private set; }
6
7 public WebViewPage ViewPage { get; private set; }
8
9 public RouteCollection RouteCollection { get; private set; }
10
11 public JqueryHelper(ViewContext viewContext, WebViewPage page, RouteCollection routeCollection)
12 {
13 this.ViewContext = viewContext;
14 this.ViewPage = page;
15 this.RouteCollection = routeCollection;
16 }
17
18 public JqueryHelper(ViewContext viewContext, WebViewPage viewPage) : this(viewContext, viewPage, RouteTable.Routes) { }
19 }
20
21 public static class JqueryExtensions
22 {
23 public static JqueryHelper Jquery(this WebViewPage page)
24 {
25 var key = typeof(JqueryHelper);
26 var jquery = page.PageData[key] as JqueryHelper;
27 if (jquery == null)
28 {
29 page.PageData[key] = jquery = new JqueryHelper(page.ViewContext, page);
30 }
31 return jquery;
32 }
33 }
34
35 public class JqueryValidations
36 {
37 public WebViewPage Page { get; private set; }
38 public JqueryValidations(WebViewPage page)
39 {
40 this.Page = page;
41 }
42 private Dictionary<string, Dictionary<string, object>> m_rules &#61; new Dictionary<string, Dictionary<string, object>>();
43 private Dictionary<string, Dictionary<string, object>> m_message &#61; new Dictionary<string, Dictionary<string, object>>();
44
45 public void Required(string name,string message)
46 {
47 this.AddRuleAndMessage(name, "required", true, message);
48 }
49
50 public void Email(string name, string message)
51 {
52 this.AddRuleAndMessage(name,"email",true,message);
53 }
54
55 public void Number(string name, string message)
56 {
57 this.AddRuleAndMessage(name, "number", true, message);
58 }
59 public void Range(string name,int min,int max, string message)
60 {
61 this.AddRuleAndMessage(name, "range", new int[] { min, max }, message);
62 }
63 public string ToScripts(string form)
64 {
65 JavascriptSerializer serializer &#61; new JavascriptSerializer();
66 StringBuilder builder &#61; new StringBuilder();
67
68 builder.Append("$(");
69 serializer.Serialize(form, builder);
70 builder.Append(").validate(");
71 serializer.Serialize(
72 new
73 {
74 rules &#61; this.m_rules,
75 messages &#61; this.m_message,
76 onkeyup &#61; false
77 }, builder);
78 builder.Append(");");
79
80 return builder.ToString();
81 }
82
83 public ValidationElement Element(string name)
84 {
85 return new ValidationElement(name, this);
86 }
87 private void AddRuleAndMessage(string name, string rule, object value, string message)
88 {
89 if (!this.m_rules.ContainsKey(name))
90 {
91 this.m_rules[name] &#61; new Dictionary<string, object>();
92 }
93 this.m_rules[name][rule] &#61; value;
94
95 if (!string.IsNullOrEmpty(message))
96 {
97 if (!this.m_message.ContainsKey(name))
98 {
99 this.m_message[name] &#61; new Dictionary<string, object>();
100 }
101 this.m_message[name][rule] &#61; message;
102 }
103
104 }
105
106
107 }
108
109 public class ValidationElement
110 {
111 public ValidationElement(string name, JqueryValidations validations)
112 {
113 this.Name &#61; name;
114 this.Validations &#61; validations;
115 }
116
117 public string Name { get; private set; }
118
119 public JqueryValidations Validations { get; private set; }
120
121 public ValidationElement Required(string message)
122 {
123 this.Validations.Required(this.Name, message);
124 return this;
125 }
126
127 public ValidationElement Email(string message)
128 {
129 this.Validations.Email(this.Name, message);
130 return this;
131 }
132
133 public ValidationElement Number(string message)
134 {
135 this.Validations.Number(this.Name, message);
136 return this;
137 }
138
139 public ValidationElement Range(int min, int max, string message)
140 {
141 this.Validations.Range(this.Name, min, max, message);
142 return this;
143 }
144
145 }
146
147 public static class JQueryValidationExtensions
148 {
149 public static JqueryValidations Validations(this JqueryHelper jquery)
150 {
151 return jquery.Validations("(default)");
152 }
153
154 public static JqueryValidations Validations(this JqueryHelper jquery, string name)
155 {
156 var key &#61; typeof(JqueryValidations) &#43; "&#43;" &#43; name;
157 var page &#61; jquery.ViewPage;
158 var validations &#61; page.PageData[key] as JqueryValidations;
159
160 if (validations &#61;&#61; null)
161 {
162 page.PageData[key] &#61; validations &#61; new JqueryValidations(page);
163 }
164
165 return validations;
166 }
167 }
168
169 }

在这段代码中定义了JqueryHelper 类&#xff0c;是对WebViewPage的扩展&#xff0c;其中有一个方法ToScript 我们要特别注意一下&#xff0c;这个方法是在页面上显示一段拼

接的js&#xff0c;也就是jquery.validation.js会用到的验证页面元素的js。

具体代码我就不细说了&#xff0c;我介绍一下基本思想吧。首先我们定义了一个JqueryHelper类&#xff0c;然后顶一个JqueryValidation类来定义对页面元素可以进行的

验证。这里面有一个链式方法必须用到的就是每个验证方法返回的结果都是JqueryValidation类的对象&#xff0c;这样我们才可以进行链式操作。

通过Dictionary来存储验证的标签Name属性值&#xff0c;错误信息&#xff0c;以及验证规则&#xff0c;最后根据这些值在ToScript中拼接出可以提交的js。

好了&#xff0c;来看个结果&#xff0c;大家就会更加清楚这个链式方法的用途所在了。

1 &#64;{
2 Layout &#61; null;
3 }
4 &#64;using MvcWeb.Extensions
5
6
7
8
9
10
11
12
13
14


15 "form" action&#61;"" method&#61;"post">
16 "text" id&#61;"user.Name" name&#61;"user.Name" />
17 &#64;{ this.Jquery().Validations().Required("user.Name","用户名是必填的 亲");}
18
19 <select name&#61;"user.Gender">
20
21
22
23 select>
24
25 &#64;{ this.Jquery().Validations().Required("user.Gender", null);}
26
27 "text" name&#61;"user.Email" />
28 &#64;{this.Jquery().Validations().Element("user.Email").Required("邮箱是必填的").Email("请填写正确的邮箱格式");}
29 "submit" value&#61;"提交" />
30
31

32
35
36

对于在页面中实现验证的方法&#xff0c;我介绍一下咱们应该注意的地方

  1. 就是我们必须引入对应的js文件&#xff0c;如果我们不引入jquery.validation.js文件&#xff0c;那么验证也是不成功的

  2. 必须把要验证的元素放到form标签内

  3. 就是我们在通过链式方法验证元素的时候应该注意顺序&#xff0c;虽然说任何顺序都是可以的&#xff0c;但是我们也要按照业务逻辑来对验证顺序进行调整

  4. 最后我们通过一个submit按钮来进行提交&#xff0c;可能有人要用ajax等其他方式来提交页面&#xff0c;我可以告诉你&#xff0c;我尝试了一下&#xff0c;这样不会触发前端js的验证

  5. 最后我们必须要通过ToScript方法来拼接出验证的js&#xff0c;在Mvc中框架会自动进行编码&#xff0c;所以我们要求框架不要编码。如果没有要求框架

    不要编码&#xff0c;那么最后得到的js结果就是编码过的js&#xff0c;这不是我们要的结果。具体你可以查看源代码看一下执行结果


    最后还是有图有真相 
    1。初始界面显示

2.如果有些条件不满足&#xff0c;那么就会在界面上显示错误信息&#xff0c;当然这是可定制的。在我

在我调试代码的时候&#xff0c;我发现在IE9下&#xff0c;有时候错误信息显示的不是很实时&#xff0c;在火狐下显示的很正常&#xff0c;可能有些问题需要解决。但是不影响使用。

总结一下&#xff0c;链式方法我们其实也经常看到&#xff0c;在我们使用linq的时候&#xff0c;有时会有很多个方法链接使用&#xff0c;提高了程序的可读性。但是我们在设计可

以用来进行链式方法操作的时候一定要注意的就是所有的链式方法的返回值类型尽量相同&#xff0c;因为这便于我们不需要掌握顺序。有的园友会提出

不同意见&#xff0c;linq语法就不是所有的返回值类型都相同&#xff0c;但是我们要知道&#xff0c;我们在使用linq的时候&#xff0c;方法的调用顺序是很重要的对吧。

强调一下&#xff0c;扩展方法不是真的在原有类中添加了一个方法&#xff0c;而是相当于调用的静态类中的静态方法实现的。

天色已黑&#xff0c;我们还在努力。坚强的我们&#xff0c;肯定会有美好的明天。

 

 



推荐阅读
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • C# WPF自定义按钮的方法
    本文介绍了在C# WPF中实现自定义按钮的方法,包括使用图片作为按钮背景、自定义鼠标进入效果、自定义按压效果和自定义禁用效果。通过创建CustomButton.cs类和ButtonStyles.xaml资源文件,设计按钮的Style并添加所需的依赖属性,可以实现自定义按钮的效果。示例代码在ButtonStyles.xaml中给出。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • Ihavethefollowingonhtml我在html上有以下内容<html><head><scriptsrc..3003_Tes ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
author-avatar
玩在青岩堡欢乐长桌宴_840
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有