这里请关注一下属性StatusCode。我们经常用JQuery来实现Ajax,比如:使用ajax()函数,虽然你可以设置error回调函数,但是,极有可能在服务端即使抛黄页了,也不会触发这个回调函数,除非是设置了dataType="json",这时在解析失败时,才会触发这个回调函数,如果是dataType="html",就算是黄页了,也能【正常显示】。
怎么办?在服务端发生异常不能返回正确结果时,请设置StatusCode属性,比如:Response.StatusCode = 500;
HttpContext
终于轮到大人物出场了。
应该可以这么说:有了HttpRequest, HttpResponse分别控制了输入输出,就应该没有更重要的东西了。但我们用的都是HttpRequest, HttpResponse的实例,它们在哪里创建的呢,哪里保存有它们最原始的引用呢?答案当然是:HttpContext 。没有老子哪有儿子,就这么个关系。更关键的是:这个老子还很牛,【在任何地方都能找到它】,而且我前面提到另二个实力不错的选手(HttpServerUtility和Cache),也都是它的手下。因此,任何事情,找到它就算是有办法了。你说它是不是最牛。
不仅如此,在ASP.NET的世界,还有黑白二派。Module像个土匪,什么请求都要去“检查”一下,Handler更像白道上的人物,点名了只做某某事。有趣的是:HttpContext真像个大人物,黑白道的人物有时都要找它帮忙。帮什么忙呢?可怜的土匪没有仓库,它有东西没地方存放,只能存放在HttpContext那里,有时惹得Handler也盯上了它,去HttpContext去拿土匪的战利品。
这位大人物的传奇故事大致就这样。我们再来从技术的角度来观察它的功能。
虽然HttpContext也公开了一些属性和方法,但我认为最重要的还是上面提到的那些对象的引用。
这里再补充二个上面没提到的实例属性:User, Items
User属性保存于当前请求的用户身份信息。如果判断当前请求的用户是不是已经过身份认证,可以访问:Request.IsAuthenticated这个实例属性。
前面我在故事中提到:“可怜的土匪没有仓库,它有东西没地方存放,只能存放在HttpContext那里”,其实这些东西就是保存在Items属性中。这是个字典,因此适合以Key/Value的方式来访问。如果希望在一次请求的过程中保存一些临时数据,那么,这个属性是最理想的存放容器了。它会在下次请求重新创建,因此,不同的请求之间,数据不会被共享。
如果希望提供一些静态属性,并且,只希望与一次请求关联,那么建议借助HttpContext.Items的实例属性来实现。
我曾经见过有人用ThreadStaticAttribute来实现这个功能,然后在Page.Init事件中去修改那个字段。
哎,哥啊,MSDN上说:【用 ThreadStaticAttribute 标记的 static 字段不在线程之间共享。每个执行线程都有单独的字段实例,并且独立地设置及获取该字段的值。如果在不同的线程中访问该字段,则该字段将包含不同的值。】 注意了:一个线程可以执行多次请求过程,且Page.Init事件在ASP.NET的管道中属于较中间的事件啊,要是请求不使用Page呢,您再想想吧。
前面我提到HttpContext有种超能力:【在任何地方都能找到它】,是的,HttpContext有个静态属性Current,你说是不是【在任何地方都能找到它】。千万别小看这个属性,没有它,HttpContext根本牛不起来。
也正是因为这个属性,在ASP.NET的世界里,您可以在任何地方访问Request, Response, Server, Cache,还能在任何地方将一些与请求有关的临时数据保存起来,这绝对是个非常强大的功能。Module的在不同的事件阶段,以及与Handler的”沟通“有时就通过这个方式来完成。
还记得我上篇博客【Session,有没有必要使用它?】中提到的事情吗:每个页面使用Session的方式是使用Page指令来说明的,但Session是由SessionS