广告
返回顶部
首页 > 资讯 > 精选 >HttpContext.Current实例分析
  • 387
分享到

HttpContext.Current实例分析

2023-06-17 09:06:45 387人浏览 八月长安
摘要

本篇内容主要讲解“HttpContext.Current实例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“HttpContext.Current实例分析”吧!无处不在的HttpContext

本篇内容主要讲解“HttpContext.Current实例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“HttpContext.Current实例分析”吧!

无处不在的HttpContext

由于asp.net提供了静态属性HttpContext.Current,因此获取HttpContext对象就非常方便了。也正是因为这个原因,所以我们经常能见到直接访问HttpContext.Current的代码:

public class Class1  {      public Class1()      {          string file = HttpContext.Current.Request.MapPath("~/App_Data/xxxxxx.xml");           string text = System.io.File.ReadAllText(file);           //..........其它的操作      }       // 或者在一些方法中直接使用HttpContext.Current      public void XXXXX()      {          string url = HttpContext.Current.Request.RawUrl;           string username = HttpContext.Current.Session["username"].ToString();           string value = (string)HttpContext.Current.Items["key"];      }       // 甚至还设计成静态属性      public static string XXX      {          get         {              return (string)HttpContext.Current.Items["XXX"];          }      }  }

这样的代码,经常能在类库项目中看到,由此可见其泛滥程度。

难道这些代码真的没有问题吗?

有人估计会说:我写的代码是给ASP.net程序使用的,又不是给控制台程序使用,所以没有问题。

真的是这样吗?

HttpContext.Current到底保存在哪里?

的确,在一个ASP.NET程序中,几乎任何时候,我们都可以访问HttpContext.Current得到一个HttpContext对象,然而,您有没有想过它是如何实现的呢?

如果您没有想过这个事情,那我今天就来告诉您吧。请看下面的代码

protected void Page_Load(object sender, EventArgs e)  {      HttpContext context1 = HttpContext.Current;       HttpContext context2 = System.Runtime.Remoting.Messaging.CallContext.HostContext as HttpContext;       bool isEqual = object.ReferenceEquals(context1, context2);       Response.Write(isEqual);  }

猜猜会显示什么?

HttpContext.Current实例分析

这就是我看到的结果,不信的话您也可以试试。

从这段代码来看,HttpContext其实是保存在CallContext.HostContext这个属性中,如果您还对HostContext感到好奇的话,您可以自己用Reflector.exe去看,我不想再贴代码了,因为有些类型和方法并不是公开的。

我们还是来看看MSDN是如何解释CallContext.HostContext的吧:

获取或设置与当前线程相关联的主机上下文。

这个解释非常含糊,不过有二个关键词我们可以记下来:【当前线程】,【关联】。

是说:和当前线程相关联的某个东西吗?

我是这样理解的。

我们在一个ASP.NET程序中,为什么可以到处访问HttpContext.Current呢?

因为ASP.NET会为每个请求分配一个线程,这个线程会执行我们的代码来生成响应结果,即使我们的代码散落在不同的地方(类库),线程仍然会执行它们,所以,我们可以在任何地方访问HttpContext.Current获取到与【当前请求】相关的HttpContext对象,毕竟这些代码是由同一个线程来执行的嘛,所以得到的HttpContext引用也就是我们期待的那个与请求相关的对象。

因此,将HttpContext.Current设计成与【当前线程】相关联是合适的。

HttpContext并非无处不在!

【当前线程】是个什么意思? 我为什么要突出这个词呢?

答:

当前线程是指与【当前请求】相关的线程。

在ASP.NET中,有些线程并非总是与请求相关。

感觉有点绕口吗? 不容易理解吗? 还是继续往下看吧。

虽然在ASP.NET程序中,几乎所有的线程都应该是为响应请求而运行的,

但是,还有一些线程却不是为了响应请求而运行,例如:

定时器的回调。

Cache的移除通知。

APM模式下异步完成回调。

主动创建线程或者将任务交给线程池来执行。

在以上这些情况中,如果线程执行到HttpContext.Current,您认为会返回什么?

还是一个HttpContext的实例引用吗?

如何是,那它与哪个请求关联?

显然,在1,2二种情况中,访问HttpContext.Current将会返回 null 。

因为很有可能任务在运行时根本没有任何请求发生。了解异步的人应该能很容易理解第3种情况(就当是个结论吧)

第4种情况就更不需要解释了,因为确实不是当前线程。

既然是这样,那我们再看一下本文开头的一段代码:

public Class1()  {      string file = HttpContext.Current.Request.MapPath("~/App_Data/xxxxxx.xml");       string text = System.IO.File.ReadAllText(file);       //..........其它的操作  }

想像一下:如果Class1是在定时器回调或者Cache的移除通知时被创建的,您认为它还能正常运行吗?

此刻您心里应该有答案了吧?

可能您会想:为什么我在其它任何地方又可以访问HttpContext.Current得到HttpContext引用呢?

答:那是因为ASP.NET在调用您的代码前,已经将HttpContext设置到前面所说的CallContext.HostContext属性中。

HttpApplication有个内部方法OnThreadEnter(),ASP.NET在调用外部代码前会调用这个方法来切换HttpContext,例如:每当执行管线的事件处理器之前,或者同步上下文(AspNetSynchronizationContext)执行回调时。切换线程的CallContext.HostContext属性之后,我们的代码就可以访问到HttpContext引用。注意:HttpContext的引用其实是保存在HttpApplication对象中。

有时候我们会见到【ASP.NET线程】这个词,今天正好来说说我对这个词的理解:当前线程是与一个HttpContext相关的线程,由于线程与HttpContext相关联,也就意味着它正在处理发送给ASP.NET的请求。注意:这个线程仍然是线程池的线程。

如何获取文件绝对路径?

在定时器回调或者Cache的移除通知中,有时确实需要访问文件,然而对于开发人员来说,他们并不知道网站会被部署在哪个目录下,因此不可能写出绝对路径,他们只知道相对于网站根目录的相对路径,为了定位文件路径,只能调用HttpContext.Current.Request.MapPath或者 HttpContext.Current.Server.MapPath来获取文件的绝对路径。如果HttpContext.Current返回了null,那该如何如何访问文件?

其实方法并非MapPath一种,我们可以访问HttpRuntime.AppDomainAppPath获取网站的路径,然后再拼接文件的相对路径即可:

HttpContext.Current实例分析

看到没:图片中HttpContext.Current显示的是 null ,所以您要是再调用MapPath,就必死无疑!

在此我也奉劝大家一句:尽量不要用MapPath,HttpRuntime.AppDomainAppPath才是更安全的选择。

异步调用中如何访问HttpContext?

前面我还提到在APM模式下的异步完成回调时,访问HttpContext.Current也会返回null,那么此时该怎么办呢?

答案有二种:

在类型中添加一个字段来保存HttpContext的引用(异步开始前)。

将HttpContext赋值给BeginXXX方法的最后一个参数(object state)

建议优先选择第二种方法,因为可以防止以后他人维护时数据成员被意外使用。

安全地使用HttpContext.Current

有时我们会写些通用类库给ASP.NET或者windowsService程序来使用,例如异常记录的工具方法。对于ASP.NET程序来说,我们肯定希望在异常发生时,能记录URL,表单值,Cookie等等数据,便于事后分析。然而对于WindowsService这类程序来说,您肯定没想过要记录Cookie吧?那么如何实现一个通用的功能呢?

方法其实也简单,就是要判断HttpContext.Current是否返回null,例如下面的示例代码:

public static void LogException(Exception ex)  {      StringBuilder sb = new StringBuilder();      sb.Append("异常发生时间:").AppendLine(DateTime.Now.ToString());      sb.AppendLine(ex.ToString());       // 如果是ASP.NET程序,还需要记录URL,FORM, COOKIE之类的数据      HttpContext context = HttpContext.Current;      if( context != null ) {          // 能运行到这里,就肯定是在处理ASP.NET请求,我们可以放心地访问Request的所有数据          sb.AppendLine("Url:" + context.Request.RawUrl);           // 还有记录什么数据,您自己来实现吧。      }       System.IO.File.AppendAllText("日志文件路径", sb.ToString());  }

就是一个判断,解决了所有问题,所以请忘记下面这类不安全的写法吧:

HttpContext.Current.Request.RawUrl;  HttpContext.Current.Server.MapPath("xxxxxx");

下面的方法才是安全的:

HttpContext context = HttpContext.Current;  if( context != null ) {      // 在这里访问与请求有关的东西。  }

到此,相信大家对“HttpContext.Current实例分析”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

--结束END--

本文标题: HttpContext.Current实例分析

本文链接: https://www.lsjlt.com/news/288037.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • HttpContext.Current实例分析
    本篇内容主要讲解“HttpContext.Current实例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“HttpContext.Current实例分析”吧!无处不在的HttpContext...
    99+
    2023-06-17
  • jQuery.ajaxPrefilter实例分析
    这篇文章主要讲解了“jQuery.ajaxPrefilter实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“jQuery.ajaxPrefilter实...
    99+
    2022-10-19
  • jQuery.getScript实例分析
    这篇文章主要讲解了“jQuery.getScript实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“jQuery.getScript实例分析”吧! ...
    99+
    2022-10-19
  • callbacks.disabled实例分析
    这篇文章主要介绍“callbacks.disabled实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“callbacks.disabled实例分析”文章能帮助...
    99+
    2022-10-19
  • ADO实例分析
    本篇内容介绍了“ADO实例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!定义和用法Close 方法用于关闭 Connection 对象、...
    99+
    2023-06-17
  • Hibernate实例分析
    这篇文章主要介绍“Hibernate实例分析”,在日常操作中,相信很多人在Hibernate实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Hibernate实例分析”的疑惑有所帮助!接下来,请跟着小编...
    99+
    2023-06-17
  • HTML实例分析
    今天小编给大家分享一下HTML实例分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。HTML是什么HTML 是一种语言,它的...
    99+
    2023-06-27
  • HashMap实例分析
    这篇“HashMap实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“HashMap实例分析”文章吧。场景扮演面试官: ...
    99+
    2023-06-27
  • vue实例分析
    本篇内容介绍了“vue实例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!  Vue (读音 /vjuː/,类似于 View) 是一套用于...
    99+
    2023-06-22
  • MySQL分库分表实例分析
    这篇“MySQL分库分表实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“MySQL分库分表实例分析”文章吧。一、为什么...
    99+
    2023-06-30
  • Android AlertDialog实例分析
    这篇文章主要讲解了“Android AlertDialog实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Android AlertDialog实例分析”吧!AlertDialog可以...
    99+
    2023-06-25
  • Javascript API实例分析
    这篇文章主要介绍“Javascript  API实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Javascript  API实例分析”文...
    99+
    2022-10-19
  • React SSR实例分析
    这篇文章主要介绍“React SSR实例分析”,在日常操作中,相信很多人在React SSR实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”React SSR实例分析”...
    99+
    2022-10-19
  • JavaScript Hoisting实例分析
    这篇文章主要介绍“JavaScript Hoisting实例分析”,在日常操作中,相信很多人在JavaScript Hoisting实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望...
    99+
    2022-10-19
  • HTML的实例分析
    这篇文章主要为大家展示了“HTML的实例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“HTML的实例分析”这篇文章吧。 实例:<!doctype&n...
    99+
    2022-10-19
  • C# XML实例分析
    本篇内容介绍了“C# XML实例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!C# XML解析的实现是如何的呢?下面我们来看看实现的方法...
    99+
    2023-06-17
  • Javacc的实例分析
    这篇文章将为大家详细讲解有关Javacc的实例分析,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。PARSER_BEGIN(Simple1)public class Simple1 { &nb...
    99+
    2023-06-03
  • Oracle表分区实例分析
    这篇文章主要介绍了Oracle表分区实例分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Oracle表分区实例分析文章都会有所收获,下面我们一起来看看吧。一、 表空间及分区表的概念表空间:是一个或多个数据文件...
    99+
    2023-06-30
  • MySQL实例crash的示例分析
    这篇文章主要介绍MySQL实例crash的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!【问题描述】我们生产环境有一组集群的多台MySQL服务器(MySQL 5.6.21),...
    99+
    2022-10-18
  • C++单例模式实例分析
    本篇内容介绍了“C++单例模式实例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!不能被拷贝的类拷贝只会放生在两个场景中:拷贝构造函数以及...
    99+
    2023-06-29
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作