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传递