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

在网上经常看见有这样的代码

  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);
    }
}

  

 

posted on 2012-11-06 20:38  dz45693  阅读(2608)  评论(0编辑  收藏  举报

导航