IHttpAsyncHandler and Request.Filter

本文关键字:Filter Request and IHttpAsyncHandler | 更新日期: 2023-09-27 18:26:54

我正试图使用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之前进行URL解码。

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;
    }
} 

IHttpAsyncHandler and Request.Filter

httphandler中有很多东西无法更改,因为为时已晚。你可以试着在那里放一个HTTPModule来拦截,看看这是否有帮助。注意:我还没有试过,如果我有时间在家,我会的。。