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
{
//
...
}