﻿# 介紹一個 ASP.NET 裡鮮為人知的 Response.Filter 屬性

ASP.NET 有一個鮮為人知也很少人使用的 [Response.Filter](http://msdn.microsoft.com/zh-tw/library/system.web.httpresponse.filter.aspx) 屬性，[Response.Filter](http://msdn.microsoft.com/zh-tw/library/system.web.httpresponse.filter.aspx) 屬性本身是一個 [Stream](http://msdn.microsoft.com/zh-tw/library/system.io.stream.aspx) 型別，所以可以利用 [Stream](http://msdn.microsoft.com/zh-tw/library/system.io.stream.aspx) 的特性，將 [Response.Filter](http://msdn.microsoft.com/zh-tw/library/system.web.httpresponse.filter.aspx) 傳給下一個 [Stream](http://msdn.microsoft.com/zh-tw/library/system.io.stream.aspx) 進行資料處理。換句話說，你就可以透過繼承自 [Stream](http://msdn.microsoft.com/zh-tw/library/system.io.stream.aspx) 的自訂型別去修改 Response.Filter 傳入的資料，並且將資料進行修正動作。

之前很早就知道有這個屬性存在，但一直沒時間研究，今天趁假日把玩了一下，感覺還不賴，發現運用這個開發技巧可發揮的領域可多了，為了讓各位有點感覺，我先秀幾段程式碼展示威力：

```csharp
Response.Filter = new GZipStream(Response.Filter, CompressionMode.Compress);    
Response.AppendHeader("Content-Encoding", "gzip");
```

以上程式碼可以放在 Page\_Init 事件裡，最主要的功能就在於他將 [Response.Filter](http://msdn.microsoft.com/zh-tw/library/system.web.httpresponse.filter.aspx) 屬性先傳入一個 [GZipStream](http://msdn.microsoft.com/zh-tw/library/system.io.compression.gzipstream\(VS.80\).aspx) 類別中，讓所有頁面輸出的 Stream 都會經過 [GZipStream](http://msdn.microsoft.com/zh-tw/library/system.io.compression.gzipstream\(VS.80\).aspx) 壓縮，最後再新增一個回應標頭，告知瀏覽器此頁回應的資料是透過 gzip 壓縮過的。

另外，如果你要將每個輸出的頁面自動將多餘的空白濾掉，也可以運用 [Response.Filter](http://msdn.microsoft.com/zh-tw/library/system.web.httpresponse.filter.aspx) 的技巧，有興趣的人可以參考 [Removing White Chars from ASP.NET Output using Response.Filter property](http://www.codeproject.com/KB/aspnet/RemovingWhiteSpacesAspNet.aspx) 這篇文章。

在我前幾天寫的 [ASP.NET MVC 開發心得分享 (3)：與 WebForm 共舞](/post/2009/02/16/ASPNET-MVC-Developer-Note-Part-3-Dancing-with-WebForm) 文章中，就有提到如何透過 [jQuery](http://jquery.com/) 將 ViewState 相關的隱藏欄位刪除，不過若是透過 [Response.Filter](http://msdn.microsoft.com/zh-tw/library/system.web.httpresponse.filter.aspx) 屬性的應用將會更完美，而我今天就是用這個例子來練習應用 [Response.Filter](http://msdn.microsoft.com/zh-tw/library/system.web.httpresponse.filter.aspx) 屬性的。

我今天寫了一個 HttpModule 專案用來對所有 ASP.NET MVC 頁面進行過濾動作，效果感覺還不錯。另外，今天也心血來潮跑去 [CodePlex](http://www.codeplex.com/) 建立一個新專案，並將今天寫的專案與原始碼都上傳上去了，有興趣的人可以到 [ASP.NET MVC Friendly HttpModule](http://www.codeplex.com/MVCFriendlyModule) 下載。

這個專案包含兩個 Stream 類別與一個 HttpModule，分別是：

1.  **StripViewStateStream**
    
    運用 Regular Expression 技巧將所有 ViewState 相關標籤全部消除
    
2.  **StripNamingContainerStream**
    
    將所有包含有 NamingContainer 的多餘名稱全部移除
    
3.  **MvcFriendlyModule**
    
    在 BeginRequest 事件裡要定義 Response.Filter 屬性需套用的 Stream 類別
    

在 **MvcFriendlyModule** 中主要程式如下，可以一次套用兩個自訂的 Stream 類別：

```csharp
void context_BeginRequest(object sender, EventArgs e)
{
    HttpApplication app = (HttpApplication)sender;

    if (app.Context.Response.ContentType == "text/html")
    {
        app.Context.Response.Filter =
            new StripNamingContainerStream(
                new StripViewStateStream(
                    app.Context.Response.Filter
                )
            );
    }
}
```

若你下載下載之後只要將 dll 加入到你現有的 ASP.NET MVC 專案，定設定網站的 web.config 加入 MvcFriendlyModule 模組即安裝完畢。

```xml
<httpModules>
    ....
    <add name="MvcFriendlyModule"
         type="MvcFriendlyModule.MvcFriendlyModule, MvcFriendlyModule" />
    ....
</httpModules>
```

除了直接套用 HttpModule 到全網站之外，你也可以僅套用在單一網頁中，也可以只單套用其中一個 Stream 就好。例如在 ViewPage 中可以寫在 Page\_Init 事件中：

```xml
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" 
         Inherits="System.Web.Mvc.ViewPage" %>
<%@ Import Namespace="MvcFriendlyModule" %>
<script runat="server">
 protected void Page_Init(object sender, EventArgs e)
 {
     Response.Filter = new StripNamingContainerStream(Response.Filter);
 }
</script>
```

其實除了 [Response.Filter](http://msdn.microsoft.com/zh-tw/library/system.web.httpresponse.filter.aspx) 屬性外，還有一個 [Request.Filter](http://msdn.microsoft.com/zh-tw/library/system.web.httprequest.filter.aspx) 屬性，用法完全一樣，可以讓你過濾所有經由 HTTP Post 進來的 Stream 資料 ( HTTP Request Body )。

**相關連結**

-   [ASP.NET MVC Friendly HttpModule](http://www.codeplex.com/MVCFriendlyModule) @ CodePlex
-   [Response.Filter 屬性](http://msdn.microsoft.com/zh-tw/library/system.web.httpresponse.filter.aspx)
-   [Request.Filter 屬性](http://msdn.microsoft.com/zh-tw/library/system.web.httprequest.filter.aspx)
-   [Removing White Chars from ASP.NET Output using Response.Filter property](http://www.codeproject.com/KB/aspnet/RemovingWhiteSpacesAspNet.aspx)
-   [Response.Filter屬性實現網站GZIP壓縮](http://www.aspstat.com/112)
-   [Producing XHTML-Compliant Pages With Response Filters](http://aspnetresources.com/articles/HttpFilters.aspx)
