惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Schneier on Security
有赞技术团队
有赞技术团队
T
The Blog of Author Tim Ferriss
F
Fortinet All Blogs
D
DataBreaches.Net
F
Full Disclosure
腾讯CDC
博客园 - 【当耐特】
MyScale Blog
MyScale Blog
Stack Overflow Blog
Stack Overflow Blog
小众软件
小众软件
Hugging Face - Blog
Hugging Face - Blog
Last Week in AI
Last Week in AI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
爱范儿
爱范儿
The GitHub Blog
The GitHub Blog
Engineering at Meta
Engineering at Meta
大猫的无限游戏
大猫的无限游戏
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
S
SegmentFault 最新的问题
The Register - Security
The Register - Security
WordPress大学
WordPress大学
博客园 - 聂微东
雷峰网
雷峰网
J
Java Code Geeks
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
P
Privacy International News Feed
酷 壳 – CoolShell
酷 壳 – CoolShell
A
Arctic Wolf
Scott Helme
Scott Helme
C
Cyber Attacks, Cyber Crime and Cyber Security
T
Tor Project blog
博客园 - 三生石上(FineUI控件)
Know Your Adversary
Know Your Adversary
AWS News Blog
AWS News Blog
G
Google Developers Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
C
CERT Recently Published Vulnerability Notes
O
OpenAI News
Project Zero
Project Zero
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Application and Cybersecurity Blog
Application and Cybersecurity Blog
云风的 BLOG
云风的 BLOG
N
News and Events Feed by Topic
MongoDB | Blog
MongoDB | Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Microsoft Security Blog
Microsoft Security Blog
Cisco Talos Blog
Cisco Talos Blog
P
Palo Alto Networks Blog
Schneier on Security
Schneier on Security

博客园 - 深山老林

测试Varnish缓存服务器与IIS连接数 谈谈持续集成 亲测SQLServer的最大连接数 读书笔记:Oracle锁定策略的总结 jQuery formValidator不支持新版手机的解决办法 TFS Workspace错误解决办法 Mindjet.MindManager.v9.0“参数错误”解决办法 c#3.0提供的扩展方法 Entityframework提供的处理并发冲突方式 ASP.NET MVC2中返回Json异常的解决办法 Visual studio 配置文件下载 WF之基本概念 数据库访问的性能问题与瓶颈问题 SQLServer中批量插入数据方式的性能对比 微软并行编程类库Parallel Extensions介绍 更改Outlook数据文件的路径 谈谈c#中的static 再次探讨企业级开发中的Try......Catch性能问题 在企业级开发中使用Try...Catch...会影响效率吗?
再次探扩展-对xVal进行扩展解决验证不同步的问题
深山老林 · 2010-03-01 · via 博客园 - 深山老林

之前写过两篇文章,分别都是在ASP.NET MVC下进行验证的,分别如下:

《ASP.NET MVC中的验证》

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

之前的团队在进行项目开发的时候,使用了第二篇文章中提到的扩展方法在项目中引入了xVal,总体上对xVal评价还是蛮高的。可是在开发的过程中遇到了一个戏剧性的问题:

  1. 一个页面上只有一个Model,而要验证的部分并不属于这个Model。
  2. 这个要验证的部分可能是其它的Model的,而且在某个页面是需要验证的,而在另外的页面是不需要验证的。

可能有人说了,这有何难,写段JavaScript验证下不完了嘛,在要验证的字段后面加一个span标记,通过JavaScript进行动态的隐藏和显示。

之前的团队成员的确就是这样做的,但是被测试打回来了,理由很简单,JavaScript验证的部分先执行,而xVal验证的部分后执行,这样在页面上用户体验不是很好,如果能够统一时间统一验证,这样是可以接受的。

又有人提出来解决办法:Model复用。很明显,被第2点否了。

当时开会讨论的时候,我没有多说话,因为已经心中有数了,只是没有时间去研究这个问题,再者,可能这个团队不太喜欢提ideas,更喜欢Solution。

先来看之前发过的一幅图。如下图所示:

 

通过图中可以看出来,要解决这个问题,可以从两个防线突破,一方面是前台突破,一方面是后台突破。

从前台突破,需要使用Standard JSON rules format(MVC2已经实现了,用的就是这种方式),可以使用jquery validation、ASP.NET native validation或者其它的验证库,当然,只要是标准的json规则格式,就可以。

从后台突破的话,就需要实现IRulesProvider接口,其实很多的验证框架都是实现这个接口来实现验证和输出的。

为了验证我的理论是否正确,终于在一个不眠之夜进行了前台的验证,结果跟我想象的是一样的。

今天终于有时间来验证下后台,我用了比较简单的办法来做的,Controller层的代码如下所示:

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create(User user, FormCollection formCollection)
        {
            if (formCollection["custom"]==string.Empty)
            {
                ModelState.AddModelError("CustomValue", "自定义验证字段无效");
            }
            
            var errors = DataAnnotationsValidationRunner.GetErrors(user);
            if (errors.Any())
            {
                new RulesException(errors).AddModelStateErrors(ModelState,"user");
            }
            ViewData["custom"] = formCollection["custom"];

            return View();
        }

通过使用ModelState添加错误信息,就实现了我们想要的验证同步效果。

ViewData["custom"] = formCollection["custom"]; 这句话是为了保存状态信息而已。

前台代码如下:

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<MVCValidate.Models.User>" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Create</title>

</head>
<body>
    <% using (Html.BeginForm())
       {%>
    <fieldset>
        <legend>Fields</legend>
        <p>
            <label for="CustomValue">
                CustomValue:</label>
            <%= Html.TextBox("custom")%>
            <%= Html.ValidationMessage("CustomValue")%>
        </p>
        <p>
            <label for="UserName">
                UserName:</label>
            <%= Html.TextBox("user.UserName") %>
            <%= Html.ValidationMessage("user.UserName")%>
        </p>
        <p>
            <label for="Password">
                Password:</label>
            <%= Html.TextBox("user.Password") %>
            <%= Html.ValidationMessage("user.Password")%>
        </p>
        <p>
            <label for="Address">
                Address:</label>
            <%= Html.TextBox("user.Address")%>
            <%= Html.ValidationMessage("user.Address")%>
        </p>
        <p>
            <label for="Telephone">
                Telephone:</label>
            <%= Html.TextBox("user.Telephone")%>
            <%= Html.ValidationMessage("user.Telephone")%>
        </p>
        <p>
            <label for="Age">
                Age:</label>
            <%= Html.TextBox("user.Age")%>
            <%= Html.ValidationMessage("user.Age")%>
        </p>
        <p>
            <label for="Email">
                Email:</label>
            <%= Html.TextBox("user.Email")%>
            <%= Html.ValidationMessage("user.Email")%>
        </p>
        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
    <% } %>

</body>
</html>
custom是我们扩展的验证字段,本身是不属于DomainModel的部分。
最后,来看下成功后的截图吧。
2010-3-1-1