关于ASP.NET MVC的验证,用起来很特别,因为MS的封装,使人理解起来很费解。也可能很多人都在Scott Guthrie等人写的一本《ASP.NET MVC 1.0》书中,见过NerdDinner项目中对Dinner对象修改和添加的时的数据验证。但有许多封装的地方,不知道是怎样的工作原理,今天研究了,拿出来给大家分享一下。

数据库还是上一篇blog中的库与表,同样的方法来创建news表的实体类,在自动生成的news这个实体类中,我们发现有一个特殊的分部方法:

partial void OnValidate(System.Data.Linq.ChangeAction action);

这个方法没有实现,我们根据C#的语法知道,如果分部类中的分部方法,没有实现的话,调用和定议的地方都不会起什么作用。现在,我们要去完善这个方法,让它“用”起来。

首先,人产在Models中创建news类的另一部分,代码如下:

Code
 1 public partial  class news
 2    {
 3        partial void OnValidate(System.Data.Linq.ChangeAction action)
 4        {
 5            if (!IsValid)
 6            {
 7                throw new ApplicationException("验证内容项出错!");
 8            }
 9        }
10        public bool IsValid
11        {
12            get { return (GetRuleViolations().Count() == 0); }
13        }
14        public IEnumerable<RuleViolation> GetRuleViolations()
15        {
16            if (String.IsNullOrEmpty(this.title .Trim () ))
17                yield return new RuleViolation("题目步能为空!", "题目");
18            if (String.IsNullOrEmpty(this.contents .Trim ()))
19                yield return new RuleViolation("内容不能为空!", "内容");          
20            yield break;
21        }
22    }
23/**//// 
24    /// 规则信息类
25    /// 
26    public class RuleViolation
27    {
28        public string ErrorMessage { get; private set; }
29        public string PropertyName { get; private set; }
30
31        public RuleViolation(string errorMessage)
32        {
33            ErrorMessage = errorMessage;
34        }
35
36        public RuleViolation(string errorMessage, string propertyName)
37        {
38            ErrorMessage = errorMessage;
39            PropertyName = propertyName;
40        }
41    }
42

在这里给出这么多代码,其实是提前有设计的,因为从业务角度考虑,还不应该写这部分代码。RuleViolation类很简单,就是一个包括了两个属性的类(这个类的结构设计是根据后面的ModelState.AddModelError主法来设计的)。

在news分部类中,有一个IsValid的属性,这个属性是bool类型的,返回值取决于GetRuleViolations这个方法,这个方法返回值是一个IEnumerable类型的,IEnumerable是通过news的几个属性是否为空来生成跌代的。如果title或contents为Null或””,就返回跌代。其实真正的用户数据的验证就是在这里实现,用户的数据的对与错,就是一个逻辑,只要用户数据不符合规则,就可以 “yield return new RuleViolation("错误标识","错误提示信息!")”;这里的错误码提示信息是显示到客户端的,所以要处理好友好的提示。

现在验证用户数据,生成错误列表的工作都做完了,但关键是怎么能让用户提交数据时,调用OnValidate。这个问题,先放一下,请记住,上面的代码,只要在用户提交数据时,调用OnValidate,这样就能得到错误集合。

现在,让我们来处理Cotroller和View层,在Cotroller层,首先来添加index这个Action,代码如下:

1public ActionResult Index()
2        {           
3            var NewsList = DCDC.news.Select(newss=>newss);
4            return View(NewsList );
5     }
6

这个Action返回所有news表中的记录。

对应的View如下:

Code
 1
 2
 3<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
 4    Index
 5asp:Content>
 6
 7<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
 8
 9    <h2>Indexh2>
10
11    <table>
12        <tr>
13            <th>th>
14            <th>
15                ID
16            th>
17            <th>
18                title
19            th>
20            <th>
21                datetimes
22            th>
23            <th>
24                contents
25            th>
26            <th>
27                IsValid
28            th>
29        tr>
30
31    
32    
33        <tr>
34            <td>
35                 |
36                
37            td>
38            <td>
39                
40            td>
41            <td>
42                
43            td>
44            <td>
45                
46            td>
47            <td>
48                
49            td>
50            <td>
51                
52            td>
53        tr>
54    
55    
56
57    table>
58
59    <p>
60        
61    p>
62asp:Content>
63

代码中,需要我们注意是的

因为要导航到Edit的View,把以接下来我们创建Edit的Action和View(因为在编辑数据时,要用到验证,Edit才是我们的重点)。

1 public ActionResult Edit(int id)
2        {
3            var list = DCDC.news.Single(newss=>newss.ID ==id);
4            return View(list);
5     }
6
<%= Html.ActionLink("Edit", "Edit", new { id=item.ID }) %>

中的id会被当成参数送到EditController的Edit(int id)的Action,成为Edit方法的实参。

Edit.aspx页面如下图:

对应Edit的Action生成view,代码如下:

Code
 1
 2<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
 3    编辑
 4asp:Content>
 5<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
 6    <h2 style ="text-align :left ;">编辑h2>
 7    
 8    
10        <fieldset>
11            <legend>详细内容legend>     
12            <p>
13                <label for="title">标题:label>
14                
15                
16            p>
17            <p>
18                <label for="datetimes">时间:label>
19                
20                 
21            p>
22            <p>
23                <label for="contents">内容:label>
24                
25                
26            p>
27            <p>
28                <input type="submit" value="更新" />
29            p>
30        fieldset>
31    
32    <div>
33        
34    div>
35
36asp:Content>
37

如果要单击“更新”返回数据新数据,还需要我们写如下一个Action:

Code
 1[AcceptVerbs(HttpVerbs.Post)]
 2        public ActionResult Edit(int id,FormCollection formValuews)
 3        {
 4            news Sig_news = DCDC.news.Single(newss => newss.ID == id);
 5            try
 6            {               
 7                Sig_news.title = formValuews.GetValue("title").AttemptedValue;
 8                Sig_news.datetimes = DateTime.Parse(formValuews.GetValue("datetimes").AttemptedValue);
 9                Sig_news.contents = formValuews.GetValue("contents").AttemptedValue;
10                DCDC.SubmitChanges();
11                return RedirectToAction("Index");
12            }
13            catch
14            {
15                foreach (var v in Sig_news.GetRuleViolations())
16                {
17                    ModelState.AddModelError(v.PropertyName,v.ErrorMessage);
18                }
19                return View(Sig_news);
20            }
21        }
22

这个Edit的Action是用户提交返来更新数据库的,我们可以从formValuews得到用户在页面上更新的数据,来更新Sig_news对象,然后调用DCDC.SubmitChanges();去更新数据库,如果没有民常,会导航到index.aspx页面。如果发生异常,就会运行到catch里。如果还记得,在本文的前半部分,我们说到OnValidate,是数据在提交时应该验证,但在这里,我们并没有显示的调用OnValidate这个方法,但实际运行中,我们发现,这个方法被执行了,如果我们建立跟踪,把断点设在DCDC.SubmitChanges();如果我们数据有民常,会发现当DCDC.SubmitChanges();执行完后就会跳到partial void OnValidate(System.Data.Linq.ChangeAction action)这个方法,这是怎么做到的呢?我们猜测,一定是在数据提交时,调用OnValidate这个方法。为了找到它们的关系,只好用Reflector.exe来“探测”一下了(Reflector.exe的用法就不说了)。

SubmitChanges方法是DataContext的一个方法,这个类位于System.Data.Linq命空间下,用Reflector.exe打开SubmitChanges,看到this.SubmitChanges(ConflictMode.FailOnFirstConflict);定位这个方法,可以看到new ChangeProcessor(this.services, this).SubmitChanges(failureMode);定位查找会发现ValidateAll(orderedList);在这个方法中,多处看到 SendOnValidate(obj2.Type, obj2, ChangeAction.Insert);这个方法,再定位,有这样一行代码 type.OnValidateMethod.Invoke(item.Current, new object[] { changeAction });这里,正是通过反射调用了OnValidate这个方法。这样我们就找到了SubmitChanges执行时调用OnValidate的方法了(其不用调用OnValidate也可以验证用户数据,只需要写个方法,在SubmitChanges 提交以前执行就可以达到同样效果)。同时,当发生异常时,OnValidate会抛出一个Application的异常,这里会被public ActionResult Edit(int id,FormCollection formValuews)方法中的Catch捕获到,就执行如下代码:

Code
1foreach (var v in Sig_news.GetRuleViolations())
2                {
3                    this.ModelState.AddModelError(v.PropertyName,v.ErrorMessage);
4                }
5                return View(Sig_news);
6

这行代码的意思是把错误的信息,以键值的方式放入ModelState中,ModelState是一个ModelStateDictionary类型,这个类型实现了IDictionary, ICollection>, IEnumerable>, IEnumerable这些接口(这里要注意,ModelState是当前对象的一个属性,并且它的AddModelError方法的第一个参数key有其独特的作用)。处理完异常后,还是返回当前页面。这时你会发现,在页面的   发生了变化,把我们错误的地方去提示出来了,这里就是,为什么我们把错误信息放到ModelState中,而错误则显示在了Html.ValidationSummary中了呢?并且发生错误的数据后会加上了一个红色的“*”,这是怎么样做到的呢?

再次利用Reflector.exe,查看Html.ValidationSummary方法和Html.ValidationMessage方法,会发现它们显示的数据是从ModelState 中获取的,如果ModelState 这个集合中没有数据,Html.ValidationSummary和Html.ValidationMessage就返回空,如果发生异常,this.ModelState中有子项,就会通过Html.ValidationSummary和Html.ValidationMessage在页面页上显示出来。因为Html.ValidationMessage在页面上有多个,所以在this.ModelState.AddModelError(v.PropertyName,v.ErrorMessage);方法中的v.PropertyName就有了用处了,这个值要与中的第一个参数对应,这样才能起到作用,显示出第二个参数“*”。

这样一来,就达到了ASP.NET MVC的数据验证。由于ASPNET MVC 验证捌的弯比较多,所以下来用个图来说明一下。

源码:/Files/axzxs2001/MvcCompany.rar

转载于:https://www.cnblogs.com/waw/archive/2011/08/29/2157134.html

艾伟_转载:ASP.NET MVC数据验证相关推荐

  1. ASP.NET MVC数据验证(上)

    关于ASP.NET MVC的验证,用起来很特别,因为MS的封装,使人理解起来很费解.也可能很多人都在Scott Guthrie等人写的一本<ASP.NET MVC 1.0>书中,见过Ner ...

  2. 【ASP.NET MVC4】第八课:MVC数据验证、验证特性、自定义验证

    知识点:MVC数据验证概述.验证特性的使用.自定义验证.扩充基于 Entity Framework 的数据模型. 1.MVC 数据验证概述 1.1  为什么要进行数据验证 ASP.NET MVC 中的 ...

  3. ASP.NET MVC 2 验证

    来源:http://www.cnblogs.com/jhxk/articles/2612885.html  只为把自己觉的好的存起来 对用户输入的验证以及强制业务规则/逻辑是大多数web应用的核心需求 ...

  4. ASP.NET MVC 5 - 验证编辑方法(Edit method)和编辑视图(Edit view)

    在本节中,您将验证电影控制器生成的编辑方法(Edit action methods)和视图.但是首先将修改点代码,使得发布日期属性(ReleaseDate)看上去更好.打开Models \ Movie ...

  5. Asp.Net MVC 身份验证-Forms

    Asp.Net MVC 身份验证-Forms 在MVC中对于需要登录才可以访问的页面,只需要在对应的Controller或Action上添加特性[Authorize]就可以限制非登录用户访问该页面.那 ...

  6. 艾伟_转载:学习 ASP.NET MVC (第五回)理论篇

    本系列文章导航 学习 ASP.NET MVC (第一回)理论篇 学习 ASP.NET MVC (第二回)实战篇 学习 ASP.NET MVC (第三回)实战篇 学习 ASP.NET MVC (第四回) ...

  7. ASP.NET MVC数据标记验证

    如果我发布的文章里有错误请各路高手给指出. DataAnnotation提供了一个简单的方式,在应用中的Model和View 类中添加验证规则,在ASP.NET MVC中有自动的绑定和UI辅助方法验证 ...

  8. 艾伟_转载:VS 2010 和 .NET 4.0 系列之《自动启动ASP.NET应用》篇

    本系列文章导航 VS 2010 和 .NET 4.0 系列之<ASP.NET 4 中的SEO改进 >篇 VS 2010 和 .NET 4.0 系列之<干净的Web.Config文件 ...

  9. 艾伟_转载:VS 2010 和 .NET 4.0 系列之《在ASP.NET 4 Web Forms中实现URL导向》篇

    本系列文章导航 VS 2010 和 .NET 4.0 系列之<ASP.NET 4 中的SEO改进 >篇 VS 2010 和 .NET 4.0 系列之<干净的Web.Config文件 ...

最新文章

  1. Linux用户管理-服务管理
  2. OpenGL ES3 非常好的系列文章
  3. Docker+geoserver发布shp地图服务
  4. Django 与ajax交互
  5. logs is not in the form of topic-partition or topic-partition.uniqueId-delete
  6. 【经典回放】多种语言系列数据结构算法:树(C#、JavaScript、VB6版)
  7. 三分钟看懂一致性哈希算法
  8. TCP连接发送窗口问题思考
  9. CAD迷你看图 for Mac(强大的cad看图软件)
  10. 【总结】编程语言的分类
  11. 使用微信同声传译插件开发一款翻译类的小程序
  12. 创建和管理图书管理系统数据库
  13. 浅议化学与社会的关系——兼议绿色化学重要性
  14. cv2库中一些函数的使用
  15. ICPC-Tic Tac Toe
  16. 蓝牙耳机连接电脑,找不到stereo模式
  17. docker-compose和docker swarm容器间网络不互通的情况
  18. 传统渲染与DLSS2.0的对比
  19. 外设驱动库开发笔记17:MS5803压力变送器驱动
  20. 不懂编程的运维人员到底还能走多远?

热门文章

  1. Centos系统中彻底删除Mysql数据库
  2. unix改变shell显示颜色
  3. HDU 1088 Write a simple HTML Browser
  4. 极兔收购百世快递,谁是赢家?
  5. 农信互联X联网副总冯兴臣:关于互农产品的一些思考
  6. 有品产品专家盖勇:如何做出超越用户期待的智能硬件产品?
  7. 亚马逊生鲜的产品质疑!国外设计师怎么分析用户体验(中英图文对照版)
  8. 做后台支付系统,你要注意这些!!!
  9. 【pmcaff】2014互联网公司薪资排行榜
  10. PostgreSQL、Greenplum 日常监控 和 维护任务