mvc3中有Ajax.ActionLink和Ajax.BeginForm兩個方法用來生成ajax的連接和ajax的表單提交。
但是當要訪問的連接是一個需要登錄的頁面,顯示時就不太友好了
我簡單模擬了一下來說明這個問題
頁面中有3個連接,第一個是退出登錄,第二是普通連接方式顯示一個需要登錄的頁面,第三個是ajax方式,頁面的內容將會在下面顯示
@Ajax.ActionLink("ajax show a page need login", "needlogin", new AjaxOptions { UpdateTargetId="container" }) <div id="container"></div>
在未登錄的情況下,點擊普通方式的連接,跳轉到
點擊ajax方式,並不是調轉到登陸頁去登陸,而是登陸頁在下面顯示了
當你的登錄頁是一個比較復雜的頁面時,他整個加到了container div中,這就很惡心了
ajax連接,希望整個頁面跳轉,只能用javascript來跳轉了
為此,我們需要寫一個自己的驗證filter
public class MyAuthAttribute : AuthorizeAttribute { protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { if (filterContext.HttpContext.Request.IsAjaxRequest()) { filterContext.Result = new AjaxUnauthorizedResult(); return; } base.HandleUnauthorizedRequest(filterContext); } }
其中AjaxUnauthorizedResult是自己定義的類
public class AjaxUnauthorizedResult : JavaScriptResult { public AjaxUnauthorizedResult() { var loginurl = FormsAuthentication.LoginUrl; this.Script = "location.href='" + loginurl + "'"; } }
他繼承了JavaScriptResult類,用於返回
使用了自己定義的filter之后效果如下
注意瀏覽器並沒有后退按鈕,說明他是js調轉的
觀察普通連接的未登錄調轉和ajax的未登錄跳轉我們發現,普通的登錄的會多一個參數 ReturnUrl 通過這個參數,我們可以在登錄時返回到之前的頁面
但對於ajax連接來說,我們不應該返回被請求的/home/needlogin頁,而是應該返回調用此頁的主頁面/home/index頁。
如何獲取到這個頁面呢
查看ajax發起的請求,發現,他在地址上加了X-Requested-With參數,以說明此請求是一個ajax請求,說以在代碼中才能用Request.IsAjaxRequest()來判斷,我們可以仿照此處來加上發起ajax請求的主頁面地址
找到 jquery.unobtrusive-ajax.js 101行
options.data.push({ name: "X-Requested-With", value: "XMLHttpRequest" });
在下面加一句
options.data.push({ name: "X-Requested-From", value: location.href });
再來看發起的ajax請求,就通過參數附帶了當前頁面地址信息
如此,我們可以在程序中獲取此參數然后構造ResultUrl 參數信息了
注意當使用Ajax.BeginForm時,此參數是post過去的,而Ajax.ActionLink則是get傳遞