views:

394

answers:

2

Hi

I have a site where part is webforms (Umbraco CMS) and part is MVC This is the HttpHandler to deal with the MVC functionality:

public class Mvc : MvcHttpHandler
{
    protected override void ProcessRequest(HttpContext httpContext)
    {
        httpContext.Trace.Write("Mvc.ashx", "Begin ProcessRequest");
        string originalPath = httpContext.Request.Path;
        string newPath = httpContext.Request.QueryString["mvcRoute"];
        if (string.IsNullOrEmpty(newPath))
            newPath = "/";

        httpContext.Trace.Write("Mvc.ashx", "newPath = "+newPath );

        HttpContext.Current.RewritePath(newPath, false);
        base.ProcessRequest(HttpContext.Current);
        HttpContext.Current.RewritePath(originalPath, false);
        }
}

Full details of how this is implemented here This method works well in an MVC 1.0 website. However when I upgrade this site to MVC 2.0 following the steps in Microsoft's upgrade documentation; everything compiles, except at runtime I get this exception:

Server Error in '/' Application.
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.

Requested URL: /mvc.ashx

Version Information: Microsoft .NET Framework Version:2.0.50727.4927; ASP.NET Version:2.0.50727.4927

This resource and it's dependencies are found fine in MVC 1.0 but not in MVC 2.0, is there an extra dependency I'd need to add? Is there something I'm missing? Is there a change in the way MVC 2.0 works?

+2  A: 

A word of caution - the MvcHandler and MvcHttpHandler types are not meant to be subclassed by user code. These handlers will change with future versions of the framework, so any types which subclass them are subject to breaking. With that in mind..

In MVC 2, the MvcHttpHandler type is an IHttpAsyncHandler, not just an IHttpHandler. This changes the semantic of how ASP.NET executes the handler. If you subclass the MvcHttpHandler, you need to override the BeginProcessRequest and EndProcessRequest methods in addition to the ProcessRequest method.

A safer mechanism would be to wrap the MvcHttpHandler instead of subclassing it. That is, make your own IHttpHandler whose ProcessRequest() method just delegates to new MvcHttpHandler.ProcessRequest(). This way, changes to the working of MvcHttpHandler shouldn't cause your wrapping handler to break.

Levi
Note: the 'safer mechanism' does not work because ProcessRequest() is protected.
Myster
Cast it to an IHttpHandler, then call the explicit method IHttpHandler.ProcessRequest().
Levi
how would you do that? i did this but still have the same result IHttpHandler ihh = (IHttpHandler)(new MvcHttpHandler());ihh.ProcessRequest(HttpContext.Current);this however still returns the no resource found. i have a HomeController and a views for Home Home.aspx/Index Home.aspx/Aboutso mvc.ashx?mvcRoute=/home.aspx should work
Sander
+1  A: 

This is what I did and it works...

public class mvc : IHttpHandler, System.Web.SessionState.IRequiresSessionState
{

    public bool IsReusable
    {
        get { return true; }
    }

    public void ProcessRequest(HttpContext httpContext)
    {
        string originalPath = httpContext.Request.Path;
        HttpContext.Current.RewritePath(httpContext.Request.ApplicationPath, false);
        IHttpHandler httpHandler = new MvcHttpHandler();
        httpHandler.ProcessRequest(HttpContext.Current);
        HttpContext.Current.RewritePath(originalPath, false);
    }

}
Bill
Nice, this example shows how to create it as Levi describes.
Myster