我试图使用IHttpAsyncHandler在请求管道中注入一个解码过滤器,但是我发现Request.Filter属性被忽略了。
有没有人成功地将Request.Filter与IHttpAsyncHandler一起使用?
public class DecodeHttpHandler : IHttpAsyncHandler {
public void ProcessRequest(HttpContext context) {
context.Request.Filter = new DecodeStream(context.Request.Filter);
}
public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) {
var decodeContext = new DecodeContext(context);
var w = new HttpContextWrapper(context);
w.Request.Filter = new DecodeStream(w.Request.Filter);
return RequestHandler.BeginProcessRequestBase(w, cb, extraData);
}
public void EndProcessRequest(IAsyncResult result){
RequestHandler.EndProcessRequestBase(result);
}
public bool IsReusable {
get {
return true;
}
}
}
public class DecodeStream : Stream {
... details ...
public override int Read(byte[] buffer, int offset, int count) {
// never gets here
int c = _sink.Read(buffer, offset, count);
return c;
}
}编辑:我找到了另一种不涉及Request.Filter的好方法,粘贴在下面。然而,令人费解的是Request.Filter根本不能工作。仅供参考,我的用例是在调用第三方RequestHandler之前进行网址解码。
public class UrlDecodeHttpHandler : IHttpAsyncHandler {
public void ProcessRequest(HttpContext context) {
throw new NotImplementedException();
}
public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) {
var decodeContext = new DecodeContext(context);
return RequestHandler.BeginProcessRequestBase(decodeContext, cb, extraData);
}
public void EndProcessRequest(IAsyncResult result){
RequestHandler.EndProcessRequestBase(result);
}
public bool IsReusable {
get {
return false;
}
}
}
public class DecodeContext : HttpContextWrapper {
private readonly HttpContext _context;
public DecodeContext(HttpContext httpContext) : base(httpContext){
_context = httpContext;
}
public override HttpRequestBase Request {
get { return new DecodeRequest(_context.Request); }
}
}
public class DecodeRequest : HttpRequestWrapper {
public DecodeRequest(HttpRequest request) : base(request) {}
public override Stream InputStream {
get {
string result;
using (var sr = new StreamReader(base.InputStream)) {
result = HttpUtility.UrlDecode(sr.ReadToEnd());
}
return GenerateStreamFromString(result);
}
}
private static Stream GenerateStreamFromString(string s) {
var stream = new MemoryStream();
var writer = new StreamWriter(stream);
writer.Write(s);
writer.Flush();
stream.Position = 0;
return stream;
}
} 发布于 2012-03-31 00:06:22
在httphandler中有很多东西是不能改变的,因为为时已晚。您可以尝试在其中放置一个HTTPModule来拦截,看看这是否有帮助。注意,我还没有尝试过,如果我有时间在家,我会的。
https://stackoverflow.com/questions/9574769
复制相似问题