2010-02-16 74 views
2

請幫我使用此操作過濾器。asp.net MVC ActionFilter用於刪除結果中的空行

我想我需要使用OnResultExecuted方法

我如何可以訪問otput HTML和他們取代的東西?

謝謝。

+0

那你想要做的(爲什麼)?如果你想刪除空行來減少輸出,你應該考慮用gzip來壓縮結果。 –

+0

正如你在代碼隱藏剩下的空行的地方源代碼(HTML)渲染頁面後知道.. 爲前:

現在我們做一個網絡的應用爲移動設備和我們有一些舊設備很多空行,空格(!)等問題。 我們試圖找到一種方法將它們從html中刪除。 最好的看法是所有的html將被轉換成1行。 – Maxim

回答

2

如何使用空白刪除HTTP模塊?這是實現簡單,簡潔和可重用......

http://madskristensen.net/post/A-whitespace-removal-HTTP-module-for-ASPNET-20.aspx

正如任何通用的空白移除的解決方案,雖然,它可以很容易地通過去除其中要求空白引入誤差。儘管如此,它不會花很長時間。 :-)

意見後編輯

這不會.aspx文件開箱即用的工作,所以你需要的context_BeginRequest更改爲以下...

void context_BeginRequest(object sender, EventArgs e) 
{ 
    HttpApplication app = sender as HttpApplication; 
    if (app.Response.ContentType == "text/html" 
     || app.Response.ContentType == "application/xhtml+xml") 
    { 
     app.Response.Filter = new WhitespaceFilter(app.Response.Filter); 
    } 
} 
+0

該模塊與我建議的幾乎完全相同。但是,它不能用於開箱即用的asp.net mvc,因爲它需要你的url有一個.aspx擴展名(這裏可能不是這種情況)。所以你必須找到另一種方法來檢查你是否應該刪除響應中的空格。您可以通過檢查針對正則表達式的響應來查看它是否爲html。 –

+0

如何檢查text/html(或application/xhtml + xml,取決於您返回的內容)的響應內容類型?請參閱編輯我的原始答案。由於其模塊化和易於重用,我認爲HTTP模塊將是有益的。 –

+0

我使用這種方法,並應用在global.asax 與.aspx擴展我解決這種方式: string rawUrl = Request.RawUrl.ToLower(); (rawUrl.Contains(「/ account /」)|| rawUrl.Contains(「/ feedback /」)|| rawUrl.Contains(「/ home /」)) (控制器名稱) – Maxim

1

現在我明白你想要做什麼了。我想我可能有一個解決方案。我已經在輸出緩存解決方案中使用了這種方法的一部分,所以我認爲它會起作用。

首先,你需要自己的流類,看起來像這樣:

private class CapturingResponseFilter : Stream 
{ 
    private readonly Stream _sink; 
    private readonly MemoryStream _mem; 

    public CapturingResponseFilter(Stream sink) 
    { 
     _sink = sink; 
     _mem = new MemoryStream(); 
    } 

    public override bool CanRead 
    { 
     get { return true; } 
    } 

    public override bool CanSeek 
    { 
     get { return false; } 
    } 

    public override bool CanWrite 
    { 
     get { return false; } 
    } 

    public override long Length 
    { 
     get { return 0; } 
    } 

    public override long Position { get; set; } 

    public override long Seek(long offset, SeekOrigin direction) 
    { 
     return 0; 
    } 

    public override void SetLength(long length) 
    { 
     _sink.SetLength(length); 
    } 

    public override void Close() 
    { 
     _sink.Close(); 
     _mem.Close(); 
    } 

    public override void Flush() 
    { 
     _sink.Flush(); 
    } 

    public override int Read(byte[] buffer, int offset, int count) 
    { 
     return _sink.Read(buffer, offset, count); 
    } 

    public override void Write(byte[] buffer, int offset, int count) 
    { 
     _mem.Write(buffer, 0, count); 
    } 

    public string GetContents(Encoding enc) 
    { 
     var buffer = new byte[_mem.Length]; 
     _mem.Position = 0; 
     _mem.Read(buffer, 0, buffer.Length); 
     return enc.GetString(buffer, 0, buffer.Length); 
    } 
} 

然後你做這樣的事情在你的動作過濾器:

private Stream _originalOutputStream; 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     _originalOutputStream = filterContext.HttpContext.Response.Filter; 
     filterContext.HttpContext.Response.Flush(); 
     filterContext.HttpContext.Response.Filter = new CapturingResponseFilter(filterContext.HttpContext.Response.Filter); 
    } 

    public override void OnResultExecuted(ResultExecutedContext filterContext) 
    { 
     if (_originalOutputStream == null) return; 

     filterContext.HttpContext.Response.Flush(); 
     var capturingResponseFilter = (CapturingResponseFilter)filterContext.HttpContext.Response.Filter; 
     filterContext.HttpContext.Response.Filter = _originalOutputStream; 
     var textWritten = capturingResponseFilter.GetContents(filterContext.HttpContext.Response.ContentEncoding); 
     //Do what you want with your text (textWritten). 
     filterContext.HttpContext.Response.Write(textWritten); 
    } 

我會考慮它的一點點一個黑客解決方案。但我沒有看到任何不是。

+0

謝謝。 您的方法與http://madskristensen.net/post/A-whitespace-removal-HTTP-module-for-ASPNET-20.aspx, 類似,但存在一些問題。 我將它們應用於基礎控制器(所有控制器都從它們繼承),現在我遇到了重定向操作的問題:發送HTTP頭之後無法重定向! – Maxim

+0

你不能做所有的動作,只有一次呈現html。你可能想看看羅素的解決方案。這幾乎是相同的東西,但使用http模塊而不是操作過濾器。 –

1

我想擴展羅素的解決方案。在MVC中,或者我猜在beginrequest事件中的任何地方Response.ContentType是「text/html」,因爲我們不知道我們會回答什麼。 我founf其中內容被定義另一個事件和過濾器是applyable:PostReleaseRequestState

http://www.4guysfromrolla.com/articles/120308-1.aspx