仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 2759|回复: 12
打印 上一主题 下一主题

[学习教程] ASP.NET教程之尽量挣脱对HttpContext的依附仓酷云

[复制链接]
飘飘悠悠 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-18 11:26:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
实不相瞒,net网页编程是我见过的执行效率最低的程序设计语言,前不久在CSDN论坛上有个评测,计算9999的阶乘,同样的循环算法,net网页编程的耗时是.NET的5倍。  本文出自:http://www.ckuyun.com/JeffreyZhao/archive/2009/03/09/no-dependency-to-httpcontext.html
  我们持续《ASP.NETMVC单位测试最好理论》,明天次要议论HttpContext的依附成绩。
  在ASP.NET中举行单位测试的天敌即是HttpContext,它是ASP.NET的中心,极度庞大,却没法举行Mock1——可见微软可以写出那末复杂的ASP.NET框架真不那末简单。如今这个情况改良了很多,因而人人已可使用System.Web.Abstractions.dll了,这个程序会合供应了关于HttpContext的笼统,也就是HttpContextBase笼统类。因而在ASP.NETMVC中,各类组件均依附于HttpContextBase而不是HttpContext。这是一个优异的做法,人人今后能够尽量地挣脱HttpContext了。
  不外这仿佛又是一个悖论。固然已能够对HttpContext举行Mock(这点加强了可测试性),可是过分依附HttpContext关于单位测试来讲也是一个危险。这是HttpContext对象的天分而至:它其实太庞大了。您应当已发觉到,这是个集万千溺爱于一身的对象,从哀求,复兴,使用程序,缓存……几近包括了Web使用程序必要的一切信息。假如要测试一个依附于HttpContext的办法,您必将要为HttpContext的Mock对象添补各类信息——其庞大水平视营业而定。并且,Mock存眷的是“举动”,也就是说它存眷的是做一件事变所利用“路径”。那末假如做一件事变能够接纳多个路径又会如何?是不是必要在测试之前筹办好一切的路径,而且考证被测试的代码“接纳了,并仅仅接纳了个中一条路径”?因而,Stub渐渐进进人们的视野。Stub存眷的是“形态”……这就是另外一个话题了,还会触及到接纳Record&Replay仍是Arrange-Act-Assert体例来举行单位测试,临时不提。
  之前谈到对视图举行单位测试时,老赵已经谈起在视图中应当只利用ViewData中的数据。这不是第一次提及要保持HttpContext了,自从有了“笼统”这一有益兵器后,统统“反面谐”要素都可以被分别。试想在MVP形式中,View和Presenter都利用各自的笼统举行交互,统统Web控件,HttpContext等对象都不复存在了,人人眼中只要“数据”和“模子”。一样,在ASP.NETMVC的Action办法中,也不该该利用HttpContext,这是基于优秀的“可测试性”而思索的。您大概会想,如今的HttpContextBase对象已能够Mock了啊。没错,它切实其实“能够”,可是如许做会引发单位测试代码的收缩,由于测试代码中的相称部分必需存眷在测试数据的筹办,而不是被测试的功效上。关于一个Action办法来讲,它存眷的应当是用户与营业逻辑的交互,而不是“怎样把HTTP哀求转化为可用的数据”。实在说究竟,仍是要“分别存眷点”。
  在ASP.NETMVC中卖力“转化数据”的条理为ModelBinder。关于这一点,现有的“示例”多数存眷把Form或QueryString中的数据转化为Action参数上,不外ModelBinder可用的中央实在更多。比方在《最好理论》的代码中,底本AccountController的Delete办法完成以下:
  1. publicActionResultDelete(stringuserName){this.MiddleTier.UserManager.Delete(userName);UriurlReferrer=this.Request.UrlReferrer;returnthis.Redirect(urlReferrer.ToString());}
复制代码
  在删除指定对象以后,页面将跳转到UrlReferrer地点中。在下面的代码中,这个值将经由过程会见Request.UrlReferer来取得。这就使您的Action办法与HttpContext发生了依附,因而它的单位测试代码就必要如许编写:
  1. [TestMethod]publicvoidDeleteTest(){stringuserName="jeffz";UriurlReferrer=newUri("http://www.microsoft.com");varmockHttpContext=newMock<HttpContextBase>();mockHttpContext.Setup(c=>c.Request.UrlReferrer).Returns(urlReferrer);varmockController=this.GetMockController();mockController.Setup(c=>c.MiddleTier.UserManager.Delete(userName)).Verifiable();mockController.Object.ControllerContext=newControllerContext(mockHttpContext.Object,newRouteData(),mockController.Object);mockController.Object.Delete(userName)...}
复制代码
  在单位测试代码中,我们Mock了一个HttpContextBase对象,让它的Request.UrlReferrer属性前往我们筹办好的对象,再机关一个新的ControllerContext并交给Controller。而假如我们的UrlReferrer可以作为Delete办法的参数,那末单位测试代码就会一会儿复杂良多:
  1. [TestMethod()]publicvoidDeleteTest(){stringuserName="jeffz";UriurlReferrer=newUri("http://www.microsoft.com");varmockController=this.GetMockController();mockController.Setup(c=>c.MiddleTier.UserManager.Delete(userName)).Verifiable();mockController.Object.Delete(userName,urlReferrer)...}
复制代码
  有些伴侣大概会问,不就是从Request的UrlReferrer属性中取值吗?我们为何要机关一个ControllerContext,不克不及间接设置Controller对象吗?比方如许就复杂多了:
  1. mockController.Setup(c=>c.Request.UrlReferrer).Returns(urlReferrer);
复制代码
  仿佛可行,不外您运转的时分就会发明,框架会抛出非常,说只要接口的成员,或能够override的成员才干够被Mock。没错,Controller的Request属性不是virtual的,没法override。Controller类云云计划是存心的,目标就是限定了可用的路径。试想,假如您Mock了Controller.Request属性,可是程序代码经由过程Controller.HttpContext.Request举行会见又怎样办呢?相似的做法另有对办法重载的计划。一样平常来讲,城市把个中几个办法托付给个中独一的办法,而只要谁人办法是能够被override的。如许在编写测试时,我们唯一的Mock出口便断定了,制止了测试代码过分懂得办法完成的成绩。
  回到正题。假如要让Delete办法接urlReferrer受参数,那末我们就要编写ModelBinder相干的组件:
  1. publicclassUrlReferrerModelBinder:IModelBinder{publicobjectBindModel(ControllerContextcontrollerContext,ModelBindingContextbindingContext){returncontrollerContext.HttpContext.Request.UrlReferrer;}}
复制代码
  并使其能够间接使用到Action的参数上:
  1. publicclassUrlReferrerAttribute:CustomModelBinderAttribute{privatestaticUrlReferrerModelBinders_modelBinder=newUrlReferrerModelBinder();publicoverrideIModelBinderGetBinder(){returns_modelBinder;}}
复制代码
  因而乎,我们的Delete办法即可写为:
  1. publicActionResultDelete(stringuserName,UriurlReferrer){this.MiddleTier.UserManager.Delete(userName);returnthis.Redirect(urlReferrer.ToString());}
复制代码
  现在的代码,不管是使用程序仍是框架类库,都必需思索“可测试性”这个请求。比方.NET3.0的WF,因为其可测试性欠安一向为人所诟病。如今我们在编写程序时,要时候扣问本人:“这么做便利测试吗?”思索到这个成绩,大概您就会宁神地做出某些决定了2。
注1:实在仍是能够Mock的。比方Typemock利用Profiler的体例举行间接注进,能够Mock任何成员。不外,假如Moq等框架没法满意您的必要,一样平常即是您的计划有些成绩了。
注2:比方,事实让Action办法前往ActionResult,仍是前往void,并间接经由过程Response输入呢?
我以前很喜欢Serv-U,自从它用net网页编程重写之后我就再也没用过,实在是太慢了,我宁可用IIS搭建FTP,虽然IIS搭建FTP在权限管理上很不灵活。
冷月葬花魂 该用户已被删除
沙发
发表于 2015-1-21 06:21:09 | 只看该作者
目前在微软的.net战略中新推出的ASP.net借鉴了Java技术的优点,使用CSharp(C#)语言作为ASP.net的推荐语言,同时改进了以前ASP的安全性差等缺点。但是,使用ASP/ASP.net仍有一定的局限性,因为从某种角度来说它们只能在微软的WindowsNT/2000/XP+IIS的服务器平台上良好运行(虽然像ChilliSoft提供了在UNIX/Linux上运行ASP的解决方案.
小魔女 该用户已被删除
板凳
发表于 2015-1-24 15:12:06 | 只看该作者
在调试JSP代码时,如果程序出错,JSP服务器会返回出错信息,并在浏览器中显示。这时,由于JSP是先被转换成Servlet后再运行的,所以,浏览器中所显示的代码出错的行数并不是JSP源代码的行数。
海妖 该用户已被删除
地板
发表于 2015-1-25 12:16:14 | 只看该作者
主流网站开发语言之PHPHP的全名非常有趣,它是一个巢状的缩写名称——“PHP:HypertextPreprocessor”,打开缩写还是缩写。PHP是一种HTML内嵌式的语言(就像上面讲的ASP那样)。而PHP独特的语法混合了C,Java,Perl以及PHP式的新语法。它可以比CGI或者Perl更快速地执行动态网页。
山那边是海 该用户已被删除
5#
发表于 2015-1-25 13:22:39 | 只看该作者
微软又推出ASP.NET。这不是ASP的简单升级,而是全新一代的动态网页实现系统,用于一台WEB服务器建立强大的应用程序。是微软发展的新体系结构.NET的一部分,是ASP和.NET技术的结合。
愤怒的大鸟 该用户已被删除
6#
发表于 2015-1-28 10:44:58 | 只看该作者
众所周知,Windows以易用而出名,也因此占据不少的服务器市场。
飘飘悠悠 该用户已被删除
7#
 楼主| 发表于 2015-2-5 14:16:07 | 只看该作者
有一丝可惜的是,这个系列太强了,Java阵营的朋友根本就是哑口无言...争论之火瞬间被浇灭,这不是我想这么早就看到的,但是值了。
不帅 该用户已被删除
8#
发表于 2015-2-12 03:15:24 | 只看该作者
但是目前在CGI中使用的最为广泛的是Perl语言。所以,狭义上所指的CGI程序一般都是指Perl程序,一般CGI程序的后缀都是.pl或者.cgi。
若天明 该用户已被删除
9#
发表于 2015-2-22 20:15:29 | 只看该作者
ASP在执行的时候,是由IIS调用程序引擎,解释执行嵌在HTML中的ASP代码,最终将结果和原来的HTML一同送往客户端。
小女巫 该用户已被删除
10#
发表于 2015-2-24 10:38:25 | 只看该作者
Asp.net:首先来说,Asp.net和Asp没什么关系,看着像是升级版本什么的,其实没什么联系。Asp是脚本编程,用的是ASP语言,而ASP.net用的是C#语言,完全不同的东西。
谁可相欹 该用户已被删除
11#
发表于 2015-3-12 23:36:36 | 只看该作者
ASP.net的服务器,要求安装一个.net环境,当然我这里指的是windows系统,顺便点一下,.net只能放在windows环境里来运行。Asp.net1.1的就装Framework1.1,Asp.net2.0的就装Framework2.0。
灵魂腐蚀 该用户已被删除
12#
发表于 2015-3-20 05:27:47 | 只看该作者
比如封装性、继承性、多态性等等,这就解决了刚才谈到的ASP的那些弱点。封装性使得代码逻辑清晰,易于管理,并且应用到ASP.Net上就可以使业务逻辑和Html页面分离,这样无论页面原型如何改变。
活着的死人 该用户已被删除
13#
发表于 2015-4-9 16:32:30 | 只看该作者
这也就是最近几年来随着各种新的后台技术的诞生,CGI应用在Internet上越来越少的原因。CGI方式不适合大访问量的应用。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-12-23 07:32

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表