views:

180

answers:

1

I am currently trying to add 301 redirect to my routes in MVC

to do this I have tried to inherit from the MvcHandler. The handler gets instantited with the right values. but I am never able to debug the overridden methods.

can someone show me a working attempt at this? the asp.net pipe simply seems to the doing its own thing...

public class CodeHttpHandler : MvcHandler
{
    public CodeHttpHandler(RequestContext p_requestContext)
            : base(p_requestContext)
    {
    }
    protected override void ProcessRequest(HttpContext p_httpContext)
    {
    }
    protected override void ProcessRequest(HttpContextBase p_httpContext)
    {
    }
}

Update:

This is the solutions I found so far:

public class CodeRouteHandler : IRouteHandler
{
    public System.Web.IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        return new CodeHandler(requestContext);
    }
}

public class CodeRouteConstants
{
    public const string CODE = "code";
    public const string REDIRECT = "Redirect";
}

public class CodeHandler : MvcHandler
{
    public CodeHandler(RequestContext requestContext)
        : base(requestContext)
    {
    }

    private int? HandleCodedRoute(System.Web.HttpContextBase httpContext)
    {
        var context = httpContext.Request.RequestContext.RouteData;
        if (context.DataTokens.ContainsKey(CodeRouteConstants.CODE))
        {
            var statusCode = Int32.Parse(context.DataTokens[CodeRouteConstants.CODE] as string ?? "500");

            httpContext.Response.StatusCode = statusCode;

            if (context.DataTokens.ContainsKey(CodeRouteConstants.REDIRECT))
            {
                var redirectionMap = context.DataTokens[CodeRouteConstants.REDIRECT] as string ?? "404";

                foreach (var v in context.Values)
                {
                    redirectionMap = redirectionMap.Replace(string.Format("{{{0}}}", v.Key), v.Value as string);
                }

                httpContext.Response.AddHeader("Location", redirectionMap);
            }

            httpContext.Response.End();
            return statusCode;
        }
        return null;
    }

    protected override System.IAsyncResult BeginProcessRequest(System.Web.HttpContext httpContext, System.AsyncCallback callback, object state)
    {
        var statusCode = HandleCodedRoute(new HttpContextWrapper(httpContext));
        if (statusCode.HasValue)
        {
            return null;
        }
        return base.BeginProcessRequest(httpContext, callback, state);
    }

    protected override System.IAsyncResult BeginProcessRequest(System.Web.HttpContextBase httpContext, System.AsyncCallback callback, object state)
    {
        return base.BeginProcessRequest(httpContext, callback, state);
    }

    protected override void ProcessRequest(System.Web.HttpContext httpContext)
    {
        base.ProcessRequest(httpContext);
    }
    protected override void ProcessRequest(System.Web.HttpContextBase httpContext)
    {
        base.ProcessRequest(httpContext);
    }
}
A: 

Hey, I also just ran into this problem. My breakpoints in ProcessRequest() were never being hit. I don't have a full-proof resolution to your problem, but I do have a work-around which might get you what you want. Try overriding the BeginProcessRequest() method from MvcHandler instead of ProcessRequest(). The Context should contain the route (action and controller) information if that's what you're looking for.

Chris Woolner
well< I validated that I did get the right information in the constructor. everything is there, and that being said, I get the right handler sent back. but my logic simply never gets called, i get default behavior and not what I coded.this has me baffled
Alexandre Brisebois
I have a problem with the Async modeli currently get the "Cannot redirect after HTTP headers have been sent." error.have you overcome this?
Alexandre Brisebois