Faking MVC Server.Transfer: Response.End() does not end my thread

rldowling03

New Member
I have two issues here, the second one is irrelevant if the first one got answered, but still technically interesting in my opinion... I will try to be as clear as possible:
  • 1st question: my goal is to fake a Server.Transfer in MVC, is there any descent way to do that, I found quite a few articles about it, but most where about redirecting / rerouting, which is not possible in my case (not that I can think of at least).
Here is the context, we have two versions of our website, a "desktop" one and a mobile one. Our marketing guy wants both versions of the home page to be served on the same url (because the SEO expert said so). This sounds trivial and simple, and it kind of is in most cases, except... Our desktop site is a .NET 4.0 ASPX site, and our mobile site is MVC, both run in the same site (same project, same apppool, same app). Because the desktop version represents about 95% of our traffic, this should be the default, and we want to "transfer" (hence same url) from the ASPX code behind to the MVC view only if user is on a mobile device or really wants to see the mobile version. As far as I saw so far, there is no easy way to do that (Server.Transfer only executes a new handler - hence page - if there is a physical file for it). Hence question has any one done that in a proper way so far? And which brings me to:
  • 2nd question: I did build my own transfer to MVC mechanism, but then figured out that a Response.End() does not actually ends the running thread anymore, does anyone have a clue why?
Obviously, I don't expect any answer out of the blue, so here is what I am doing:in the page(s) which needs transfering to mobile, I do something like:\[code\]protected override void OnPreInit(EventArgs e) { base.OnPreInit(e); MobileUri = "/auto/intro/index"; // the MVC url to transfer to //Identifies correct flow based on certain conditions 1-Desktop 2-Mobile BrowserCheck.RedirectToMobileIfRequired(MobileUri);}\[/code\]and my actual TransferToMobile method called by RedirectToMobileIfRequired (I skipped the detection part as it is quite irrelevant) looks like:\[code\]/// <summary>/// Does a transfer to the mobile (MVC) action. While keeping the same url./// </summary>private static void TransferToMobile(string uri) { var cUrl = HttpContext.Current.Request.Url; // build an absolute url from relative uri passed as parameter string url = String.Format("{0}://{1}/{2}", cUrl.Scheme, cUrl.Authority, uri.TrimStart('/')); // fake a context for the mvc redirect (in order to read the routeData). var fakeContext = new HttpContextWrapper(new HttpContext(new HttpRequest("", url, ""), HttpContext.Current.Response)); var routeData = http://stackoverflow.com/questions/12618996/RouteTable.Routes.GetRouteData(fakeContext); // get the proper controller IController ctrl = ControllerBuilder.Current.GetControllerFactory().CreateController(fakeContext.Request.RequestContext, (string)routeData.Values["controller"]); // We still need to set routeData in the request context, as execute does not seem to use the passed route data. HttpContext.Current.Request.RequestContext.RouteData.DataTokens["Area"] = routeData.DataTokens["Area"]; HttpContext.Current.Request.RequestContext.RouteData.Values["controller"] = routeData.Values["controller"]; HttpContext.Current.Request.RequestContext.RouteData.Values["action"] = routeData.Values["action"]; // Execute the MVC controller action ctrl.Execute(new RequestContext(new HttpContextWrapper(HttpContext.Current), routeData)); if (ctrl is IDisposable) { ((IDisposable)ctrl).Dispose(); // does not help } // end the request. HttpContext.Current.Response.End(); // fakeContext.Response.End(); // does not add anything // HttpContext.Current.Response.Close(); // does not help // fakeContext.Response.Close(); // does not help // Thread.CurrentThread.Abort(); // causes infinite loading in FF}\[/code\]At this point, I would expect the Response.End() call to end the thread as well (and it does if I skip the whole faking the controller execution bit) but it doesn't.I therefore suspect that either my faked context (was the only way I found to be able to passed my current context with a new url) or the controller prevents the thread to be killed.fakeContext.Response is same as CurrentContext.Response, and the few attempts at ending the fake context's response or killing the thread didn't really help me.Whatever code is running after the Response.End() will NOT actually be rendered to the client (which is a small victory), as the Response stream (and the connection, no "infinite loading" in the client) is being closed. But code is still running and that is no good (also obviously generates loads of errors when trying to write the ASPX page, write headers, etc.).So any new lead would be more than welcome!To sum it up: - does anyone have a less hacky way to achieve sharing a ASPX page and a MVC view on the same url?- if not, does anyone have a clue how I can ensure that my Response is really being ended?Many thinks in advance!
 
Back
Top