RSS 2.0 Feed
ASP.NET
摘要:ASP.NET 2.0其实已经出来挺长时间了,但国内关于ASP.NET 2.0的书似乎很少。前几天特意关注了一下ASP.NET 2.0的书,有些感想,和大家分享。如果你是一个对ASP.NET 2.0很关注的人,那么一定不会没有听说过Dino Esposito这个名字。他写了两本关于ASP.NET 2.0的书,《Programming Microsoft ASP.NET 2.0: Core Reference》和《Programming Microsoft ASP.NET 2.0 Applications: Advanced Topics》,这两本书可以算是从入门到提高型,非常值得推荐。然后,我在China-Pub上找到了第一本书的中文版,而且居然已经正式出版了,清华大学出版社,书名是《ASP.NET 2.0技术内幕》,在网站上提供了两章的试读,似乎对此书中文版质量非常的有信心。于是我便将第一章的试读下载下来,用Word打开,随手翻到一页,赫然就发现有一个章节的开头是:“在ASP.NET提供程序模型的背后有一个著名的设计模式——战略(strategy)模式。”嗯,“提供程序模型”,我只能说,如果读者早已了解了ASP.NET 2.0中的Provider Model的话,那么看这句话肯定能看懂,另外,国内有把“Strategy Pattern”翻译成“战略模式”的吗?当然啦,译者在这里保留了“strategy”这个原词,实在是英明之极。正好看到博文视点的一位编辑MM在线,于是赶紧问她,“《Programming Microsoft ASP.NET 2.0 Applications: Advanced Topics》这本书国内已经有出版社在做中文版了吗?”,稍过了一会儿,编辑MM回复道,“此书中文版权也被清华大学出版社拿到了”...然后我在China-Pub上果然搜索出了这本被命名为《ASP.NET 2.0高级编程》的书。唉,可怜的Dino...当然啦,我略显夸张了,其实《ASP.NET 2.0技术内幕》还算不上“烂”书,如果读者有足够的阅读和理解功力,还是可以一读的。其实对于ASP.NET 2.0的入门者来说,.NET Framework 2.0自带的QuickStart就是极好的入门教程,而且有中文版。在这里可以在线阅读。博客园的LoveCherry组织翻译的Scott Mitchell的ASP.NET2.0教程也是不错的快速上手型实战教程,值得推荐。今天在第二书店上,偶然发现了孟子E章写的《ASP.NET2.0应用开发技术》,鉴于作者在CSDN论坛上的良好声誉,我也强烈推荐此书。对于已经了解了ASP.NET 2.0基础的读者,我再强烈推荐两本书:《ASP.NET 2.0 MVP Hacks and Tips》和《Expert ASP.NET 2.0 Advanced Application Design》。...[阅读全文]

posted @ | Feedback (22) | Filed Under [ ASP.NET ]

摘要:记得在之前的某个VS2005的测试版本中,内置的Access Provider被去除了,而代之以SQLExpress Provider。当时在asp.net论坛上,开发组的成员就告知在未来会将Access Provider的源码都发布出来。现在,在MSDN站点上,ASP.NET 2.0 Provider Toolkit被正式发布了出来。第一步被发布的就是Access Provider的源代码,里面是用来实现的ASP.NET 2.0中的Membership, Role Manger, Profile, Web Parts Personalization等特性的Access Data Provider的源码。在8月中,还将发布一份讲述如何定制和扩展ASP.NET 2.0中的Provider模式的白皮书。ASP.NET 2.0 Provider Toolkit在不久还将包含ASP.NET 2.0中更多的SQL Server, SQL Express, 和AD/AZMan providers的源码。:)...[阅读全文]

posted @ | Feedback (3) | Filed Under [ ASP.NET ]

摘要:在博客园看到了一位园友写的文章《如何处理OutOfMemoryException异常?》,于是想和大家交流一下ASP.NET中出现OutOfMemoryException的问题。实际上,在ASP.NET Web服务器上,ASP.NET所能够用到的内存,通常不会等同于所有的内存数量。在machine.config配置文件中,配置节<processModel>中有一个属性“memoryLimit”,这个属性的值是一个百分值,默认为“60”,即指定了ASP.NET进程(在任务管理器中大家就可以看到ASP.NET的进程,IIS5中为aspnet_wp,IIS6中为w3wp)能够使用所有物理内存的60%。当ASP.NET使用的内存量超过这个限额时,IIS会开始自动回收(recycle)进程,即创建一个新的进程去负责应付Http请求,而将旧进程所占用的内存回收。当我们有一台很大内存的服务器时,“memoryLimit”这个值是需要进行适当的调整的。比如我们准备了一台4G内存的服务器,那么4G×60%=2.4G。但是,对于Win32操作系统,一个进程所能占用的所有内存空间只有2G。当ASP.NET进程占用的内存开始达到2G时,由于它并没有达到2.4G的“回收阈值”,所以IIS不会启动recycle进程操作,但是由于Win32的限制,实际上已经不能给这个进程分配更多的内存了,于是,OutOfMemoryException就很可能会被抛出了。为了避免这样的情况,我们就必须将“memoryLimit”适当调小,以让IIS更早的进行进程回收。微软推荐的ASP.NET进程占用内存是不超过60%,并最好使计算出的实际值不超过800M。就是说,对于一台4G内存的服务器,最好将“memoryLimit”属性设置成“20”。设置一个适当的回收阈值,让IIS适时的进行进程回收,对于保证整个服务器的稳定运行,避免OutOfMemoryException是非常重要的。在IIS6中,ASP.NET进程的回收阈值不再由配置节中的“memoryLimit”属性决定,而是由IIS管理器中的应用程序池配置中的设置决定。但是,即使正确设置了这些配置,也不能保证完全避免OutOfMemoryException的发生,原因可能是多样而复杂的,比如内存回收操作可能耗时太多等等。开发人员要注意的,就是在代码中时刻牢记不要无谓的使用和浪费内存。:)如果你有一台大内存的服务器,同时对Win32操作系统中对于进程最高使用2G内存的限制很郁闷,可选的解决方法有两个:1、使用/3GB模式启动计算机,方法参加文后的链接2、使用Windows Server 2003 64bits Edition资源链接:Microsoft IIS 5.0 Process Recycling Tool,使IIS5具有类似IIS6的进程监视回收功能Microsoft KB: Information on Application Use of 4GT RAM TuningMicrosoft KB: 4 GB RAM 调试功能和物理地址扩展开关介绍...[阅读全文]

posted @ | Feedback (11) | Filed Under [ ASP.NET ]

摘要:以前在我的Blog上就曾经写过一篇文章,描述了ASP.NET 2.0 Beta2中对于页面编译模型,相对于Beta1的重大改变。今天在网上发现了两篇(here & here)不错的Blog,更详细的描述了这个变化,以及其中运行的机制原理。从我个人的喜好而言,我更喜欢Beta1的Code-Beside方式,因为机制非常清晰明了,很好理解,而且感觉也非常优雅。但是Code-Beside的方式有一个明显的缺陷,开发人员很难使页面从自己定义的一个Page Base Class继承下来,而在ASP.NET 1.1中,这是非常简单的事情(只需要直接更改Code-Behind文件的父类即可)。Beta2的改进使其实现方式更加复杂了,但是好处就是让开发人员又能享受自己定制的Page Base Class的好处了,而且也消除了在ASP.NET 1.1中,Code-Behind文件中不得不加上一大串protected控件声明的缺陷。...[阅读全文]

posted @ | Feedback (6) | Filed Under [ ASP.NET ]

摘要:孙展波的Blog中已经描述了对于特殊目录,Beta2相对Beta1所做出的调整。除此之外,Beta2的编译模型相对Beta1也会做一个相当大的修改。 首先回到ASP.NET 1.1的“远古时代”,看看ASP.NET引擎是如何处理页面文件和Code-Behind文件的。 我们在页面文件的上方通常会看到这样一句声明: <%@ Page CodeBehind="Default.aspx.cs" Inherits="WebApplication1.CDefault" %> 当我们在页面文件上加入一个新的ASP.NET控件时,VS.NET自动会在Code-Behind代码文件中增加一个protecte的对象声明,并在代码中使用和操作这个对象。VS.NET会时刻维护页面文件中的控件与代码文件中的控件对象声明之间的同步。 当我们编译站点时,VS.NET将所有Code-Behind文件编译在一起,生成一个位于/bin目录中的.dll文件。然后,我们将所有的页面文件和/bin部署到服务器上。当用户浏览页面文件时,ASP.NET引擎自动根据页面中的内容,生成一个.cs的类文件,并根据页面文件头部声明中的“Inherits”所指定的内容,让这个类从指定的父类继承下来。这样,页面就和后台代码文件中的内容通过“继承”的方式结合在了一起。 这种页面编译模型最大的问题,就是页面中的控件,必须时刻与Code-Behind中的控件对象声明保持同步,虽然开发人员“意识”不到这一点,但是如果VS.NET出错而未能同步,就会损坏这种通过“继承”来连接的关系。 OK,在ASP.NET 2.0 Beta1中,我们终于可以用更加优雅的方式来实现了页面文件和Code-Behind文件的分离和连接了。由于有了partial class这个新的语言特性,我们终于可以摆脱巧妙、但“笨拙”的继承连接关系。为了体现Beta1中后台代码文件的特点,我们干脆直接把后台代码文件叫Code-Beside文件。 在页面文件的顶端,会如下面所示范的这样做一个声明: <%@ Page Language="C#" CompileWith="Default.aspx.cs" ClassName="Default_aspx" %> 注意,VS.NET在开发时不会给我们提供一个手段,把所有的Code-Beside文件都编译到/bin里面的一个.dll中。 部署时,我们直接把所有的页面文件和Code-Beside文件直接XCopy到服务器上。当用户浏览页面时,ASP.NET引擎自动根据页面上的内容,生成一个partial类,然后与Code-Beside中的partial类整合在一起,最后完成编译。这个编译过程(页面文件和Code-Beside)完全是在运行时动态完成的,如果我们修改了页面文件或者Code-Beside文件,都不需要做任何手工操作,ASP.NET引擎会自动在下次浏览时重新进行编译动作。 嗯,当然,很多人会觉得不爽,“为啥我要把后台代码文件也给部署上去呢?”所以,ASP.NET Beta1也提供了其他的编译部署方案,比如,把整个站点的所有内容,包括页面文件和Code-Beside文件统统编译成一个.dll,然后部署到服务器上。 最后,终于,我们可以来看看ASP.NET Beta2中,页面编译模型又发生了什么变化。 页面文件顶端的声明变成了如下所示: <%@ Page CodeFile="Default.aspx.cs" Inherits="Default_aspx" %> 怎么样?看到“Inherits”,是不是怀疑又走回ASP.NET 1.1的老路了?对,也不对。 当使用VS.NET创建一个页面的时候,VS.NET会自动创建一个Code-Behind(我们重新用回Code-Behind这个词)文件,当我们在页面上增加一个控件的时候,VS.NET如同Beta1一样,并不会在Code-Behind中增加一个什么声明。但是,当我们编译站点的时候,VS.NET自动根据页面文件的内容,生成一个“临时中间”partial类,然后把这个partial类和Code-Behind中的partial类整合编译,最终生成一个位于/bin中的.dll文件。 部署时,我们如同ASP.NET 1.1中一样,把/bin和所有页面文件部署到服务器上。当用户浏览页面时,ASP.NET引擎根据页面内容生成一个类文件,然后根据文件头部声明的“Inherits”的值,让这个类文件从指定的父类继承下来,最后完成编译过程。 总之,Beta2的页面编译模型吸收了ASP.NET 1.1和ASP.NET 2.0 Beta1的优点,我们既可以把站点的所有后台代码编译好,然后和所有页面文件一起部署,也获得了Beta1中,开发时后台代码文件中不需要另外声明页面控件对象的好处。 当然,对于开发人员来说,这一切都是在“盖子”底下运作,我们不需要了解这些,就可以方便的进行开发。 微软会在11月份推出一个新的社区技术预览版(CTP),将会体现所有的这些变化。Beta2预计会在明年年初发布,Beta2的设计基本上延续到RTM。 更加详细的信息,请参考MSDN上的这篇文章。...[阅读全文]

posted @ | Feedback (14) | Filed Under [ ASP.NET ]

摘要:有朋友询问如何在Web页面上做到像SharePoint中的效果一样,能直接激活客户端的Word来打开.doc文件,而不是类似直接点击.doc文档链接时Word在IE中被打开那样。想想这个问题应该很多人都会感兴趣,所以干脆写一篇blog来大致描述一下方法。 在安装Office2003以后,有一个ActiveX控件被安装到了系统中,这个控件位于“Program Files\Microsoft Office\OFFICE11\owssupp.dll”。通过这个控件,客户端页面上的JavaScript就可以激活本地的Office软件,来实现打开、编辑Office文档。(另,Office XP应该就已经包含这个ActiveX控件了。) 首先,用Script创建一个本地的对象: openDocObj = new ActiveXObject("SharePoint.OpenDocuments.2"); // 为了兼容Office XP,可以创建“SharePoint.OpenDocuments.1” 然后,调用openDocObj的相应的方法。比如打开服务器上的一个Office文档: openDocObj.ViewDocument("http://www.abc.com/documents/sample.doc"); openDocObj对象会根据参数中不同的Office文档类型(.doc、.xls、.ppt)来打开不同的程序(Word、Excel、PowerPoint)。ViewDocument()方法还有一个重载签名,可以让我们手工指定激活哪个程序来打开文档: openDocObj.ViewDocument("http://www.abc.com/documents/sample.doc", 要激活的程序的ProgID); 那么要打开Office程序在线编辑文件又如何? openDocObj.EditDocument("http://www.abc.com/documents/sample.doc"); 就可以直接激活Word,在Word里面编辑文档,然后直接点击Word里面的保存功能,就可以将文件保存会服务器上了。注意:为了让Word能将编辑后的文档直接保存会服务器,访问Web站点的当前上下文的Windows Identity必须对服务器的相应目录(即“http://www.abc.com/documents”这个虚拟目录所对应的服务器上的物理路径)有相应的写权限,否则保存动作会失败。编辑完成后,EditDocument()会返回一个bool值,来反映编辑操作是否成功。 我们还可以通过打开服务器上的一个文档模版,来创建一个新的文档: openDocObj.CreateNewDocument("http://www.abc.com/documents/sampleTemplate.dot", "http://www.abc.com/documents/"); 就可以使用“http://www.abc.com/documents/sampleTemplate.dot”这个模版来创建一个新的文档,默认新文档的保存地点是“http://www.abc.com/documents/”。创建新文档时使用的程序取决于模版文件的类型(比如.dot模版会对应Word)。新文档的保存同样需要注意权限问题。CreateNewDocument()方法同样会返回一个bool值来反映操作是否成功。 CreateNewDocument()方法的第一个参数,除了可以使用一个模版的地址外,还可以直接指定为希望用来创建新文档的客户端程序的ProgID。...[阅读全文]

posted @ | Feedback (141) | Filed Under [ SharePoint ASP.NET ]

摘要:这篇Blog来自一位同事和我的一次关于公司一个项目中的一个错误的讨论。错误非常简单,就是当在一个页面的构造函数中使用类似:Session[“aaa”] = “bbb”;的时候,就会抛出异常,说系统中Session没有被enable,所以不能使用(当然实际情况是肯定被enable了)。问题所在和解决方法也很快被找到了,在构造函数中不能使用Session的,将这个移到Page_Init中就OK了。这个错误的根本原因应该是在页面的构造函数被调用时,ASP.NET引擎中负责处理Session的SessionStateModule中相应初始化Session的代码还没有被执行,所以才导致了那时不能访问当前上下文的Session信息。SessionStateModule在其Init方法中,是在HttpApplication的AcquireRequestState事件(更确切说,应该是通过使用AddOnAcquireRequestStateAsync()方法,来进行异步的事件处理)上注册了相应的方法,来完成初始化HttpSessionState对象,并将其赋值给当前的HttpContext的Session属性,而在HttpApplication的AcquireRequestState事件被调用的时候,页面对象已经被创建了,就是说,页面的构造函数的执行是在AcquireRequestState事件被调用之前,所以在页面构造函数中访问Session当然会引发相应的异常。HttpApplication的确切执行顺序是:BeginRequest -> AuthenticateRequest -> AuthorizeRequest -> ResolveRequestCache -> 构建页面(在这里页面构造函数被调用) -> AcquireRequestState(这里才初始化当前上下文的Session) -> PreRequestHandlerExecute -> 进入页面执行生命周期(开始Page_Init) -> PostRequestHandlerExecute -> ReleaseRequestState -> UpdateRequestCache -> EndRequest...[阅读全文]

posted @ | Feedback (3) | Filed Under [ ASP.NET ]

摘要:前两天做了一个小东西,包装了一下ViewState的存储,实现将页面的ViewState保存到我们指定的地点。关于ViewState的原理已经如何进行这样的修改,可以参看以前我的一篇Blog上面的内容。Kaneboy.Web.ViewState内置了三种存储ViewState的方式,保存在Session中、压缩后保存在页面上的Hidden Field中,以及按照ASP.NET 1.1所实现的那样,直接保存在Hidden Field中。通过查看其源码,你可以更深入的了解ViewState的知识。根据我的使用试验,在有DataGrid或类似控件的页面上,使用内置的ViewState压缩方式就可以大大的缩小页面的体积。详细的使用说明在这里,通过阅读说明,你就可以大致了解它。源码在这里。...[阅读全文]

posted @ | Feedback (8) | Filed Under [ ASP.NET ]

摘要:“源码是最好的文档”,有了源码,任何软件系统在开发人员面前就毫无“神秘”可言了...今天需要做一个上传文件的Web页面,在