首页 > 开发 > 综合 > 正文

关于上下文(Context)/1(转MS)

2024-07-21 02:22:03
字体:
来源:转载
供稿:网友


关于上下文
susan warren
microsoft corporation
2002年1月14日

编写 web 应用程序时最常见的问题之一,是要让代码知道它的执行上下文。让我们通过一个简单的例子(即个性化页面)来说明这个问题:
     请登录。

     欢迎 susan!
虽然看起来很简单,但即使是这一小段 web ui,仍然需要好几段信息,而且每次请求该页时这些信息都会发生变化。我们需要知道以下内容:
  1. 用户登录了吗?
  2. 用户的显示名是什么?

更通常的问题是,每次请求该页时,唯一的上下文是什么?以及如何编写代码以便能考虑到此信息?
事实上,由于 http 的无状态特性,web 应用程序可能需要跟踪许多不同的上下文片段。当用户与 web 应用程序交互时,浏览器将一系列独立的 http 请求发送到 web 服务器。应用程序自身必须将这些请求组织成令用户感到愉悦的体验;同时,知道请求的上下文也十分关键。
asp 引入了几个内部对象,如 requestapplication,以便帮助跟踪 http 请求的上下文。asp.net 完成下一步骤,并将这些对象以及其他几个与上下文有关的对象捆绑在一起,形成一个极为方便的内部对象 context
context 是 system.web.httpcontext(英文)类型的对象。它作为 asp.net page 类的属性公开。也可以通过用户控件和业务对象(下文中详细介绍)获得该对象。以下是 httpcontext 形成的对象的部分列表:
对象说明application值的关键字/值对集合,可由应用程序的每个用户访问。application 是 system.web.httpapplicationstate 类型。applicationinstance实际运行的应用程序,它公开一些请求处理事件。这些事件在 global.asax、httphandler 或 httpmodule 中处理。cacheasp.net cache 对象,它提供对缓存的编程访问。rob howard 的 asp.net caching 专栏(英文)对缓存作了详尽介绍。error处理页时遇到的第一个错误(如果有)。有关详细信息,请参阅 rob 撰写的 exception to the rule, part 1(英文)。items关键字/值对集合,可以用来在参与处理同一请求的所有组件之间传递信息。items 是 system.collections.idictionary 类型。request有关 http 请求的信息,包括浏览器信息、cookies 以及在窗体或查询字符串中传递的值。request 是 system.web.httprequest 类型。response用于创建 http 响应的设置和内容。response 是 system.web.httpresponse 类型。server服务器是一个实用程序类,带有一些有用的帮助器方法,包括 server.execute()server.mappath()server.htmlencode()。server 是 system.web.httpserverutility 类型的对象。session值的关键字/值对集合,可由应用程序的单个用户访问。session 是 system.web.httpsessionstate 类型。traceasp.net 的 trace 对象,提供对跟踪功能的访问。有关详细信息,请参阅 rob 撰写的文章 tracing(英文)。user当前用户(如果已经过身份验证)的安全上下文。context.user.identity 是用户的名称。user 是 system.security.principle.iprincipal 类型的对象。
如果您是一位 asp 开发人员,那么对上面讲述的部分对象应不会感到陌生。虽然有一些改进,但大体而言,它们在 asp.net 中的作用与在 asp 中是完全一样的。

context 基础知识


context 中的部分对象也已升级为 page 中的顶级对象。例如,page.context.responsepage.response 指的是同一个对象,因此,以下代码是等价的:

[visual basic® web 窗体]

   response.write ("您好")   context.response.write ("你好")

[c# web 窗体]

   response.write ("您好");   context.response.write ("你好");

还可以从业务对象使用 context 对象。httpcontext.current 是静态属性,可以很方便地返回当前请求的上下文。这在各种方法中都十分有用,下面仅列举一个从业务类的缓存中检索项目的简单示例:

[visual basic]

      ' 获取请求上下文      dim _context as httpcontext = httpcontext.current   ' 获取缓存中的数据集   dim _data as dataset = _context.cache("mydataset")

[c#]

      // 获取请求上下文      httpcontext _context = httpcontext.current;   // 获取缓存中的数据集   dataset _data = _context.cache("mydataset");

操作中的 context


context 对象为一些常见的 asp.net“如何…?”问题提供了答案。也许,说明此宝贵对象的价值的最好方法,就是在操作中将它展示出来。下面是一些我所知道的最巧妙的 context 技巧。

我如何从自己的业务类中生成 asp.net 跟踪语句?


回答:很简单!使用 httpcontext.current 获取 context 对象,然后调用 context.trace.write()

[visual basic]

imports systemimports system.webnamespace context   ' 演示从业务类中生成一个 asp.net    ' 跟踪语句。   public class traceemit            public sub somemethod()                  ' 获取请求上下文         dim _context as httpcontext = httpcontext.current                  ' 使用上下文编写跟踪语句         _context.trace.write("在 traceemit.somemethod 中")      end sub   end classend namespace   

[c#]

using system;using system.web;namespace context{   // 演示从业务类中生成一个 asp.net    // 跟踪语句。   public class traceemit   {        public void somemethod() {                    // 获取请求上下文            httpcontext _context = httpcontext.current;            // 使用上下文编写跟踪语句            _context.trace.write("在 traceemit.somemethod 中");        }    }}

如何才能从业务类中访问会话状态值?


回答:很简单!使用 httpcontext.current 获取 context 对象,然后访问 context.session

[visual basic]

imports systemimports system.webnamespace context   ' 演示从业务类中访问 asp.net 内部   ' 会话。   public class usesession         public sub somemethod()                  ' 获取请求上下文         dim _context as httpcontext = httpcontext.current                  ' 访问内部会话         dim _value as object = _context.session("thevalue")      end sub   end classend namespace

[c#]

using system;using system.web;namespace context{   // 演示从业务类中访问 asp.net 内部    // 会话   public class usesession   {        public void somemethod() {                    // 获取请求上下文            httpcontext _context = httpcontext.current;            // 访问内部会话            object _value = _context.session["thevalue"];        }    }}

如何才能在应用程序的每页中添加标准页眉和页脚?


回答:处理应用程序的 beginrequestendrequest 事件,并使用 context.response.write 生成页眉和页脚的 html。
从技术上讲,可以在 httpmodule 中或通过使用 global.asax 处理 beginrequest 这样的应用程序。httpmodules 的编写比较困难,而且正如本例所示,简单应用程序使用的功能通常不使用它。因此,我们使用应用程序范围的 global.asax 文件。
与 asp 页一样,一些固有的 asp.net 上下文已提升为 httpapplication 类的属性,其中的类表示 global.asax 继承类。我们不需要使用 httpcontext.current 获取对 context 对象的引用;它在 global.asax. 中已可用。
本例中,我将 <html> 和 <body> 标记以及一条水平线放入页眉部分,而将另一条水平线及相应的结束标记放入页脚部分。页脚还包含版权消息。运行结果应如下图所示:

图 1:浏览器中呈现的标准页眉和页脚示例
这是一个简单的示例,但您可以很容易地将它扩展,使其包含标准的页眉与导航,或者仅输出相应的 <!-- #include ---> 语句。请注意,如果希望页眉或页脚包含交互内容,应考虑使用 asp.net 用户控件。

[somepage.aspx 源代码 - 内容示例]

<font face="arial" color="#cc66cc" size="5">常规页面内容</font>

[visual basic global.asax]

<%@ application language="vb" %><script runat="server">      sub application_beginrequest(sender as object, e as eventargs)         ' 生成页眉         context.response.write("<html>" + controlchars.lf + _"<body bgcolor=#efefef>" + controlchars.lf + "<hr>" + _ controlchars.lf)      end sub                   sub application_endrequest(sender as object, e as eventargs)         ' 生成页脚         context.response.write("<hr>" + controlchars.lf + _      "2002 microsoft corporation 版权所有" + _      controlchars.lf + "</body>" + controlchars.lf + "</html>")      end sub </script>

[c# global.asax]

<%@ application language="c#" %><script runat="server">        void application_beginrequest(object sender, eventargs e) {            // 生成页眉            context.response.write("<html>/n<body bgcolor=#efefef>/n<hr>/n");        }        void application_endrequest(object sender, eventargs e) {            // 生成页脚            context.response.write("<hr>/2002 microsoft corporation 版权所有/n");            context.response.write("</body>/n</html>");        }</script>

如何在用户经过身份验证后显示欢迎信息?


回答:测试 user 上下文对象以查看用户是否经过身份验证。如果是,还要从 user 对象获取用户名。当然,这是本文开头的示例。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表