HttpResponse的Output與OutputStream、Filter關係與區別介紹

來源:互聯網
上載者:User

在網上經常看見有這樣的代碼

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.