HttpResponse的Output与OutputStream、Filter关系与区别介绍

 更新时间:2021年9月22日 10:18  点击:1825
在网上经常看见有这样的代码

HttpResponse response = HttpContext.Current.Response;
response.Filter = new PageFilter(response.Filter);

来拦截输出流,自己也做个类似的东东,如asp.net中 js 合并 压缩,现在我也来说说这几个东东是什么吧,需要大家对asp.net的生命周期比较熟悉,如不熟悉的朋友建议先看看ASP.NET 请求处理流程 ASP.NET管线与应用程序生命周期

首先我们来看看这3个属性的源代码吧:

复制代码 代码如下:

public TextWriter Output
{
get
{
return this._writer;
}
set
{
this._writer = value;
}
}


public Stream OutputStream
{
get
{
if (!this.UsingHttpWriter)
{
throw new HttpException(SR.GetString("OutputStream_NotAvail"));
}
return this._httpWriter.OutputStream;
}
}


复制代码 代码如下:

public Stream Filter
{
get
{
if (this.UsingHttpWriter)
{
return this._httpWriter.GetCurrentFilter();
}
return null;
}
set
{
if (!this.UsingHttpWriter)
{
throw new HttpException(SR.GetString("Filtering_not_allowed"));
}
this._httpWriter.InstallFilter(value);
IIS7WorkerRequest request = this._wr as IIS7WorkerRequest;
if (request != null)
{
request.ResponseFilterInstalled();
}
}
}

我们看到Filter和OutputStream都用到了一个属性UsingHttpWriter,那这个属性是怎么定义的了
复制代码 代码如下:

private bool UsingHttpWriter
{
get
{
return ((this._httpWriter != null) && (this._writer == this._httpWriter));
}
}

从这个属性我们可以知道_writer 、_httpWriter实际上是同一个东东,它们的类型是HttpWriter ,而HttpWriter 又继承与TextWriter。现在我们可以解释Output就是_httpWriter,而OutputStream是_httpWriter的OutputStream属性。类HttpWriter 主要代码如下
复制代码 代码如下:

public Stream OutputStream
{
get
{
return this._stream;
}
}


internal HttpWriter(HttpResponse response) : base(null)
{
this._response = response;
this._stream = new HttpResponseStream(this);
this._buffers = new ArrayList();
this._lastBuffer = null;
this._charBuffer = (char[]) s_Allocator.GetBuffer();
this._charBufferLength = this._charBuffer.Length;
this._charBufferFree = this._charBufferLength;
this.UpdateResponseBuffering();
}


internal HttpResponseStream(HttpWriter writer)
{
this._writer = writer;
}

HttpResponse 在Filter属性设置调用了HttpWriter类的InstallFilter方法,而获取调用了该类的GetCurrentFilter
复制代码 代码如下:

internal void InstallFilter(Stream filter)
{
if (this._filterSink == null)
{
throw new HttpException(SR.GetString("Invalid_response_filter"));
}
this._installedFilter = filter;
}

internal Stream GetCurrentFilter()
{
if (this._installedFilter != null)
{
return this._installedFilter;
}
if (this._filterSink == null)
{
this._filterSink = new HttpResponseStreamFilterSink(this);
}
return this._filterSink;
}

由以上代码我们可以得知HttpResponse的输出流就是Filter属性设置的流,即HttpResponse的Output和OutputStream属性的输出流都是来自Filter中的流。我们来看看_writer 、_httpWriter它们是在什么时候初始化的了?在HttpResonse中有一个方法
复制代码 代码如下:

internal void InitResponseWriter()
{
if (this._httpWriter == null)
{
this._httpWriter = new HttpWriter(this);
this._writer = this._httpWriter;
}
}

该方法是由HttpRuntime的ProcessRequestInternal来调用
复制代码 代码如下:

private void ProcessRequestInternal(HttpWorkerRequest wr)
{
HttpContext context;
try
{
context = new HttpContext(wr, false);
}
catch
{
wr.SendStatus(400, "Bad Request");
wr.SendKnownResponseHeader(12, "text/html; charset=utf-8");
byte[] bytes = Encoding.ASCII.GetBytes("<html><body>Bad Request</body></html>");
wr.SendResponseFromMemory(bytes, bytes.Length);
wr.FlushResponse(true);
wr.EndOfRequest();
return;
}
wr.SetEndOfSendNotification(this._asyncEndOfSendCallback, context);
Interlocked.Increment(ref this._activeRequestCount);
HostingEnvironment.IncrementBusyCount();
try
{
try
{
this.EnsureFirstRequestInit(context);
}
catch
{
if (!context.Request.IsDebuggingRequest)
{
throw;
}
}
context.Response.InitResponseWriter();
IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(context);
if (applicationInstance == null)
{
throw new HttpException(SR.GetString("Unable_create_app_object"));
}
if (EtwTrace.IsTraceEnabled(5, 1))
{
EtwTrace.Trace(EtwTraceType.ETW_TYPE_START_HANDLER, context.WorkerRequest, applicationInstance.GetType().FullName, "Start");
}
if (applicationInstance is IHttpAsyncHandler)
{
IHttpAsyncHandler handler2 = (IHttpAsyncHandler) applicationInstance;
context.AsyncAppHandler = handler2;
handler2.BeginProcessRequest(context, this._handlerCompletionCallback, context);
}
else
{
applicationInstance.ProcessRequest(context);
this.FinishRequest(context.WorkerRequest, context, null);
}
}
catch (Exception exception)
{
context.Response.InitResponseWriter();
this.FinishRequest(wr, context, exception);
}
}

[!--infotagslink--]

相关文章

  • 浅析AngularJS Filter用法

    系统的学习了一下angularjs,发现angularjs的有些思想根php的模块smarty很像,例如数据绑定,filter。如果对smarty比较熟悉的话,学习angularjs会比较容易一点,这篇文章给大家介绍angularjs filter用法详解,感兴趣的朋友一起学习吧...2015-12-29
  • nestjs中异常过滤器Exceptionfilter的具体使用

    这篇文章主要介绍了nestjs中异常过滤器Exceptionfilter的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-07
  • Angularjs中如何使用filterFilter函数过滤

    这篇文章主要介绍了Angularjs中如何使用filterFilter函数过滤的相关资料,需要的朋友可以参考下...2016-02-12
  • jQuery遍历DOM节点操作之filter()方法详解

    这篇文章主要介绍了jQuery遍历DOM节点操作之filter()方法,结合实例形式详细分析了filter的功能及4种具体用法,需要的朋友可以参考下...2016-04-17
  • Spring Security和自定义filter的冲突导致多执行的解决方案

    这篇文章主要介绍了Spring Security和自定义filter的冲突导致多执行的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-06-23
  • asp.net core MVC 全局过滤器之ExceptionFilter过滤器(1)

    这篇文章主要为大家详细介绍了asp.net core MVC 全局过滤器之ExceptionFilter过滤器,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-22
  • 详解Angularjs filter过滤器

    这篇文章主要介绍了angularjs filter过滤器的相关资料,需要的朋友可以参考下...2016-02-12
  • AngularJS中的过滤器filter用法完全解析

    这篇文章主要介绍了AngularJS中的过滤器filter用法,包括Angular中一些常用的自带的过滤器的列举以及自定义filter的方法,需要的朋友可以参考下...2016-04-24
  • Event filter with query SELECT * FROM __InstanceModificationEvent WITHIN

    这篇文章主要介绍了Event filter with query SELECT * FROM __InstanceModificationEvent WITHIN ,需要的朋友可以参考下...2016-01-27
  • php中array_map,array_filter,array_walk区别

    在php中array_map,array_filter,array_walk三个函数都是对数据操作的,下面我来介绍这三个函数的用法与区别。 array_walk: array_walk()返回布尔值,如果回调函数...2016-11-25
  • 在django中查询获取数据,get, filter,all(),values()操作

    这篇文章主要介绍了在django中查询获取数据,get, filter,all(),values()操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-09
  • Java中使用Filter过滤器的方法

    Filter过滤器是javaWeb层面的,它跟Servlet类似,每次前端请求,首先进入的是过滤器,我们必须实现Filter接口,重写三个方法,才能使用Filter过滤器,需要的朋友可以参考下...2021-06-28
  • 详解AngularJS Filter(过滤器)用法

    这篇文章主要介绍了AngularJS的filter,中文名“过滤器”是用来过滤变量的值,或者格式化输出,得到自己所期望的结果或格式的东东,的相关资料,需要的朋友可以参考下...2015-12-29
  • django rest framework使用django-filter用法

    这篇文章主要介绍了django rest framework使用django-filter用法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-15
  • 使用Filter拦截器如何实现请求跨域转发

    这篇文章主要介绍了使用Filter拦截器如何实现请求跨域转发,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-08-29
  • php FILTER_VALIDATE_IP

    过滤器验证ip地址,是否合法。 定义和用法 该过滤器验证FILTER_VALIDATE_IP价值作为一个网址。 名称: “ validate_ip ” 身份证号码: 275 可能...2016-11-25
  • Springboot 如何实现filter拦截token验证和跨域

    这篇文章主要介绍了Springboot 如何实现filter拦截token验证和跨域操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-08-12
  • 基于python实现matlab filter函数过程详解

    这篇文章主要介绍了基于python实现matlab filter函数过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-06-09
  • Java GZIPOutputStream流压缩文件的操作

    这篇文章主要介绍了Java GZIPOutputStream流压缩文件的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-08
  • Spring Security之默认的过滤器链及自定义Filter操作

    这篇文章主要介绍了Spring Security之默认的过滤器链及自定义Filter操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-06-23