详细可以参考这两篇文章:
http://msdn.microsoft.com/msdnmag/issues/0900/cutting/default.aspx
http://msdn.microsoft.com/msdnmag/issues/1000/cutting/default.aspx
那时候,设计的目标是为了做Demo CD,而作为Demo CD不能够要求客户机上必须装有IIS,所以就需要设计一个轻量级的离线的ASP Host。在2000年,这两篇文章归到Cutting Edge去了,不过这样的技术在当时来说确实非常Cutting Edge了,一般Demo CD最多内附一个PWS(Personal Web Server)让Win9x也能装上看看ASP的效果,基本上没有人会想到要实现自己的ASP Host。这不仅仅是技术问题,而且还是思想问题,RIA还没有提出,用HTML或者Flash做Windows应用还是非常罕见,没有人有理由要实现一个随处可运行的展示给localhost看的Web Host。
现在Cassini来了,靠的主要是System.Web.Hosting这个namespace下面的东西。其实要实现ASP.NET Host关键就是要把Request流的内容倒入HttpWorkerRequest,之后HttpWorkerRequest配合HttpRuntime就是你所要的一切输入了,而且是完整封装好和普通ASP.NET无异的了。至于输出,Cassini同样是需要实现原本HttpResponse直接让IIS实现的功能,自行把Response流的各种Header写入,然后写Response流的主体。
System.Web.Hosting其实是ASP.NET 1.x就有的东西,看来MS一早就准备了要让ASP.NET可以脱离IIS运行。如果非Windows平台上的.NET Framework能够弄出来,就能够轻易地把ASP.NET迁移过去。现在也有人在搞.NET Compact Framework上的ASP.NET Hosting(因为.NET CF没有System.Web.Hosting),那么ASP.NET就能够成为全平台的Web应用了哦,既能在线也能离线。
2006年3月31日星期五
Macro CSS, CSS Script or Xml CSS?
继续上次那篇Programmable CSS,我现在有三个实现方案:
1.Macro CSS
用Macro来实现简单的CSS编程,既然CSS是纯文本输出,那么可以考虑仿照ASM/C++的Macro那样,定义一些简单的文本输出Macro,例如Coo所谓的自定义颜色常量就完全可以好像C++定义常量那样定义。页面就引用一个.mcss文件,这个后缀在服务器端关联一个HttpHandler(假设在.NET环境,其他语言环境自行变通),专门负责处理.mcss文件里面的Macro输出标准css。
这样做需要对Macro CSS用正则表达式进行分析,提取指令,还要做变量存储,我觉得这是比较麻烦的事情。例如变量存储,我上次说了要实现子元素可以设定padding为父元素padding的加上1px,这就需要允许在Macro里面定义变量,然后Macro运行时这些变量是无类型的,或者说是动态类型的,要支持各种运算,烦死,简直就是要自己写一个Macro Engine。
不写Macro Engine的方法有没有?也还是有的,就是把Macro转换为对应的服务器端脚本,例如ASP.NET,然后让服务器帮你编译执行,这样会舒服很多。这和直接写个满是<% %>的CSS有什么不同?我们可以为Macro CSS编写转换到不同服务器端语言的引擎,然后同一种Macro CSS就能够运行于任意动态服务器端了。
2.CSS Script
这个东西我不确定是否可行,其实就是完全用Script实现页面CSS的操作。
CSS Script拥有类似Atlas那样的一套完整的、兼容多种浏览器的Framework,然后能够用Javascript按照类似C#的写法或者类似XML的写法那样直接操作一些Framework中的封装好的CSS对象。简而言之,这就是一个CSS版的Atlas,Atlas用于DHTML和WebService,而CSS Script则用于CSS。或许未来的Atlas将会把CSS操作也封装进去,难说呢。没看过Atlas的一定要先去看看,否则会不明白我说什么的,因为Atlas实在是太过高度封装了。
3.Xml CSS
就是直接用XML来描述一个CSS模型,然后用XSLT来生成CSS,实现起来很简单,只不过用XML来写CSS或许会让人很不习惯,因为要写多很多代码。不过如果有IDE工具支持的话,或许大家都愿意接受。
原本的CSS也是DOM的一部分,除去HTML的DOM,CSS也可以独立成DOM。能够独立成DOM自然也就能够用XML来表示。用XML来表示,就可以向这个DOM增加新的元素,例如常量、运算、条件等,而新增的这些元素都通过XSLT解释最终生成普通的CSS就行了。
1.Macro CSS
用Macro来实现简单的CSS编程,既然CSS是纯文本输出,那么可以考虑仿照ASM/C++的Macro那样,定义一些简单的文本输出Macro,例如Coo所谓的自定义颜色常量就完全可以好像C++定义常量那样定义。页面就引用一个.mcss文件,这个后缀在服务器端关联一个HttpHandler(假设在.NET环境,其他语言环境自行变通),专门负责处理.mcss文件里面的Macro输出标准css。
这样做需要对Macro CSS用正则表达式进行分析,提取指令,还要做变量存储,我觉得这是比较麻烦的事情。例如变量存储,我上次说了要实现子元素可以设定padding为父元素padding的加上1px,这就需要允许在Macro里面定义变量,然后Macro运行时这些变量是无类型的,或者说是动态类型的,要支持各种运算,烦死,简直就是要自己写一个Macro Engine。
不写Macro Engine的方法有没有?也还是有的,就是把Macro转换为对应的服务器端脚本,例如ASP.NET,然后让服务器帮你编译执行,这样会舒服很多。这和直接写个满是<% %>的CSS有什么不同?我们可以为Macro CSS编写转换到不同服务器端语言的引擎,然后同一种Macro CSS就能够运行于任意动态服务器端了。
2.CSS Script
这个东西我不确定是否可行,其实就是完全用Script实现页面CSS的操作。
CSS Script拥有类似Atlas那样的一套完整的、兼容多种浏览器的Framework,然后能够用Javascript按照类似C#的写法或者类似XML的写法那样直接操作一些Framework中的封装好的CSS对象。简而言之,这就是一个CSS版的Atlas,Atlas用于DHTML和WebService,而CSS Script则用于CSS。或许未来的Atlas将会把CSS操作也封装进去,难说呢。没看过Atlas的一定要先去看看,否则会不明白我说什么的,因为Atlas实在是太过高度封装了。
3.Xml CSS
就是直接用XML来描述一个CSS模型,然后用XSLT来生成CSS,实现起来很简单,只不过用XML来写CSS或许会让人很不习惯,因为要写多很多代码。不过如果有IDE工具支持的话,或许大家都愿意接受。
原本的CSS也是DOM的一部分,除去HTML的DOM,CSS也可以独立成DOM。能够独立成DOM自然也就能够用XML来表示。用XML来表示,就可以向这个DOM增加新的元素,例如常量、运算、条件等,而新增的这些元素都通过XSLT解释最终生成普通的CSS就行了。
2006年3月30日星期四
ASP.NET 2.0解决了Code-Behind需要控件声明同步的问题
这显然是一个非常明智而且很早就应该实现的做法,因为已经在HTML中声明为runat="server"的控件,就应该算是声明过,还要在code-behind中同步的用C#代码再声明一个同名控件显然是违反了《程序员修炼之道》中所谓的DRY(Don't Repeat Yourself)原则。
原本ASP.NET 1.x的编译模型是编译站点时先编译code-behind部分,然后得到code-behind部分的Page派生类,等到运行时再编译aspx部分此事得到code-behind部分的派生类(也就是Page的二级派生类),而一旦aspx和code-behind出现控件声明的不同步那么这个继承关系将出现问题。
ASP.NET 2.0的做法就是把aspx和code-behind都看作Page派生类的partial class,并且合成编译,而aspx中所有的控件声明都将在编译时自动转换为C#声明,这样的好处是只有一层Page派生类而且不用同步什么东西,所有东西都是仅声明一次。不过有一个问题就是,到底aspx中的声明是转换为C#的partial class再编译还是能够直接编译呢?转换为C#编译是很直接的思路,ASP.NET 2.0 的内部变化也是说原本由VS.NET 2002/2003做的声明同步工作现在交给ASP.NET Runtime了,但是这样就有一个问题,如果要开发一种新的ASP.NET语言(例如Delphi for ASP.NET 2.0),那么也就必须建立aspx到该语言的翻译,这是十分麻烦的事情。但是如果aspx和code-behind分开编译的话,这好像超出了partial class的能力范围,根据C# 2.0的规范,partial class的所有部分必须是同时编译的,不可以是增量编译的,也不可以是跨语言编译的,而aspx和code-behind都直接编译的话就需要双语言编译,也就需要增量编译。
ASP.NET 2.0还有一个很好的地方,就是部署编译,你能够把整个网站都编译了(包括aspx和code-behind)然后发布,发布目标的aspx将是一个仅引用后台类的控文件,这样性能最好而且也不用担心代码泄漏(特别是编译后的dll再混淆一下的话)。不过因为aspx部分也编译了,所以这样发布的网站发布之后就不能改动。而ASP.NET 2.0还提供另一个极端,就是完全运行时编译。以前ASP.NET 1.x如果是code-behind的话,code-behind部分就必须在VS.NET里面先编译,不过现在ASP.NET 2.0能够自动监测code-behind部分是否有改动过(甚至是/App_Code目录下的其他非UI逻辑的code),如果有就运行时编译,这对于调试来说是挺方便的,不需要每次调时前先在VS.NET里面按Ctrl+Shift+B编译。
原本ASP.NET 1.x的编译模型是编译站点时先编译code-behind部分,然后得到code-behind部分的Page派生类,等到运行时再编译aspx部分此事得到code-behind部分的派生类(也就是Page的二级派生类),而一旦aspx和code-behind出现控件声明的不同步那么这个继承关系将出现问题。
ASP.NET 2.0的做法就是把aspx和code-behind都看作Page派生类的partial class,并且合成编译,而aspx中所有的控件声明都将在编译时自动转换为C#声明,这样的好处是只有一层Page派生类而且不用同步什么东西,所有东西都是仅声明一次。不过有一个问题就是,到底aspx中的声明是转换为C#的partial class再编译还是能够直接编译呢?转换为C#编译是很直接的思路,ASP.NET 2.0 的内部变化也是说原本由VS.NET 2002/2003做的声明同步工作现在交给ASP.NET Runtime了,但是这样就有一个问题,如果要开发一种新的ASP.NET语言(例如Delphi for ASP.NET 2.0),那么也就必须建立aspx到该语言的翻译,这是十分麻烦的事情。但是如果aspx和code-behind分开编译的话,这好像超出了partial class的能力范围,根据C# 2.0的规范,partial class的所有部分必须是同时编译的,不可以是增量编译的,也不可以是跨语言编译的,而aspx和code-behind都直接编译的话就需要双语言编译,也就需要增量编译。
ASP.NET 2.0还有一个很好的地方,就是部署编译,你能够把整个网站都编译了(包括aspx和code-behind)然后发布,发布目标的aspx将是一个仅引用后台类的控文件,这样性能最好而且也不用担心代码泄漏(特别是编译后的dll再混淆一下的话)。不过因为aspx部分也编译了,所以这样发布的网站发布之后就不能改动。而ASP.NET 2.0还提供另一个极端,就是完全运行时编译。以前ASP.NET 1.x如果是code-behind的话,code-behind部分就必须在VS.NET里面先编译,不过现在ASP.NET 2.0能够自动监测code-behind部分是否有改动过(甚至是/App_Code目录下的其他非UI逻辑的code),如果有就运行时编译,这对于调试来说是挺方便的,不需要每次调时前先在VS.NET里面按Ctrl+Shift+B编译。
2006年3月27日星期一
关于中学是否应该教Office应用
Jim跟我说,中学花时间去教Office,还不如教程序设计锻炼一下思维能力。不过最近Piggest却提了一些排版问题,显然不上课那些功能就在二级菜单你也不知道它原来是这样用的。
Office这件东西,有人说只有5%的功能常用,95%的功能常人用不到,所以作为一个聪明的开发商就应该把主要精力花在优化着5%常用功能的易用性上,这是非常合理的。问题是,要完成一份Document所需要的成本是全局的,假如5%常用功能的使用成本很低,但是偏偏你要用到几个5%以外的功能而它们的使用成本非常高,那么无论MS如何优化那5%的功能对此都毫无帮助。例如,很可能你不知道插入分页符,然后通过手动插入回车来实现分页,结果你用20min输入完文章,然后花了10min来分页,但之后你每次改动文档时需要手动调整分页的时间和输入改动的时间是1:1,那么显然输入和分页所花费的时间将趋于1:1,即使输入部分(作为常用功能)优化得很好你做得很快,最终生成Document的成本还是被分页而卡得很高。
降低你用非5%常用功能时的成本,唯一途径就是你接受过比较系统的学习。就好像Piggest去上Maya培训那样,就好像我说学Javascript要必须看O'Reilly的《Javascript权威指南》一样,不经过系统学习那些非常用功能你是不会知道的,这时候那些非常用功能你就只能用常用功能去“模拟”,这时候使用非常用功能的成本就会暴增。很多东西称之为“易学难精”正是因为非常用功能自己学难以了解到,甚至系统教材也没有,只有长期钻研的高手才对该领域有所了解,例如ASP.NET的页面生存周期的细节,MS不肯公开细节,于是就出现了个高手自己用Reflector看ASP.NET源代码和自己做实验然后把结果公布到自己的Blog的现象。
Office这件东西,有人说只有5%的功能常用,95%的功能常人用不到,所以作为一个聪明的开发商就应该把主要精力花在优化着5%常用功能的易用性上,这是非常合理的。问题是,要完成一份Document所需要的成本是全局的,假如5%常用功能的使用成本很低,但是偏偏你要用到几个5%以外的功能而它们的使用成本非常高,那么无论MS如何优化那5%的功能对此都毫无帮助。例如,很可能你不知道插入分页符,然后通过手动插入回车来实现分页,结果你用20min输入完文章,然后花了10min来分页,但之后你每次改动文档时需要手动调整分页的时间和输入改动的时间是1:1,那么显然输入和分页所花费的时间将趋于1:1,即使输入部分(作为常用功能)优化得很好你做得很快,最终生成Document的成本还是被分页而卡得很高。
降低你用非5%常用功能时的成本,唯一途径就是你接受过比较系统的学习。就好像Piggest去上Maya培训那样,就好像我说学Javascript要必须看O'Reilly的《Javascript权威指南》一样,不经过系统学习那些非常用功能你是不会知道的,这时候那些非常用功能你就只能用常用功能去“模拟”,这时候使用非常用功能的成本就会暴增。很多东西称之为“易学难精”正是因为非常用功能自己学难以了解到,甚至系统教材也没有,只有长期钻研的高手才对该领域有所了解,例如ASP.NET的页面生存周期的细节,MS不肯公开细节,于是就出现了个高手自己用Reflector看ASP.NET源代码和自己做实验然后把结果公布到自己的Blog的现象。
2006年3月23日星期四
Client 说她的瘦身计划不能变,所以 Server 你必须再胖些
上次说到“HTML + AJAX + WebService = C/S or B/S?”,我说通过WebService方式调用会不会又让B/S变得类似C/S了,不过结果是Client说她不能再胖,胖了Browser就不让进,呵呵……
首先第一件事就是关于DOM,有人说这才是AJAX的本质而XMLHttpRequest只是一个小工具,不过这个本质(不是McDull的那个本质,咔咔)的执行效率就实在不怎么样,不至于很差,但是你绝对不能把以前用ThickClient的Native Code所做的东西完全交给它,因为太多了你就会发现它忙不过来。
举个CSDN上见到过几次的一个例子,就是做一个类似Google Suggest那样的有筛选功能的ComboBox,遇到问题的人都说那东西只要待筛选项超过5K就没效率了,然后我说不要用DOM来构建下拉的内容而改用拼接HTML同时只有当用户超过500ms没按键时才筛选,结果有所改善,不过可能也无法处理超过10K的待筛选项。
我自己也做过一个动态生成table的东西,用DOM构建table的话一个50*30格的就要300ms~500ms,这个效率实在太低啦。
第二个问题就是复杂的客户端调用规则。例如我有一个用户注册表单要调用服务器端的3个WebMethod:
bool IsUsernameDuplicated(string Username) //用户名是否已被使用
bool IsEmailDuplicated(string Email) //Email是否已被使用
void SignUp(...) //把所有注册信息提交到数据库
现在要求异步调用IsUsernameDuplicated和IsEmailDuplicated,我也不知道哪个先返回,但必须两个都返回false才调用SignUp,任何一个返回true或者Timeout了都不调用SignUp。这样事情就会变得很麻烦,前两个WebMethod返回时必须作标记,然后用一个定式执行的程序不停的检查这两个标记直到都有返回(或者Timeout)为止。
当客户端有一系列复杂的调用规则时,问题就更加复杂了,所以最后你会发现还是不要在客户端搞复杂调用好,这些规则应该都交给服务器端处理,然后封装为一个WebMethod。例如应该只设置一个SignUp,调用时通过返回一个int来表示用户名/Email是否已被使用,又或者用Atlas的Exception机制来返回这个。
简而言之,Client跑Browser的Scripting跑道上时别给太多或者太复杂的东西它干,它根本干不来,事情还是尽量让Server包办好了。不过也有例外的时候,例如那边Flash就在大喊我很Rich(因为它自己叫自己RIA),我可以负责很重的UI任务,呵呵……
首先第一件事就是关于DOM,有人说这才是AJAX的本质而XMLHttpRequest只是一个小工具,不过这个本质(不是McDull的那个本质,咔咔)的执行效率就实在不怎么样,不至于很差,但是你绝对不能把以前用ThickClient的Native Code所做的东西完全交给它,因为太多了你就会发现它忙不过来。
举个CSDN上见到过几次的一个例子,就是做一个类似Google Suggest那样的有筛选功能的ComboBox,遇到问题的人都说那东西只要待筛选项超过5K就没效率了,然后我说不要用DOM来构建下拉的内容而改用拼接HTML同时只有当用户超过500ms没按键时才筛选,结果有所改善,不过可能也无法处理超过10K的待筛选项。
我自己也做过一个动态生成table的东西,用DOM构建table的话一个50*30格的就要300ms~500ms,这个效率实在太低啦。
第二个问题就是复杂的客户端调用规则。例如我有一个用户注册表单要调用服务器端的3个WebMethod:
bool IsUsernameDuplicated(string Username) //用户名是否已被使用
bool IsEmailDuplicated(string Email) //Email是否已被使用
void SignUp(...) //把所有注册信息提交到数据库
现在要求异步调用IsUsernameDuplicated和IsEmailDuplicated,我也不知道哪个先返回,但必须两个都返回false才调用SignUp,任何一个返回true或者Timeout了都不调用SignUp。这样事情就会变得很麻烦,前两个WebMethod返回时必须作标记,然后用一个定式执行的程序不停的检查这两个标记直到都有返回(或者Timeout)为止。
当客户端有一系列复杂的调用规则时,问题就更加复杂了,所以最后你会发现还是不要在客户端搞复杂调用好,这些规则应该都交给服务器端处理,然后封装为一个WebMethod。例如应该只设置一个SignUp,调用时通过返回一个int来表示用户名/Email是否已被使用,又或者用Atlas的Exception机制来返回这个。
简而言之,Client跑Browser的Scripting跑道上时别给太多或者太复杂的东西它干,它根本干不来,事情还是尽量让Server包办好了。不过也有例外的时候,例如那边Flash就在大喊我很Rich(因为它自己叫自己RIA),我可以负责很重的UI任务,呵呵……
2006年3月21日星期二
Benny说不要太早走出社会喔~
上次回去修华附论坛那台服务器时,Benny说第二天就要面试20个本科生,从中要两个,试用期月薪¥1K+,转正后再加¥500。然后我问他招那两个人的工作范围是什么,他说一个负责发布新闻,长期坐在网络中心,另外一个跟吴老师东奔西跑(估计是维修类的)。
Benny的意思就是,能够留在学校里,最好就一直留在学校里不要出来。不过留在学校里虽然什么都好,但是现在好的学校都越来越“敛财”了,所谓教育产业化搞到学校也变成了服务运营商,能够骗到一点钱就骗一点,积累资金“扩大生产”,真正专心搞教学或者研究的人又剩下多少呢?
Benny的意思就是,能够留在学校里,最好就一直留在学校里不要出来。不过留在学校里虽然什么都好,但是现在好的学校都越来越“敛财”了,所谓教育产业化搞到学校也变成了服务运营商,能够骗到一点钱就骗一点,积累资金“扩大生产”,真正专心搞教学或者研究的人又剩下多少呢?
2006年3月19日星期日
Site moved~
由于sitesled已经有一段时间无法进行FTP上传了,所以改到5000megs,PURL保持不变:
http://purl.oclc.org/NET/cathsfz
由于原来用开GB2312发布,现在服务器的charset为UTF-8,改过来可真不容易。用GB2312发布,则客户端打开时自动根据HTTP的charset而不是HTML的charset设置为UTF-8,用户需要手动改回GB2312才能正常浏览;用UTF-8发布,根本就是乱麻,因为Blogger保存文章和模板时就有charset属性,GB2312的文章按UTF-8发布无论如何都是乱码。
最后我意外找到了解决方案,就是先用GB2312完整发布一次,然后改用UTF-8发布,并把模版和首页上的几篇文章改为UTF-8,最后仅发布索引一次,那就OK了。这个解决方案首先解决了首页显示问题(这是我原本的目标),后来发现打开内页竟然GB2312又能自动识别(难道仅访问/时HTTP协议会返回charset),所以暂时我的Blog“看起来”完全没问题。
http://purl.oclc.org/NET/cathsfz
由于原来用开GB2312发布,现在服务器的charset为UTF-8,改过来可真不容易。用GB2312发布,则客户端打开时自动根据HTTP的charset而不是HTML的charset设置为UTF-8,用户需要手动改回GB2312才能正常浏览;用UTF-8发布,根本就是乱麻,因为Blogger保存文章和模板时就有charset属性,GB2312的文章按UTF-8发布无论如何都是乱码。
最后我意外找到了解决方案,就是先用GB2312完整发布一次,然后改用UTF-8发布,并把模版和首页上的几篇文章改为UTF-8,最后仅发布索引一次,那就OK了。这个解决方案首先解决了首页显示问题(这是我原本的目标),后来发现打开内页竟然GB2312又能自动识别(难道仅访问/时HTTP协议会返回charset),所以暂时我的Blog“看起来”完全没问题。
2006年3月5日星期日
My Life Rate~
This Is My Life, Rated | |
Life: | 5.6 |
Mind: | 6.2 |
Body: | 5.5 |
Spirit: | 6.3 |
Friends/Family: | 5.9 |
Love: | 1.5 |
Finance: | 5.5 |
Take the Rate My Life Quiz |
订阅:
博文 (Atom)