Kaneboy's SharePoint Blog

SharePoint & Office Zealot
随笔 - 392, 评论 - 8102, 引用 - 201

导航

关于


About me :
SharePoint Architect. Build SharePoint solutions from year of 2003. Joined Microsoft in 2004. Working for HP now.

Certification :
MCPD - Web Dev
MCTS - SharePoint 2007 Dev
MCTS - SharePoint 2007 Config
MCTS - WSS 3.0 Dev
MCTS - WSS 3.0 Config
MCTS - SPS2003 Infra
MCTS - SPS2003 App
MCT
(ex)MVP 

Contact me :
kaneboy@gmail.com | follow @kaneboy on twitter

Authored books:


标签

每月存档

最新留言

广告

说说ASP.NET 2.0的书

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 on 2006-08-17 02:39:00 by kaneboy  评论(22) 阅读(16060)

ASP.NET 2.0 Provider Toolkit

记得在之前的某个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 on 2005-08-03 14:59:00 by kaneboy  评论(3) 阅读(7358)

ASP.NET中的OutOfMemoryException

在博客园看到了一位园友写的文章《如何处理OutOfMemoryException异常?》,于是想和大家交流一下ASP.NET中出现OutOfMemoryException的问题。

实际上,在ASP.NET Web服务器上,ASP.NET所能够用到的内存,通常不会等同于所有的内存数量。在machine.config配置文件中,<processModel>中有一个属性“memoryLimit”,这个属性的值是一个百分值,默认为“60”,即指定了ASP.NET进程(在任务管理器中大家就可以看到ASP.NET的进程,IIS5中为aspnet_wpIIS6中为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 Tuning
Microsoft KB: 4 GB RAM 调试功能和物理地址扩展开关介绍

posted on 2005-05-07 19:39:00 by kaneboy  评论(11) 阅读(19437)

ASP.NET 2.0 Beta2 关于页面编译模型变化的两篇文章

以前在我的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 on 2005-02-06 03:54:00 by kaneboy  评论(6) 阅读(4050)

ASP.NET 2.0 Beta2中页面编译模型的变化

孙展波的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 on 2004-11-18 15:22:00 by kaneboy  评论(14) 阅读(12254)

如何在Web页面上直接打开、编辑、创建Office文档

有朋友询问如何在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 on 2004-11-03 17:49:00 by kaneboy  评论(141) 阅读(77907)

System.Web.UI.Page类的构造函数的执行时机

这篇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 on 2004-09-12 00:57:00 by kaneboy  评论(3) 阅读(5169)

将ViewState保存到其他地方

前两天做了一个小东西,包装了一下ViewState的存储,实现将页面的ViewState保存到我们指定的地点。关于ViewState的原理已经如何进行这样的修改,可以参看以前我的一篇Blog上面的内容。

Kaneboy.Web.ViewState内置了三种存储ViewState的方式,保存在Session中、压缩后保存在页面上的Hidden Field中,以及按照ASP.NET 1.1所实现的那样,直接保存在Hidden Field中。通过查看其源码,你可以更深入的了解ViewState的知识。

根据我的使用试验,在有DataGrid或类似控件的页面上,使用内置的ViewState压缩方式就可以大大的缩小页面的体积。

详细的使用说明在这里,通过阅读说明,你就可以大致了解它。源码在这里

posted on 2004-08-16 00:27:00 by kaneboy  评论(8) 阅读(4890)

唾手可得的宝藏:Mono源码

“源码是最好的文档”,有了源码,任何软件系统在开发人员面前就毫无“神秘”可言了...

今天需要做一个上传文件的Web页面,在调用HttpPostedFile.SaveAs(String filename)方法将文件写到服务器磁盘上时,想到如果此文件已经存在于磁盘上,这个方法会如何处理呢?直接覆盖?抛出异常?

翻一下.NET Framework文档,可惜里面没有对这个情况进行说明。于是进入Mono源码目录,定位到HttpPostedFile.cs文件,用记事本打开,找到SaveAs(String filename)方法,第一句就是:

FileStream File = new FileStream(filename, FileMode.Create);

OK,确切答案就是如果已经存在同名文件会直接覆写。

我猜一定有人会想,“万一Mono的实现和.Net Framework不同怎么办?”其实我过后就这么想了,于是用Reflector打开了System.Web.dll,定位这个方法,呵呵,.Net Framework的实现也是“FileMode.Create”。不过.Net Framework使用了一个try...catch来保证关闭这个FileStream,而Mono的实现里面则没有,嗯,这是不是意味着Mono的稳定性仍有不少改进之处呢?

posted on 2004-08-10 18:19:00 by kaneboy  评论(14) 阅读(6910)

自己实现的一个Script Callback

昨天网上一位朋友推荐我看了一篇文章《Remote Scripting in .NET》,这篇文章的作者利用了Microsoft Remote Scripting技术,在服务器端进行了一些封装,方便了在ASP.NET中的页面上调用直接调用服务器端方法。

说起来我以前对Microsoft Remote Scripting还是挺陌生的,MRS的原理是利用了内置的一个Java Applet,通过一些高层的封装,使页面上使用Script能够直接调用服务器上公开的方法。感兴趣的朋友可以看看MSDN上的文档,用起来还算是方便,特别是配合前面那篇文章作者做的那个封装的.NET组件

不过我个人对Applet并不是很感冒,特别是在我家里的那台没有安装JRE的WinXP SP2RC2的机器上更是根本没法用...

其实我最喜欢的还是ASP.NET 2.0中的Script Callback那样的实现方式,简单、明了,于是想到,既然它也是底下使用XMLHTTP来实现的,那不如我自己在ASP.NET 1.1下面也照样用XMLHTTP实现一个好了。花费了一阵功夫,大功告成。大部分都是仿造的ASP.NET 2.0中的实现方式,但是部分地方还是不能做到完全一样,因为对于实现ICallbackEventHandler接口的控件的处理,我没法直接写到Page类或更里面的地方,所以需要在页面里面创建一个ScriptCallbackManager的控件。

服务器端的进行步骤:
1、让页面上的某个控件实现ICallbackEventHandler接口,我个人喜欢就让Page类直接实现;
2、在实现了ICallbackEventHandler接口的控件上实
现RaiseCallbackEvent方法,来处理客户端的请求;
3、在页面中加入一个ScriptCallbackManager控件,在构造函数中指明实现了ICallbackEventHandler接口的控件,和调用完成后执行客户端的Script函数名。

public class WebForm1 : System.Web.UI.Page, ICallbackEventHandler
{
    private void Page_Load(object sender, System.EventArgs e)
    {
        this.Controls.Add(new ScriptCallbackManager(this, "handleResultFromServer"));
    }

    public String RaiseCallbackEvent(String eventArgument)
    {
        return "You sent " + eventArgument + " !";
    }


页面上的进行步骤:
1、在需要调用服务器方法的地方直接调用内置的scriptCallback()函数,第一个参数指定了要传递到服务器端的变量,第二个参数指定了此次请求的上下文;
2、编写一个在完成调用之后自动执行的函数,这个函数的名称需要和服务器端ScriptCallbackManager控件的构造函数中指定的函数名称相同。

function callBack()
{
    var param = document.all.txtRequest.value;
    var context = "";
   
    scriptCallback(param, context);
}

function handleResultFromServer(result, context)
{
    alert(result);
}


在callBack()方法中调用了系统内置的一个Script函数scriptCallBack(),这个函数会自动调用服务器方法,并将第一个参数的值传给服务器端的RaiseCallbackEvent()方法的参数。handleResultFromServer是在调用完成后自动执行的函数。

感兴趣的朋友可以在这里下载到这个Script Callback实现的项目源码。

posted on 2004-08-02 23:39:00 by kaneboy  评论(17) 阅读(10516)

ASP.NET 2.0,无刷新页面新境界!

“无刷新页面”,只是一种不确切的效果描述(其实还有其他各种方法来实现这个效果),更确切的说法是:在页面上用JavaScript调用服务器端的一个方法,然后处理返回的数据。实现它最标准的方法当然是XMLHTTP。但是,程序员都是懒惰的家伙,每个人都希望能有更方便的方法,或者,更佳的包装。比如,LostinetRane就是对XMLHTTP的一个很好的包装。

终于,在ASP.NET 2.0里面,我们可以轻松的来做到这点了。服务器端任何实现了System.Web.UI.ICallbackEventHandler接口的控件,都可以通过RaiseCallbackEvent()方法来处理从页面上的JS脚本传递过来的请求和数据,处理后,再将结果传回给页面。这项能力的底层仍然是XMLHTTP。

下面是一个简单的演示:

在页面上,我们放上两个文本框和一个按钮:
<INPUT id="txtMessage">
<INPUT onclick="callToServer();" type="button" value="Call to Server">
Result : <INPUT id="txtResult" >


当点击按钮的时候,将调用JS脚本方法callToServer(),JS脚本如下:
function callToServer()
{
    var param = document.getElementById("txtUsername").value;
    var context = ""; 
<% = ClientScript %>    <% = ClientScript %>
}

function handleResultFromServer(result, context)
{
    document.getElementById("txtResult").value = result;
}


handleResultFromServer()方法则负责将从服务器传回的数据写到txtResult这个文本框里面。

再看看服务器端的代码:

public partial class Default_aspx : System.Web.UI.ICallbackEventHandler
{
    private String ClientScript
    {
        get
        {
            return this.GetCallbackEventReference(this, "param", "handleResultFromServer", "context");
        }
    }

    public string RaiseCallbackEvent(string eventArgument)
    {
        return "客户端在[" + DateTime.Now.ToString() + "]传送来 [" + eventArgument + "].";
    }
}

我们让页面直接实现ICallbackEventHandler接口,然后接口定义的RaiseCallbackEvent()方法中将服务器的时间和传来的数据一起返回回去。

ClientScript属性的作用是,它调用了页面的GetCallbackEventReference()方法,获得了让客户端有能力调用服务器端方法的JS脚本,并输出到页面的callToServer()方法中,这样,点击页面按钮时,就开始执行页面上包含了调用服务器方法的的callToServer()方法。

注意GetCallbackEventReference()方法的参数,在参数中,我们定义了客户端的哪个变量包含了要传递给服务器,服务器方法执行后,调用客户端的哪个方法等信息。GetCallbackEventReference()的详细参看请看这里

最后,我们这个页面的执行效果就是:

posted on 2004-07-07 23:42:00 by kaneboy  评论(63) 阅读(87922)

项目进行中...

这两天忙着做手头的一个项目,ASP.NET的,没太多技术难度。但做项目通常能让我在思考实现的过程中,冒出各种各样的想法...

为了在ASP.NET 1.1里面实现类似2.0里面的Membership(用于用户的身份验证Authentication)和Role Manager(用于用户的权限验证Authorization)模块,我认真将2.0的文档里面相关的部分看了一遍,然后在1.1里面几乎依葫芦画瓢的实现了出来。在实现的过程中,我渐渐感到Membership和RoleManager的实现方式很是眼熟,然后,我越来越觉得它们的概念非常像一样东东:SOA!

随便写个例子吧,想象一下我们通常如何设计User类和Role类:

class User {
    RoleCollection Roles;
}

class Role {
    UserCollection Users;
}


各个类之间都有Association。于是,我们用User.Roles来获得一个用户的角色信息,用Role.Users来获得一个角色下有哪些用户。

或者:

class User {}

class Role {}

ICollection RoleService.GetRolesFromUser( String username );
ICollection RoleServie.GetUsersFromRole( String roleName );
void RoleService.AddUserToRole( String username, String roleName );


各个类之间没有Association,我们通过一个(或几个)相关的ServiceFacade来获取相关的信息和进行相关的操作。

Membership和Role Manager就是用的类似于第二种的方式来实现的。好处?Membership和RoleManager之间完全各自独立,两者之间没有直接的联系,没有“依存”关系。比如,我们可以让Membership用AD集成的方式来进行用户认证,但是用户的角色、权限信息则放在SqlServer的表里面。

各个Domain Model的独立,还带来了更多的好处。1、在用ORM(或者手工)载入Entity的数据的时候,因为各个Entity之间被设计成没有Association,所以,我们可以暂时抛开令人烦恼的Lazy-Loading的问题。2、Entity完全可以通过WebService传递到远程,如果有各种Assocation,想象被传递到远程的User实体被直接调用User.Roles将是件多么令人烦恼的事。

但是,别忘了Membership和Role Manager从逻辑上来说,是完全可以分开的,而通常很多东西,天生就是结合非常紧密的。比如:Order和OrderDetail、OrderDetail和Product。

总之,程序员的一大工作就是:Do right thing in right place!

posted on 2004-06-28 20:12:00 by kaneboy  评论(9) 阅读(4195)

Implement Membership & Roles & Personalization in ASP.NET 1.1

现在手头正刚开始一个ASP.NET 1.1的项目,因为客户需求中有一项是某些用户的认证信息需要同客户现行的AD认证集成起来,首先想到的就是ASP.NET 2.0中一个非常方便的特性,Membership,因为使用了Provider Model Patterns,在系统中插入定制的用户认证机制是非常方便的。那干嘛不自己在ASP.NET 1.1里面实现出来呢?然后又想到既然将Membership实现出来,那不如将Roles、Personalization一同实现,充分(“抢先”)利用2.0带给我们的好处。笑脸

刚开始还有计划在Roles和Personalization这两块使用现成的Authorization and Profile Application Block,但是在仔细研究了一下它自带的QuickStart后,又感觉这个东东太过“笨重”而不灵活。非常奇怪,我个人觉得ASP.NET 2.0开发组的众多设计要比做Application Block的PAG组的要好得多...

最后推荐一个非常Cool的MS发布的站点,weRock247.NET,学习SmartClient开发不可错过的站点!

posted on 2004-06-16 23:57:00 by kaneboy  评论(7) 阅读(3524)

ViewState

最近好像很流行在ViewState上面玩花样,有人做了一个ViewState Decoder的东东,可以用软件直接解析出ViewState中的内容

其实ViewState这个东东要解析出来的确不难,Paul Wilson(也就是做那个模仿ObjectSpaces的ORMapper的)写过一篇言简意赅的文章,里面就讲解了ViewState的结构,并提供了解析ViewState的例子。

这么看来ViewState其实还是很“脆弱”的,因为能够被很轻易的解析出来,所以很自然的会面临被恶意修改的问题。而且如果页面里面有一个DataGrid之类的控件,ViewState也会膨胀到令人不满意的地步。当然我们可以自己补足它的种种缺点。

MSDN上很早也有一篇讲解ViewState的文章,并且在文章里面说明了如何加强ViewState的安全性,包括将散列计算值附加在ViewState里面以保证不被篡改,还有给ViewState进行一些加密。

ViewState默认是保存在客户端页面的一个Hidden Field里面的,自然会增加下载页面和提交页面(别忘了这个Hidden Field里面的内容被下载回来以后,还要被原样的Postback回去)的时间,但干吗不把ViewState直接保存在服务器端呢?比如保存在服务器上的文件里面,或者SqlServer数据库里面,这样就完全的避免了使返回页面体积增大的问题。Dino Esposito在他著名的Cutting Edge专栏里面就写过这么一篇文章,讲解了如何透明的将ViewState保存在服务器端

如果不想这么麻烦,还有其他方法,比如,将ViewState在服务器端压缩后再写到Hidden Field里面,传回到服务器后再解压缩,这样一样可以很有效的打压ViewState的体积。

当然,最最简单有效的方法,就是适当的使用控件的EnableViewState属性。

posted on 2004-06-15 10:09:00 by kaneboy  评论(6) 阅读(6758)

Is this MVC ? Maybe... But I don't think so...

这两天在CSDN的文档区翻到了一篇翻译的文章,《在ASP.NET中实现Model-View-Controller模式》,这篇文章是摘自鼎鼎大名的ESP,我想.NET程序员很少没有看过这本书的,说它是.NET程序员的Must-Read毫不为过(另一篇Must-Read是AppArc,即Application Architecture for .NET: Designing Applications and Services)。

回到这篇文章上来,原文在这里,Implementing Model-View-Controller in ASP.NET。我当初在看这部分的时候就相当疑惑,这里所描述的实现能否准确的称为MVC?

先看看大家熟悉得不能再熟悉的MVC的图示:


再看看ESP中对MVC模式的描述(如果感兴趣,可以看看最“正宗”的SmallTalk中MVC模式的描述,点这里):
It is important to note that both the view and the controller depend on the model. However, the model depends on neither the view nor the controller. This is one the key benefits of the separation. This separation allows the model to be built and tested independent of the visual presentation. The separation between view and controller is secondary in many rich-client applications, and, in fact, many user interface frameworks implement the roles as one object. In Web applications, on the other hand, the separation between view (the browser) and controller (the server-side components handling the HTTP request) is very well defined.

MVC模式有两点非常重要:1、Model完全独立于Controller和View;2、Controller独立于View的实现。上面对MVC的描述的最后一句话的意思是“ASP.NET中通过将View定义到页面文件,将Controller定义到Code-Behind组件中实现了Controller和View的分离”。

我不知道在这里ESP是怎么定义“separation”的含义的,如果Controller是通过“Front Controller”来实现,我还是认可达到了一定的分离度,但是如果Controller是通过“Page Controller”(也就是那个.aspx.cs的Code-Behind的模式)来实现的,我则对于是否真的这就算是“separation”表示怀疑。在这篇文章中,实现MVC就是用的Page Controller的方式。所以,我对于这篇文章中所示范的实现是否真正算是MVC方式表示严重怀疑。

作为一个真正的MVC的系统,Model和Controller因为从View中独立了出来,所以具有非常高的重用性,比如,如果将作为View的页面进行修改,或者干脆把现有的页面文件删除然后再做过新的页面,或者将程序的界面从ASP.NET页面改成一个WinForms程序,甚至改为一个Mobile设备上的程序,Model和Controller仍然是可重用的,就是说,界面背后的数据、流程、状态控制、业务规则都是一样的,所以View的变换决不会影响Model和Controller。

对于一个MVC实现的系统来说,实现上面这一点应该是基本的需求,而且也是MVC的初衷(把View从Model和Controller中解藕出来,View的变化不影响其他部分)。而上文所提到的那样的实现方式,我看不出能够达到MVC所需要达到的要求。

就我所知,现在.NET下真正实现了MVC的框架只有两个:SourceForge上的Maverick和微软的UIPAB,利用它们提供的Framework,可以真正的同时很方便的实现MVC的Application。如果有时间,我希望不久能以UIPAB为基础,写一篇如果实现MVC模式的WebForms程序的文章。

posted on 2004-05-28 00:44:00 by kaneboy  评论(4) 阅读(3810)

ASP.NET Tips : 用JS产生Postback

用Page.GetPostBackEventReference()方法可以返回一个产生Postback的JS Method,不再详叙。这里演示如何Postback以后知道是哪个元素触发的Postback。

在页面上:

...onClick="javascript:<% this.Page.GetPostBackEventReference(this, "@@@@@SomeTag" %>"...

在页面的Page_Load()里面:

if (this.IsPostBack)
{
??? String eventArg = Request[ "__EVENTARGUMENT" ];
??? if (eventArg.IndexOf("@@@@@" ) > -1)......
}


Source : http://weblogs.asp.net/mnolton/archive/2003/06/04/8260.aspx

posted on 2004-05-26 11:46:00 by kaneboy  评论(4) 阅读(3682)

Using 1.1, Waiting 2.0 & EasyThread

一、Using 1.1, Waiting 2.0

和其他所有的.NET程序员一样,我一边期待着.Net 2.0早日发布,并关注着它的各种新特性,一边仍然基于.Net 1.1在实现着各种各样的项目或产品。

很自然的,我希望我能在ASP.NET 1.1里面就能享受到这些能帮我更快更方便的编程的新东东。其实很多人已经在把2.0下面的新特性在1.1下面实现出来,比如Provider PatternsMaster PageThemeImage ManagementSqlCache Dependency(RobHoward也用HttpHandler实现过一个,点这里下载)、PersonalizationObjectSpaces...

其实我最期待的是WebPart在1.1下面的实现,但个人估计难度太大,可能不太现实(虽然Dino Esposito提过有这个计划)...

二、EasyThread

微软内部一个哥们儿做了一个EasyThread的VS.NET的Add-in,只要在一个方法前面加上一个Attribute,这个Add-in就会在编译时自动生成代码,让这个方法在另外一个线程里面运行。轻轻松松将原本单线程的程序变为多线程。

这个东东还有以前说过的那个XC#启发了我一个思路,它们都是利用VS.NET的Add-in能力,通过在源码中插入特定的Attribute,然后在编译时自动查找这些Attribute然后插入特定的代码以实现一些原本C#语法不能实现的功能。那么干嘛不用类似的方式,来实现AOP呢?将AOP的实现从运行时移到编译时...这个Idea还有待证实...

三、Snippet Compiler

介绍一个小工具,Snippet Compiler,它的好处是让我们有时候只想验证某个想法而只需要写上几行代码的时候无需打开VS.NET新建一个项目,但又比EditPlus之类的要强大一点点。

posted on 2004-05-20 12:23:00 by kaneboy  评论(10) 阅读(3061)

Data...

因为这几天在评估公司一个项目应用ASP.NET 2.0一些新特性的情况,所以对.Net Fx 2.0的一些特性又着重了解了一下。

这里是Dino写的一篇回顾Microsoft的数据访问技术的文章,其中展望了ADO.NET 2.0将带来的一些新的特性。这里是一篇内容更加丰富的描述ADO.NET 2.0新特性的文章。这里是PDC03会议上面的一个ppt演示。

从它们带来的信息看,ADO.NET 2.0的不少新特性非常令人期望。Provider Factory、XmlAdapter、Paging Fill Data、Server Cursor、Asynchronous Connection and Command、Bulk Copy等等,当然还有ObjectSpace。

当然,这些信息都已经是比较“古老”的信息了,根据最新的信息显示,原先计划的不少新特性会最终去掉。前几天Dino的Blog上已经对此作出了说明,包括我比较喜欢的Paging...

我现在最大的希望是6月份VS2005 Beta能够如期推出,并希望这个Beta版本和Final Release的差别不要太大(但从Beta到明年Release这么长的一段时间间距使得这个希望有点悬)。

ps1:这两天正在考虑实现一个SharePointDataProvider,让程序员可以通过标准的ADO.NET接口访问SharePoint List中的数据。带来的一个额外好处就是不少报表软件能够更方便的显示SharePoint中的内容了。

ps2:今天收到了Longhorn DVD光盘和MVP eLearning Kit,eLearning Kit上面有几本不错的开发方面的书(Coding Techniques for Microsoft Visual Basic .NET、Designing Enterprise Applications with Microsoft Visual Basic .NET、OOP: Building Reusable Components with Microsoft Visual Basic .NET、Practical Standards for Microsoft Visual Basic .NET、Programming Microsoft Windows with Microsoft Visual Basic .NET(没错,这本就是Charles Petzold写的那本书的VB版本)),可惜都是VB.NET的...

posted on 2004-05-17 17:02:00 by kaneboy  评论(3) 阅读(3242)

WebParts, MSIB, Framework Design...

1、不少人向我抱怨能够找到的实用的WebPart太少了,Microsoft在它的网站上其实提供了不少WebPart、Template、Tools等好东东的下载。当然,自己DIY,丰衣足食。

2、Microsoft Solution for Internet Business 2.5版发布了,MSIB里面描述了如何高质量的用Windows Server System来构建Internet站点。网管必看!

3、想知道如何设计和使用一套Framework吗?看看这里。这篇文档对Framework的一些通用原则、IoC、Spring做了简洁明了的描述,绝对推荐!(感谢文章作者,和jjx在.Net评测网上的推荐)

4、Improving .NET Application Performance and Scalability正式在MSDN上登陆了!它包含了如何在设计、编码、数据库设计、测试等各个阶段对系统的性能进行调整和优化的各种原则和指南。

posted on 2004-04-29 11:46:00 by kaneboy  评论(4) 阅读(2964)

Powered by: Joycode.MVC引擎 0.5.2.0