Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

URL rewrite in OWIN middleware

I have a problem with URL rewriting which works in Global.asax but not in OWIN middleware.

Global.asax code

protected void Application_BeginRequest()
{
    //Perfectly working rewrite. 
    //By route rules, this resolves to the action Global()
    //of the HomeController
    HttpContext.Current.RewritePath("Home/Global");
}

OWIN middleware code (used for culture detection, code shortened for brevity)

public class GlobalizationMiddleware : OwinMiddleware
{
    public GlobalizationMiddleware(OwinMiddleware next)
        : base(next)
    { }

    public async override Task Invoke(IOwinContext context)
    {
        context.Request.Path = new PathString("/Home/Global");
        await Next.Invoke(context);
    }
}

I expect that "Global" action of the controller "Home" gets called...but instead, the default action "Index" is called.

After the Path is changed context.Request.Uri.AbsoluteUri is http://localhost/Global/Home

But Controller's Request.Url.AbsoluteUri is still http://localhost

I even tried context.Environment["owin.RequestPath"] = "/Home/Global"; but that doesn's seem to work either.

Before anyone asks, yes, I call the IAppBuilder.Use(typeof(GlobalizationMiddleware)) in Startup.cs and the debugger enters the Invoke method.

What am I doing wrong?

EDIT

I even tried referencing System.Web and then doing this...doesn't work either :(

System.Web.Routing.RequestContext requestContext = context.Environment["System.Web.Routing.RequestContext"] as System.Web.Routing.RequestContext;
requestContext.HttpContext.RewritePath("/Home/Global");

System.Web.HttpContextBase contextBase = context.Environment["System.Web.HttpContextBase"] as System.Web.HttpContextBase;
contextBase.RewritePath("/Home/Global");

EDIT 2 - Found a working solution (see below) but I'm unsure whether it's the right solution, comments would be appreciated :)

like image 348
Mirek Avatar asked Jan 31 '15 13:01

Mirek


1 Answers

I found a working solution.

Unfortunately, I needed to include System.Web. I'm directly altering the RouteData object in the RequestContext.

System.Web.Routing.RequestContext requestContext = context.Environment["System.Web.Routing.RequestContext"] as System.Web.Routing.RequestContext;
requestContext.HttpContext.RewritePath("Home/Global");
requestContext.RouteData.Values["action"] = "Global";

But this feels too hacky to my tastes... I'm not sure if this is the right solution so I won't accept this as the valid answer, maybe someone will come with a better solution.

like image 83
Mirek Avatar answered Nov 08 '22 08:11

Mirek