今天你抛弃了ASP.NET了吗?问题篇
我用ASP.NET开发也有几年了,一直在忍耐,忍耐,终于,我实在忍无可忍了。ASP.NET制造出来的问题比带来的好处多的多的多的多!
1. VIEWSTATE之类的问题就不说了,为了持久客户端状态,用了个通用的架构,无法做到区别对待,结果一棒子把其他的优势都淹没了。我就在想,为什么ms不能够判断我的方法应用了什么web control,然后智能的进行状态持久呢?
参考:http://www.cnblogs.com/artech/archive/2007/04/06/702658.html 浅谈ASP.NET的Postback
2. 最最最让我无法忍受的,就是在ASP.NET里面,VS的“查询引用”、“重构”等功能变的死慢。我只是想看看这个DLL的某个方法被什么代码引用了,结果一旦项目有个网站项目,那么整个过程变的死慢。原因就是:asp.net的无聊codebehind用了动态编译技术,根据页面的web control在生成dll的时候自动建立webcontrol的代码对象,这个就导致了vs在构造引用索引的时候变的死慢。
参考:http://www.cnblogs.com/artech/archive/2007/05/21/753620.html 深入剖析ASP.NET的编译原理之一:动态编译(Dynamical Compilation)
3. 另外一个让我超级无法接受的,就是ASP.NET里面对版本的控制。每次我进行项目DEBUG的时候,90%的时候,编译器会说:“引用的版本不是最新版本,debug可能不准确。。。”之类的。比如说:
bbbbb.dll 引用了 aaaaa.dll <1.0.0.0>
ccccc.dll 引用了 aaaaa.dll <2.0.0.0>
网站引用了 aaaaa.dll<3.0.0.0> bbbbb.dll, ccccc.dll
这个时候,如果要对网站debug,添加了aaaaa项目,想进入aaaaa项目就会报错,因为bbbbb/ccccc仍然引用了个旧的版本号。项目很大的时候,我不可能把所有网站引用到的dll全部都编译一次,要对某个dll进行项目debug的时候,就崩溃了。
4. 我到现在还没有看出来asp.net AJAX到底有什么很强的优势,我只是感觉到用了ajax之后,整个网站都很慢。因为使用了coolite作为客户端框架,结果看一个gridview都要load半天,而用传统的html(别笑我)、简单的aspx没有这个问题。这说明了压根不是服务器问题,也不是aspx的核心机制问题,就是这些ajax+webcontrol+庞大的js库导致的。
5. 如果再加一个罪名,就是最新的Oracle Padding Attack。这个不说不知道,一说,我才发现,为什么之前的日志总是会出现Resource.axd的请求出错,很多非法的请求。开始以为是服务器响应问题,后来才发现,是有人在攻击。
6. 再来,就是ASP.NET 2.0提出的傻×编译,竟然把项目一个folder编译为一个随机字符串的dll,例如appCode_xsdfasdf.dll...... 我崩溃了!!!部署一个项目有几十个dll,而且每次都不一样,玩我是吧。让我自己手动根据时间去清旧的dll,然后部署。我还以为有什么好处,结果不得不装一个插件,回到1.0的整体打包时代。
7. ASP.NET 2.0的时候,所有东西都交给了HttpContext这个庞然大物,结果呢?无法测试驱动、无法单元测试。虽然到了后期3.0+进行了重构,提供了一些接口,但是这个败笔仍然存在着。
微软的C#是不错,也许是因为JAVA不错,所以微软抄起来有个方向。至于ASP.NET这个东东,我实在是无语了。结果后来,微软自己也出来个ASP.NET MVC,来了个改朝换代。
那么这个被我批的一无是处的ASP.NET到底还剩下了什么?MS的大牛架构师们,到底有什么值得学习的思路还能被挖掘?
彻底瓦解ASP.NET的核心 寻找最有价值的思想
--------------------------------------------------
我准备用非常简短的一段话,把ASP.NET的思想描绘出来(非严谨模式,如果错误,请指出)。
B/S 就是一个标准的请求响应模型,客户端发送“hello”,服务器返回“world”。ASP.NET在这个模型下面,进行了一系列的封装建模,形成了自己的一套aspx解决方案。我就从项目编译开始说起。
1. 建立一个asp.net项目,包含了aspx + aspx.cs文件,aspx有个标签指向了引用的aspx.cs文件,aspx.cs就成为了的CodeBehind。
但这个aspx.cs文件是半成品,里面没有声明用户使用的各种控件对象(TextBox...),所以是partial class,微软在我们编写代码的时候VS智能提示了控件,编译的时候动态生成了控件。
2. 项目预编译为DLL的时候,aspx页面自动继承了HttpHandler,成为一个请求的处理核心。
3. 用户向IIS请求页面,经过了HttpModule -> HttpFactory, 然后获取HttpHandler(也就是我们的Page)进行请求处理, 最后输出到客户端(response.write(xxx))。
这个过程很像spring的动态加载,至于如何优化,我不敢乱猜,有牛人写了文章[1] [2] 。MS肯定会用了临时XML文件(说明dll的更新度)、目标路径的aspx文件(指向需要加载的dll位置)等一些列去判断如何加载DLL。
4. 当用户点击了一个button进行提交之后,aspx会把页面的显示数据(包括了庞大的GridView)压入ViewState,传递给aspx.cs,所以我们的代码才能获取Textbox.Text这些数值,我们对控件设置了数值之后,aspx.cs又会把这些数据压入ViewState,传递到客户端,再赋值到控件。
过程中,页面部分肯定需要JS去帮助,服务端肯定需要类似反射的机制去赋值、取值。至于是动态编译(Emit)还是真的去反射,就需要进一步考察。
不知道这4段话,能否对ASP.NET进行了一个概括?ASP.NET里面最失败的,我认为就是过多的使用了动态编译、动态加载这些技术。虽然提高了一丁点的开发效率,但是带来的问题确实一大堆。
既然ASP.NET的核心技术就是如此,我现在就希望寻找、开发一种ASP.NET的核心技术,即吸收了ASP.NET作为服务端开发的优势,又拥有页面快速开发的效果。
抛弃ASP.NET, 寻找优秀的继位者
-------------------------------------
1. 网站必须要用ASP.NET,否则我们写的C#就费了,各种框架就白写了。那么,必然要使用Httphandler去做业务逻辑处理。
2. 页面一定不使用Web Control这些控件。用现在流行的JS框架替代,例如JQuery, ExtJs.
3. 页面的逻辑部分,使用JQuery Template解决。
4. 服务端和页面传递使用Json协议。
要替换ASP.NET,我就思考了以上几点(说出来才4句话,我可是搜索资料+思考了几天了) 。
首先我不会自己继承HttpHandler,去web.config注册来实现业务逻辑。毕竟一个aspx.cs就是一个httpHandler,我为啥要多此一举呢?可以设想一下,如果我自己继承了httphandler之类的,那么用户的请求如何路由到指定的业务逻辑代码?这个过程也ASP.NET里面的动态加载类似了,最终又是一套复杂的架构。
其次,我一定不用任何的服务端脚本、标签技术,我要彻底的让页面和服务器分离。页面就使用js解析json去操作,最多使用个javascript template去实现动态页面。否则,一旦用了asp.net的页面逻辑技术(web control 。。。),就前功尽弃了。
最后,我的业务代码一定不会放在ASP.NET的网站项目,否则那个该死的智能提示会要我命的,因此需要自己继承一个Page,然后通过一种简单的注册机制,指向实际的项目代码。这样整个网站项目就是前端页面+一个替代框架。其余的都会在一个新的类库。
大概思路如上所述,下一篇我尝试贡献一个原型系统,希望能够通过继承现有的一些前端框架,再加上传统的后台逻辑编码,实现真正的.NET FRAMEWORK下的快速开发。