【飞秋】Asp.net MVC2 model验证 看似美好,实则让人失望。

ASP.NET mvc tree 树 类似 TreeView 控件 mvc tree 树 支持mvc2 mvc3 具体请查看调用列子,很简单的。使用请详细看TreeData每个字段的意义。和asp.net 种TreeView 控件一样。 立即下载

最近几天看了一下Asp.net MVC2的model验证,初始的感觉让我眼前一亮,于是去看了看它的源代码,Validation和Metadata部分应该是从Dynamic Data哪里得到的灵感,一切似乎都那么美好,网上关于如何使用的文章页很多,但是随后的一段经历让我对Validation部分的代码和设计产生了很大的不满,它所夸赞的可以很容易与其它验证框架的集成其实也并不是那么容易,下面我就来说说为什么我会对它不满:

当前的MVC的验证是在Model的属性上加入Attribute,如下:

 

代码
 1
 2     [DisplayColumn("UserName", "Password", true)]
 3     public class LogOnModel
 4     {
 5         [Required]
 6         [DisplayName("User name")]
 7         public string UserName { get; set; }
 8
 9         [Required]
10         [DataType(DataType.Password)]
11         [DisplayName("Password")]
12         public string Password { get; set; }
13
14         [DisplayName("Remember me?")]
15         public bool RememberMe { get; set; }
16
17         public EmbeddedClass Embedded { get; set; }
18     }
19
20     public class EmbeddedClass
21     {
22         [DisplayName("Try count")]
23         [Range(3, 5)]
24         public int TryCount { get; set; }
25
26         [DisplayName("Non Model")]
27         public string NonModel { get; set; }
28     }
 

 

 

但是随之而来的问题也来了,那就是

1。 过多的属性(Attribute)使得Model过于臃肿,

2。一个Model代表的是一个类,它的实例应该有自己的Attribute, 如果是把Attribute加在了Model上,那么所有的实例只能使用同样的Attribute,在我们的程序中很多的类经常是在很多函数中使用,并且每个函数会有不同的验证要求,

3。 如果是简单类型的参数,就不能做一些验证了,譬如范围验证。

4。 如果类中的属性是非值类型的(非值类型,不包括string),那么验证并不会去验证这个属性实例内部的属性,譬如我上面的Embedded 属性。

这些让我有了一个自己的想法,所以于是想把这些验证放在配置文件中,于是仔细的看了MVC2绑定和验证部分的源代码,想看看如何扩展。我比较懒,DefaultModelBinder 这个类是asp.net mvc2 中用于绑定数据和调用验证的最重要的类,其中Model的验证部分是在 函数OnModelUpdated中被调用的,

 

 1         protected virtual void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext) {
 2             Dictionary<string, bool> startedValid = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
 3
 4             foreach (ModelValidationResult validationResult in ModelValidator.GetModelValidator(bindingContext.ModelMetadata, controllerContext).Validate(null)) {
 5                 string subPropertyName = CreateSubPropertyName(bindingContext.ModelName, validationResult.MemberName);
 6
 7                 if (!startedValid.ContainsKey(subPropertyName)) {
 8                     startedValid[subPropertyName] = bindingContext.ModelState.IsValidField(subPropertyName);
 9                 }
10
11                 if (startedValid[subPropertyName]) {
12                     bindingContext.ModelState.AddModelError(subPropertyName, validationResult.Message);
13                 }
14             }
15         }
 

在这个函数中,ModelValidator.GetModelValidator(bindingContext.ModelMetadata, controllerContext),有这么一句,也就是获得ModelValidator, 悲剧就在此函数中打开这个函数看看:

代码

 1 public static ModelValidator GetModelValidator(ModelMetadata metadata, ControllerContext context) {
 2             return new CompositeModelValidator(metadata, context);
 3         }
 4
 5         public abstract IEnumerable<ModelValidationResult> Validate(object container);
 6
 7         private class CompositeModelValidator : ModelValidator {
 8             public CompositeModelValidator(ModelMetadata metadata, ControllerContext controllerContext)
 9                 : base(metadata, controllerContext) {
10             }
11
12             public override IEnumerable<ModelValidationResult> Validate(object container) {
13                 bool propertiesValid = true;
14
15                 foreach (ModelMetadata propertyMetadata in Metadata.Properties) {
16                     foreach (ModelValidator propertyValidator in propertyMetadata.GetValidators(ControllerContext)) {
17                         foreach (ModelValidationResult propertyResult in propertyValidator.Validate(Metadata.Model)) {
18                             propertiesValid = false;
19                             yield return new ModelValidationResult {
20                                 MemberName = DefaultModelBinder.CreateSubPropertyName(propertyMetadata.PropertyName, propertyResult.MemberName),
21                                 Message = propertyResult.Message
22                             };
23                         }
24                     }
25                 }
26
27                 if (propertiesValid) {
28                     foreach (ModelValidator typeValidator in Metadata.GetValidators(ControllerContext)) {
29                         foreach (ModelValidationResult typeResult in typeValidator.Validate(container)) {
30                             yield return typeResult;
31                         }
32                     }
33                 }
34             }
35         }
 

它尽然是直接构造了一个CompositeModelValidator,这个CompositeModelValidator还是私有的,没有用工厂模式,CompositeModelValidator不能继承重写,也就是说第一、如果想验证,那就只能是验证属性,不能验证简单类型(当然有其他办法可以解决这个问题),第二、也就是我上面提到的第四点,如果属性是非值类型,对不起不能验证其内部的属性,第三、对于验证一个Model那些部分我控制不了,只能是它的属性。这三点使我我本来想扩展MVC2的验证部分,也就是继承自ModelValidator,看来是不行了,只能自己写新的验证部分了,只觉得MVC2有点失败,比其MVC1的成功,它有点让我失望。

 

 当然,这并不代表了,我上面所说的那些就做不了,我会在下一篇中给出利用Enterprise Library 的验证来实现 扩展。


关注技术文章飞秋:http://www.freeeim.com/,24小时专业转载。

相关推荐

Rust 与 C/C++:Rust 比 C/C++ 更好还是只是“技能问题”?

对于许多嵌入式系统开发人员而言,的崛起似乎掀起了一股不小的浪潮,特别是在相较于传统的语言,Rust的“内存安全”优势让人眼前一亮。然而,是否可以将Rust作为C/C++的替代品?或者说,Rust是否真的比C/C++更好,抑或它只是一个“技能问题”呢?在嵌入式开发的领域,我观察到,尽管Rust在一些高性能、内存安全敏感的场景中受到了广泛推崇,但它在实际应用中的普及度,特别是在嵌入式领域,依然有限。今天,我会从多个角度探讨这个问题,并且分享一些对于Rust、C/C++以及嵌入式系统开发的个人见解。

qq_63315166的博客 1300

ASP.NET MVC异常处理

为了让网站运行时不出现因为异常而报错,接下来是今天百度后的学习笔记。 1.最简单的方法则是在配置文件里加上<customErrors>节点 <customErrors>节点用于自定义一些url,其作用是当网站出现错误时跳转到此url。 <customErrors mode="On" defaultRedirect="1.html"> ...

weixin_30567471的博客 222

Quanto option期权公式推导(更新中)

Quanto期权不同于以标的股票或资产的计价货币支付最终收益的普通欧式期权,它以另一种货币以预先确定的汇率支付最后的收益。以股票B的计价货币来计价的quanto看涨期权的收益为F0×max⁡(Sa(T)−K,0)×Sb(T)F_0 \times \max(S_a(T)-K, 0) \times S_b(T)F0​×max(Sa​(T)−K,0)×Sb​(T) 其中SaS_aSa​以货币A计价,SbS_bSb​以货币B计价,F0F_0F0​是预先固定的汇率. 假设上述股票均遵循几何布朗运动,可以得到以下恒等式

qq_41782124的博客 3687

MVC中Html.EditorFor宽度及高度怎么设定

因为是转载文章 在此标明出处,以前有文章是转的没标明的请谅解,因为有些已经无法找到出处,或者与其它原因。 如有冒犯请联系本人,或删除,或标明出处。 因为好的文章,以前只想收藏,但连接有时候会失效,所以现在碰到好的直接转到自己这里。 原文 出处http://www.myexception.cn/asp-dotnet/551537.html MVC中Ht

路漫漫 修远兮 1万+

基于PyTorch的BP神经网络PID控制器动态调参实战

本文详细介绍了基于PyTorch的BP神经网络PID控制器动态调参实战,结合BP神经网络的自适应能力和PID控制算法的经典优势,实现工业控制中的高效参数调整。通过PyTorch实现BP-PID融合架构,包括网络设计、损失函数优化及动态调参技巧,显著提升控制性能,适用于温度控制、电机控制等场景。

weixin_29094775的博客 523

kali破解WIFI密码

今天我们来学习一下通过kali和一个好的字典来破解WIFI密码。 声明:此教程仅供学习研究使用,严禁使用此技术进行非法行为 首先我们需要一个具有监听功能的无线网卡(这里我给大家推荐:rt3070) 本章实验通过虚拟机VMware进行: 先通过services.msc来打开VMware USB Arbitration Service 插上监听网卡,连接USB到虚...

#的博客 5814

ASP.NET MVC4入门到精通系列目录汇总

http://www.cnblogs.com/jiekzou/p/4772273.html************************ 序言 最近公司在招.NET程序员,我发现好多来公司面试的.NET程序员居然都没有 ASP.NET MVC项目经验,其中包括一些工作4、5年了,甚至8年10年的,许多人给我的感觉是:工作了4、5年,Web开发依旧停留在拖控件的水平,最最基本的算 法,递归、排...

weixin_33690963的博客 115

基于LangGraph的智能报告生成平台项目分析

不知道你是否知道或者了解OpenAI and Gemini Deep Research。他们是一种能够根据输入问题进行规划、结合网络搜索获取信息并最终呈现结果的研究工具或技术。那这样research是如何实现的呢?最近刚好看到一个实现类似功能的开源项目: open_deep_search。本文将基于该项目进行代码层面剖析。

u011160113的博客 925

C#.NET MVC 导出WORD文档

使用C#.NET 的MVC模式将记录导出为Word

七海桑城 4124

9 海康视觉平台VisionMaster 上手系列:典型案例之螺丝机案例

海康视觉平台VisionMaster 上手系列:典型案例之螺丝机案例 快速入门 工业机器视觉 机器视觉

HuangGong2022的博客 7181

uniapp 如何封装实现任意页面都能使用的全局弹窗

项目内容场景全局监听消息提示难点uniapp 无法全局挂载组件解决方案动态创建 DOM + 动态 Vue 实例优势跨页面 / 不依赖页面组件树 / 灵活调用如果你使用的是小程序平台,DOM 操作可能受限,需要用或方式兼容处理。想支持多个弹窗堆叠?你可以扩展,加个弹窗队列管理器。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 946

IIS7部署ASP.NET MVC4程序报错解决

处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler” 原文地址:http://www.cnblogs.com/navy235/archive/2012/05/10/2494333.html 今天安装了windows7 开发web项目需要安装IIS,当安装完以后,web程序已经映射到了本地IIS上,运

海涛的博客 1万+

支持UE4.27、UE5.0、UE5.1、UE5.2、UE5.3、UE5.4、UE5.5的VS2022一键安装方法

本文提供了两种安装VS2022以支持UE5开发的方案。方案一通过百度网盘提供一键安装包,下载解压后以管理员身份运行批处理文件即可完成安装。方案二需从微软官网下载安装程序,通过创建包含特定参数的批处理文件来自定义安装组件。两种方案都需保持联网环境,建议先卸载旧版VS。安装完成后可测试打包UEC++项目Windows包。

2501_93651177的博客 356

c# winForm父子窗口信息交互方式介绍

1,从父窗体向子窗体传值 // 从父窗体向子窗体传值 private void btnParent_click(object sender, EventArgs e){ //方法一 通过重写构造函数传值 重写子窗体的构造函数 // FrmChild chidl = new FrmChild(txtParent.Text); // child.ShowDialog(); // 方法二 通过公共变量传值,如果这个变量是在父窗体中声明的,那么需要时静态变量 // FrmChild chidl = ne

zlhcsm的博客 1554

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

ASP.NET MVC 随想录—— 使用ASP.NET Identity实现基于声明的授权,高级篇

在这篇文章中,我将继续ASP.NET Identity 之旅,这也是ASP.NET Identity 三部曲的最后一篇。在本文中,将为大家介绍ASP.NET Identity 的高级功能,它支持声明式并且还可以灵活的与ASP.NET MVC 授权结合使用,同时,它还支持使用第三方来实现身份验证。 关于ASP.NET Identity 的基础知识,请参考如下文章: ASP.NET MVC 随...

weixin_34233679的博客 555

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

ASP.NET MVC5 运行原理

这是来自微软官方的运行原理图 当前请求到达 IIS服务器后,同样动态请求被转发到net平台,在管道执行过程中(IHttpModule),有一个特殊的IHttpModule 它就是UrlRoutingModule,MVC从这里就开始了。 它 根据当前的HttpContext封装HttpContextWrapper,从Route路由表中取出和当前URL匹配的路由数据(RouteData)...

绝圣弃智-零的博客 1358

the schema version of 'microsoft.aspnet.mvc' is incompatible with version of nuget

Nuget versioning issue with package restore http://stackoverflow.com/questions/12035976/nuget-versioning-issue-with-package-restore Restart VS as administrator, extension manager uninstall nu...

weixin_30419799的博客 133

VS创建MVC出错解决方法

搞定

weixin_34337381的博客 258

ASP.NET MVC利用log4net记录错误日志信息的简单运用

1、在NuGet中下载log4net包 2、在配置文件中配置以下代码: &lt;configuration&gt; &lt;configSections&gt; &lt;section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/&gt; &lt;/confi...

LLL技术交流 877

javax.servlet.ServletException: Servlet.init() for servlet dispatcherServlet threw exception

javax.servlet.ServletException: Servlet.init() for servlet dispatcherServlet threw exception 查看有没有缺少包 包出现冲突 由于我的pom文件引入了easyexcel依赖 从而导致了easyexcel的依赖与自己的出现了冲突 所以,建议各位先去仔细检查下pom文件,有没有出现包冲突或者缺少包 ...

诸事顺利 1820

Asp.Net面试题

多线程同步: 1、Lock,lock的参数必须是基于引用类型的对象 2、System.Threading.Interlocked,对于整数数据类型的简单操作,可以用 Interlocked 3、ReaderWriterLock 需要读取资源的数据,而不是修改资源的数据,在这种情况下获取资源的独占权无疑会影响运行效率,因此.Net提供了一种机制,使用ReaderWriterLock进行资源访

布里渊区 3728

ASP.NET MVC4中用 BundleCollection使用问题手记

ASP.NET MVC4中对JS和CSS的引用又做了一次变化,在MVC3中我们这样引用资源文件: link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" /> 将在运行的时候自动将虚拟(相对)路径转换为应用程序绝对路径。这是比较传统的引用方式,尽管他做了一次转换操作,对服务器的请求数量压

sgear 4109

MVC5自定义T4模板

在程序包控制台输入install-package mvc5codetemplatescsharp为项目安装mvc5codetemplates 创建的myCreate.tt内容如下 @model                       @Html.AntiForgeryToken()      int i=0;   foreach

weixin_38326624的博客 818

MVC 当前上下文中不存在名称“Styles” “Scripts”

  它们在程序集System.Web.Optimization下,只要全名引用即可   修改配置 在web项目的Views下的web.config修改如下即可,如果是Areas下,处理方法相同 &lt;system.web.webPages.razor&gt; &lt;host factoryType="System.Web.Mvc.MvcWebRazorHostFact...

weixin_34220834的博客 520
上一篇: 【飞秋】OpenExpressApp对建模支持的初步计划
下一篇: 【飞秋】进一步完善 -- GEF创建助手工具条
普通网友
博客等级 码龄22年 1万+粉丝 3156原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值