兰斌专栏
世界上没有答案
posts - 11,comments - 76,trackbacks - 0
     摘要: 关于使用VS2005内置服务器和IIS的问题  阅读全文
posted @ 2007-02-13 17:51 小笨笨 阅读(4968) | 评论 (29)编辑
     摘要: SQLDMO,一个随SQL SERVER一起发布的COM对象,你能用它执行丰富的数据库功能!  阅读全文
posted @ 2006-10-17 10:10 小笨笨 阅读(1765) | 评论 (7)编辑
     摘要: 让.NET在Linux上起舞  阅读全文
posted @ 2006-07-26 12:20 小笨笨 阅读(758) | 评论 (0)编辑
     摘要: TestDriven.NET和NCover,NCover,NCoverExplorer的介绍和应用  阅读全文
posted @ 2006-07-20 14:54 小笨笨 阅读(2723) | 评论 (19)编辑

原文地址:http://msdn.microsoft.com/msdnmag/issues/06/07/AtlasAtLast/

        近来开始看Atlas,体验了一下感觉挺不错的,先翻篇文章奉上,有翻的不好甚至有误的地方请大家指正,共同提高!

这篇文章讨论以下几个方面:
1.ASP.NET "Atlas"的介绍
2.Atlas的体系结构
3.客户端和服务器端的控件
4.Atlas和Web服务

        在2005年9月的时候,ASP.NET小组发布了第一个有关ASP.NET中称之为"Atlas"的新特性的社区技术回顾。这个Microsoft.NET Framework 2.0的扩展使开发者能够使用浏览器和服务器的特性更简单地制作出丰富、有交互性的网站。
Atlas提供的丰富功能涉及到Ajax(异步JavaScript和XML),它的名字是用组成它的已有很久的技术的首字母组成的。现代的浏览器里包含了XMLHttpRequest对象,这个在JavaScript中使用的对象能够发出一个到服务器的请求。这个功能允许页面能够响应用户的输入并做一个特殊的不要求整个页面刷新的操作。这个概念总的来说非常简单,但AJAX类库能够减轻写客户端的用于和服务器交互并处理从Web Service返回的XML的JavaScript。
        Ajax试图解决的总的问题归根到底还是HTTP协议本身。HTTP协议是浏览器使用的和服务器交互获得页面并从服务器获得返回的数据的基础。这个协议是无状态的,这意味着保存的用户的输入在页面刷新的时候提交给了服务器。一直以来典型的用户体验是整个页面都被刷新了来得到服务器传回的状态信息。用户在页面上的输入在服务器回传到浏览器的HTML中得到恢复。
        ASP.NET用一个隐藏的view state域来为你处理这个过程。尽管事实上只有页面的一部分需要获得更新,但整个页面的HTML都会被传送到服务器,而且在这个过程中整个屏幕是一片空白。当这个刷新发生的时候,用户不能和页面交互直到浏览器收到新的视图并把它显示出来。AJAX使用XMLHttpRequest这个对象产生一个发送到服务器调用Web服务的请求,而这个过程并不刷新整个页面,以此来改进用户体验。页面上需要更新的部分将被JavaScript直接更改,而JavaScript作出更改是基于收到的XML。用户甚至感觉不到页面的更新正在进行,他能够继续阅读火和页面交互,而同时后台正在进行异步交互。

什么是Atlas?
         ASP.NET的Atlas的作用不是又一个为以客户端为中心的Web程序的AJAX脚本库。Atlas建立在.NET Framework 2.0,它增加了更好的使用客户端JavaScript和XMLHttpRequest对象的支持。它包含了基于服务器的特性,这个特性丰富了现存的ASP.NET程序,Atlas控件和服务使用的客户端脚本库也起到了同样的作用。如图1的体系结构图展示了Atlas的体系结构延伸了客户端和服务器端,它可以被看作制作更加丰富、更加具有交互性的跨浏览器Web程序的主要开发技术。
                                                    
                                                           图1        

        Atlas并没有局限在使用异步的JavaScript请求来更新部分页面的功能上。你将获得看似不切实际的更丰富的客户体验。举个例子,假设有个Web程序创建了一些电影数据。这个程序也许希望能够允许用户去搜索一个指定的男演员。很明显不可能提供一个复杂的包含所有男演员的DropDownList来让用户从里面进行选择,所以程序很可能会分解这个问题。用户很可能被要求选择男演员的名字的首个字母。到服务器的请求将会提供一个一个更可控制的列表,但是这样的用户体验并不怎么好。这个程序可以向用户显示一个TextBox,让用户输入男演员名字的一部分。接着服务器至少有一些数据来减小搜索的范围。这样要好的多,但仍有改进的空间。使用Atlas,你可以提供一个TextBox做动态响应,当用户输入缩小搜索范围时不必等整个页面刷新完毕。
        Figure 2 展示你如何使用Atlas,当用户输入的时候自动完成操作
                                                                
                                                                         图2     
        
         Atlas CTP可以从atlas.asp.net上下载。当安装完毕,它会增加一个额外的供C#和Visual Basic.net的Web开发人员使用的Web Site模板。当你在Visual Web Developer中新建一个Web Site工程,你将会看到一个如图3的对话框。Atlas Web Site包伙了Microsoft.Web.Atlas.dll和一个升级过的Web.config文件,这个Web.config文件的设置使得Web程序能够使用基于Atlas的ASP.NET功能。在现在的发行版本中,Microsoft.Web.Atlas.dll位于bin目录中作为整个程序的本地编译器。
                                                     
                                                        图3      
       
        基于Atlas的程序可以通过从一台开发机器拷贝文件到一台装有ASP.NET 2.0的服务器而方便的进行配置,还不必担心分离的安装的Atlas。安装是在程序级别的,而不是机器级别的。当后续的CTP版本可以使用的时候,它们可以和机器上旧版本的Atlas一起使用,就算一些功能或特性进一步发展了或改变了。这相对于安装是在机器级别更给迁移到更新的版本提供了灵活性。

Atlas的体系结构
         在图1中展示的Atlas的体系结构图中该注意的第一个东西就是它横跨了客户端和服务器端。ASP.NET 2.0增加了一些额外的客户端功能,但这并不包含Atlas扩展的。在体系结构图的右边,注意Atlas服务器端功能建立在ASP.NET 2.0的顶端并扩展了它的功能。同时Atlas也包括了一组新的服务器端控件,用来从浏览器中存取基于服务器的数据和服务。
        在左边你可以看到一个复杂的客户端脚本库,它能独立地被用来写以客户端为中心地JavaScript(这句翻译的不是很好)。这是客户端的基础,经常被Atlas的新特性使用来开发更丰富、改进用户体验的程序。
        在图4中你可以看到在一个Web程序中的典型的客户端-服务器端交互。第一,浏览器请求一个页面,这个请求包含了用户的交互。当用户作出一些动作向服务器请求数据时,非常不幸的整个页面刷新发生了,为的就是更新页面的某一部分,这种行为就不允许用户继续和这个页面进行交互。用户只能停下来等待。
                                                          
                                                                           图4     

        图5展示了使用Atlas方法进行客户端-服务器端交互,这样就不会导致整个页面进行刷新。相对的,初始的html得到了,一系列发到服务器的请求从XML、JavaScript Object Notation(JSON)或html中的片断中得到数据来更新页面。后台的异步请求可以调用Web Services或得到页面的改变,而不会使用户感觉他们必须停下来等待。这些异步请求为后来的服务器回送控制更新过的view state信息,这样当整个页面的刷新是必须的时候,页面上精确的状态就能提交个服务器。
                                                                   
                                                                           图5  

posted @ 2006-07-14 13:39 小笨笨 阅读(1986) | 评论 (4)编辑
        学习敏捷开发的时候接触到了单元测试。当时感觉这种方法真是太好了,测试功能代码是否如你想象的那样工作,可以减少以后的调试,也能给重构带来很多的方便。
       但现在我发现,在复杂的系统中,要做单元测试并不是那么容易的。这里我要声明一点,目前我为之写测试代码的系统基本已经开发了很久了,现在是想为方便以后的修改或重构而引入单元测试的。
        我这里主要要说的是系统的耦合度一旦比较高,写测试代码让我感觉相当困难。比如我们的系统(WEB)它是页面通过Remoting去连接服务器端的一个OM,然后传一个对象(这个对象包含了页面的信息)给OM,由OM进行处理产生一些字符序列,然后OM再调用另外程序集的方法根据产生的字符序列对数据库做相应的操作。这里,连接数据库的操作是由OM里的程序完成的,而对数据库的操作是由OM调用的那块程序集完成的,而我目前就是要对这块程序集写测试代码,而正是这样一段测试代码难住了我。
        所谓单元测试,我的理解就是测试当下的代码片断中的方法。我们根据代码的需求赋给它需要的参数,然后看代码是否传回我们期望的结果。我认为这个过程中应该不涉及别的部分的代码(特别是底层的代码,高层的代码另当别论了)。但目前我这里的情况是,OM做了很多事是我不知道的,尤其是经OM产生的对象。而且这里的代码也和页面的Session关系密切,这就更增加了难度。
        所以我目前对单元测试感觉到了困惑,不明白这种情况下的单元测试该如何进行。希望有这方面经验的高手能给我建议!
        这是第一次放首页,我是希望有更多的人能给我建议,dudu如果觉得不合适,请至少保留半天,谢谢!
        最后还是希望大家能给我帮助,指点迷津……
posted @ 2006-06-23 11:57 小笨笨 阅读(1251) | 评论 (14)编辑
     摘要: 近来忙毕业设计,又很长时间没写blog了。 学ajax也有段时间了,理论是看了不少,也对MagicAjax框架做了下了解,当然要吃透它还是有很长的路要走。 一直觉得对Ajax底层的代码应该总结一下。其实很底层的代码是比较简洁明了的,但功能却比较简单。一般我们都用Send(null).以前我一直在想我怎么来控制当异步传送Http请求时要调用的后台的指定的(我想用的)代码,现在终于明白了(唉,对自己... 阅读全文
posted @ 2006-05-25 11:42 小笨笨 阅读(686) | 评论 (2)编辑
        MagicAjax中最重要的文件就是MagicAjaxModule.cs。这个文件中的MagicAjaxModule类实现了IHttpModule接口并实现了它的Init方法。它拦截了Http请求,并进行了复杂的处理。这个处理主要是三个步骤:Application_BeginRequest,Application_AcquireRequestState和Application_EndRequest。在Application_BeginRequest中它保存了当前HttpContext对象的HttpRequest和HttpResponse,这个对以后的输出有重要的作用。

_request = context.Request;
_response 
= context.Response;

              
        Application_AcquireRequestState的处理是最主要的。首先它判断这是否是一个aspx请求,如果不是的话就直接返回。这里也对请求是“get”的页面直接输出。接下来它会判断这是不是一个ajax请求。如果是的话,它就会调用下面的语句

HttpContext.Current.Handler.ProcessRequest(HttpContext.Current);
             
 还有一句比较重要:

_response.End();

          当然,MagicAjax有三种不同的页面存储,我这里用的是NoStore,其它两种以后在探:)
          到了这句执行结束,其实返回的是整个页面的代码,但页面要实现无刷新更新就只需要变动部分的代码,那这是怎么变出来的呢?答案就在Application_EndRequest这个处理中。首先我们看到前面保存的_request对象发挥了它的作用:

if (_request == null)
                
return;

        只要这是个ajax请求,我们就获得ViewState中的内容并输出到客户端:

if (_magicAjaxContext.IsPageNoStoreMode && _request.Form["__VIEWSTATE"!= null)
                        
{
                            
string vsValue = _filter.GetViewStateFieldValue();
                            
if (vsValue != null && _request.Form["__VIEWSTATE"!= vsValue)
                            
{
                                AjaxCallHelper.WriteSetFieldScript(
"__VIEWSTATE", vsValue);
                            }

                        }

        最后,下面的语句:

AjaxCallHelper.End();

正是整个函数的调用,将整个页面的代码转换成变动部分的JS代码。AjaxCallHelper这个类本身就负责输出的。我们可以看它的这个End函数的内容:

public static void End()//在执行这个方法前输出的还是整个页面的代码,但在执行这个方法后就变成了内容变动那部分的javascript代码,这里最后输出的是stringBuilder的部分内容
        {
            
if (_writingLevel > 0)
                
throw new MagicAjaxException("Script writing level should be 0 at the end of AjaxCall. IncreaseWritingLevel calls do not match DecreaseWritingLevel calls.");

            WriteEndSignature();

            HttpResponse hr 
= HttpContext.Current.Response;

            hr.Clear();
            MergeNextWritingLevelRecursive(
0);
            hr.Write((_sbWritingLevels[
0as StringBuilder).ToString());

            MagicAjaxContext.Current.CompletedAjaxCall 
= true;
            hr.End();
        }

我们可以看到,HttpResponse对象在将输出到客户端时被替换掉了,最后输出的是sbWritingLevels中的一个StringBuilder的文本。这里输出还牵涉到一个脚本等级(估摸应该是这个意思),这个偶还不是很清楚,看来要查点资料了,不知道是不是脚本输出的优先级问题?
    这里就是MagicAjax的主要过程,可能其中有不少问题和错误,还请大家不吝指教拉!
posted @ 2006-04-21 17:11 小笨笨 阅读(418) | 评论 (1)编辑
     摘要: 首先是怎么使用MagicAjax.Net。这个其实很多人多讲过了,我这里重复一下。 首先还是新建个项目,然后添加引用:MagicAjax.dll。然后在配置文件Web.config中放入以下配置:<httpModules><addname="MagicAjax"type="MagicAjax.MagicAjaxModule,MagicAjax"/></httpModu... 阅读全文
posted @ 2006-04-20 15:08 小笨笨 阅读(785) | 评论 (0)编辑
        接口是某些方法和字段构成的一个集合。一个接口中可以不声明任何方法和字段,也可以声明多个方法和字段,但它永远不能实例化。当一个类实现了一个接口,它就要实现接口中的所有方法,如果这个类没有做到这点,那么这个类是不能实例化的。当一个类实现了一个接口,其它类的对象就能通过这个接口对类进行访问。一个类可以实现多个接口,当然,一个接口也可以为多个类所实现。
        从功能上来说,委托和接口是比较相似的。其实委托最常见的应用是传统C或C++程序员会使用函数指针的情况。也就是说,委托与函数指针类似,它可以把函数的引用和实现分离开,允许实现作为独立的模块存在。与接口相比,委托有一个优势,使得它的使用比接口更加灵活,那就是委托可以很容易的链接到一起,也就是允许多个委托组合成一个委托链。我们可以用“+=”和“-+”轻松地做到。当然我们在需要地时候还可以手工迭代委托链。比如下面一段代码:
Delegate [] examples = Fxb.GetInvocationList();
foreach(Delegate f in examples)
{
   f.DynamicInvoke(args);
}
        这段代码是调用委托地GetInvocationList方法检索委托实例的列表,并返回一个System.Delegate对象数组,这些对象构成委托链。这样写有些好处,比如可以用来引发异常,还可以查看委托链中每个方法的值。委托既可以与静态方法关联,也可以与非静态方法相关联,只要先提供此类的一个特定实例即可。
        委托说了半天,继续回头说接口。接口中可以有属性,方法,甚至可以有事件(event),但就是不能包含委托,因为委托是一个类型。我们在接口中使用属性也是很重要的一点,因为这会方便客户使用反射检测并了解实现了这个接口的类的行为。
        其实序幕里应该讲讲UML的,但本人比较懒,也就略过了,反正也不是很难的东西,在模式的学习中对UML有个了解也就够了。
posted @ 2006-04-18 20:59 小笨笨 阅读(179) | 评论 (0)编辑