从自定义处理程序调用默认的asp.net HttpHandler

时间:2012-03-29 18:03:52

标签: asp.net routing httphandler httpcontext

我正在将ASP.NET路由添加到较旧的webforms应用程序中。我正在使用自定义HttpHandler来处理所有内容。在某些情况下,我想将特定路径映射回aspx文件,因此我需要将控制权传递回asp.net的默认HttpHandler。

我最接近的是这个

public void ProcessRequest(HttpContext context) {
    // .. when we decide to pass it on

    var handler = new System.Web.UI.Page();
    handler.ProcessRequest(context);

    MemoryStream steam = new MemoryStream();
    StreamWriter writer = new StreamWriter(stream);
    HtmlTextWriter htmlWriter = new HtmlTextWriter(writer);
    handler.RenderControl(htmlWriter);


    // write headers, etc. & send stream to Response
}

它没有做任何事情,流没有任何输出。 MS的System.Web.UI.Page文档(作为IHttpHandler)说“不要调用ProcessRequest方法。它是供内部使用的”。

从环顾四周看起来你可以用MVC做到这一点,例如:MvcHttpHandler doesn't seem to implement IHttpHandler

还有这个东西System.Web.UI.PageHandlerFactory似乎只会为aspx文件生成一个Page处理程序,但它是内部的,我不能直接使用它。

此页面:http://msdn.microsoft.com/en-us/library/bb398986.aspx指的是“默认的asp.net处理程序”,但不识别类或给出任何可能如何使用它的指示。

关于我如何做到这一点的任何想法?有可能吗?

3 个答案:

答案 0 :(得分:7)

持久性得到回报!这实际上是有效的,因为这些信息似乎几乎无处可用,我以为我会回答我自己的问题。感谢Robert关于使用内部构造函数实例化的这篇文章,这是关键。

http://www.rvenables.com/2009/08/instantiating-classes-with-internal-constructors/

public void ProcessRequest(HttpContext context) {
    // the internal constructor doesn't do anything but prevent you from instantiating
    // the factory, so we can skip it.
    PageHandlerFactory factory =
        (PageHandlerFactory)System.Runtime.Serialization.FormatterServices
        .GetUninitializedObject(typeof(System.Web.UI.PageHandlerFactory));

     string newTarget  = "default.aspx"; 
     string newQueryString = // whatever you want
     string oldQueryString = context.Request.QueryString.ToString();
     string queryString = newQueryString + oldQueryString!="" ? 
         "&" + newQueryString :
         "";

     // the 3rd parameter must be just the file name.
     // the 4th parameter should be the physical path to the file, though it also
     //   works fine if you pass an empty string - perhaps that's only to override
     //   the usual presentation based on the path?

     var handler = factory.GetHandler(context, "GET",newTarget,
         context.Request.MapPath(context,newTarget));

     // Update the context object as it should appear to your page/app, and
     // assign your new handler.

     context.RewritePath(newTarget  , "", queryString);
     context.Handler = handler;

     // .. and done

     handler.ProcessRequest(context);
}

...和一些小奇迹一样,aspx页面处理&完全呈现,无需重定向。

我希望这只能在IIS7中使用。

答案 1 :(得分:1)

我是你在webforms中使用Routing你应该只能为你想要的特定.aspx文件添加一个忽略路由。然后由默认的HttpHandler处理。

http://msdn.microsoft.com/en-us/library/dd505203.aspx

答案 2 :(得分:0)

另一种选择是通过处理不希望返回默认响应并将其他响应重新映射到您自己的IHttpHandler的情况来反转逻辑。每当myCondition为false时,响应将是"默认"。该交换机实现为IHttpModule:

public class SwitchModule: IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.PostAuthenticateRequest += app_PostAuthenticateRequest;
    }

    void app_PostAuthenticateRequest(object sender, EventArgs e)
    {
        // Check for whatever condition you like           
        if (true)
            HttpContext.Current.RemapHandler(new CustomHandler());

    }

    public void Dispose()        
}

internal class CustomHandler: IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        context.Response.Write("hallo");
    }

    public bool IsReusable { get; }
}