asp.NetmvcではHttpResponseを使用する.Filter

20791 ワード

HttpResponseのFilter属性はStreamであり,このストリームを書き換えることでresponseオブジェクトの出力を変更することができる.フィルタをカスタマイズする場合、Streamから直接新しいクラスが派生する場合は、Streamのすべての抽象メソッドを実装する必要がありますが、実際のアプリケーションでは、Writeメソッドだけがフィルタを作成する際に最も関心を持っています.ここのHttpResponseFilter抽象クラスは少し便利です.

  
    
/// <summary>
/// ResponseFilter , 。
/// Write , Stream 。
///
///
/// (1) , , 。
/// (2) Sink
/// (3) Write , 。Write Stream 。
///
/// PageTitelFilter ,
/// </summary>
public abstract class HttpResponseFilter : Stream
{
private Stream _sink;
private long _position;
/// <summary>
///
/// </summary>
/// <param name="sink"> </param>
protected HttpResponseFilter(Stream sink)
{
this ._sink = sink;
}
/// <summary>
///
/// </summary>
protected Stream Sink
{
get
{
return _sink;
}
}
public override sealed long Seek( long offset, SeekOrigin origin)
{
return _sink.Seek(offset, origin);
}
public override sealed void SetLength( long value)
{
_sink.SetLength(value);
}
public override sealed void Close()
{
_sink.Close();
}
public override sealed void Flush()
{
_sink.Flush();
}
public override sealed int Read( byte [] buffer, int offset, int count)
{
return _sink.Read(buffer, offset, count);
}
public override sealed bool CanRead
{
get
{
return true ;
}
}
public override sealed bool CanSeek
{
get
{
return true ;
}
}
public override sealed bool CanWrite
{
get
{
return true ;
}
}
public override sealed long Length
{
get
{
return 0 ;
}
}
public override sealed long Position
{
get
{
return _position;
}
set
{
_position
= value;
}
}
}
このクラスから継承すると、ページヘッダーを指定した値に置き換えるfilterクラスを簡単に書くことができます.

  
    
[Obsolete( " " )]
/// <summary>
/// HttpResponseFilter 。
///
/// title
/// </summary>
public class PageTitleFilter : HttpResponseFilter
{
private string _pageTitle;
public PageTitleFilter(Stream sink, string title)
:
base (sink)
{
this ._pageTitle = title;
}
public override void Write( byte [] buffer, int offset, int count)
{
byte [] data = new byte [count];
Buffer.BlockCopy(buffer, offset, data,
0 , count);
string s = System.Text.Encoding.UTF8.GetString(data);
if ( string .IsNullOrEmpty(s) == false )
{
string pattern = @" <title>.*</title> " ;
string replacement = string .Format( " <title>{0}</title> " , _pageTitle);
s
= Regex.Replace(s, pattern, replacement, RegexOptions.IgnoreCase | RegexOptions.Singleline);
byte [] outData = System.Text.Encoding.UTF8.GetBytes(s);
Sink.Write(outData,
0 , outData.GetLength( 0 ));
}
else
{
Sink.Write(buffer, offset, count);
}
}
}
asp.Netmvcでは、ActionFilterAttributeを使用してHttpResponseFilterを適用できます.

  
    
public class HttpResponseFilterAttribute : ActionFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
if (System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath != " / " )
{
filterContext.HttpContext.Response.Filter
= new PageTitleFilter(filterContext.HttpContext.Response.Filter, " demo title " );
}
}
}
HttpResponseFilterAttributeをMyControllerに適用すると、MyControllerのすべてのアクション出力のページタイトルが「demo title」に置き換えられます.

  
    
[HttpResponseFilterAttribute]
public class MyController : Controller
{
// ...
}