我有兩個問題在這裏,第二個是無關緊要,如果第一個得到答案,但仍然技術上有趣的我認爲...我會嘗試要儘可能明確:虛假MVC Server.Transfer:Response.End()不會結束我的線程
- 1問題:我的目標就是假一Server.Transfer的MVC中,沒有任何血統的方式來做到這一點,我發現了好幾篇文章吧,但多數地方約重定向/重新路由,這在我的情況下是不可能的(至少不是我能想到的)。
這裏是上下文,我們有兩個版本的我們的網站,一個「桌面」和一個移動的。我們的營銷人員希望兩個版本的主頁在同一個網址上投放(因爲SEO專家這麼說)。
這聽起來微不足道,很簡單,除了...我們的桌面網站是一個.NET 4.0 ASPX網站,我們的移動網站是MVC,它們都運行在同一個網站(同一個項目,相同的應用程序,相同的應用程序)。
因爲桌面版本代表我們流量的95%左右,所以這應該是默認設置,並且我們希望只有當用戶在移動設備上時,才能從後面的ASPX代碼「轉移」(因此具有相同的url)設備或真的想看到移動版本。據我目前所見,沒有簡單的方法來做到這一點(Server.Transfer只執行一個新的處理程序 - 因此,如果有一個物理文件的頁面)。因此,迄今爲止,問題是否有人以適當的方式做到了這一點?
而且這是我帶來:
- 第二個問題:我沒有建立自己轉移到MVC機制,但後來想通了,一到Response.End()實際上並沒有結束正在運行的線程了,不是任何人都知道爲什麼?
很顯然,我不希望任何回答出藍色的,所以這裏是我在做什麼:
在網頁這就需要transfering移動,我做這樣的事情:
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);
}
和我通過RedirectToMobileIfRequired稱爲實際TransferToMobile方法(我跳過,因爲它是相當無關緊要的檢測機構)的樣子:
/// <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 = 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
}
在這一點上,我希望Response.End()調用也可以結束該線程(如果我跳過整個控制器執行位的僞裝,它會這樣做),但它不會。
因此,我懷疑要麼是我僞造的上下文(是我發現能夠使用新url傳遞當前上下文的唯一方式),要麼是控制器阻止線程被終止。
fakeContext.Response和CurrentContext.Response是一樣的,少數嘗試結束假上下文的響應或者殺死線程並不能真正幫助我。 (Response.End())實際上不會呈現給客戶端(這是一個小勝利),因爲響應流(和連接,客戶端中沒有「無限加載」)是正在關閉。但是代碼仍在運行,這並不好(當然,在編寫ASPX頁面,編寫頭文件等時也會產生大量錯誤)。
因此,任何新的領導將超過歡迎!
總結一下: - 有沒有人有一個更簡單的方法來實現共享一個ASPX頁面和MVC視圖在同一個網址? - 如果沒有,是否有人知道我如何確保我的迴應真的結束?
非常感謝提前!
的「搜索引擎優化專家」之稱的最常見和globaly接受partern運行一個網站的移動版本不一件好事?真棒! – Pluc
+1;內容;諷刺+1 + – tsemer
@Pluc:的確,在這裏給了我意見,SEO專家是比較貴的,他贏了:)。但無論如何,不幸的是,在我的情況下並不是每一個都有幫助(除非你作爲SEO專家的服務收取更多費用)。 Thx說明明顯不過:)。 –