mvc3中正确处理ajax访问需要登录的页面

mvc3中有Ajax.ActionLink和Ajax.BeginForm两个方法用来生成ajax的连接和ajax的表单提交。

但是当要访问的连接是一个需要登录的页面,显示时就不太友好了

我简单模拟了一下来说明这个问题

image

页面中有3个连接,第一个是退出登录,第二是普通连接方式显示一个需要登录的页面,第三个是ajax方式,页面的内容将会在下面显示

@Ajax.ActionLink("ajax show a page need login", "needlogin", new AjaxOptions { UpdateTargetId="container" })
<div id="container"></div>

在未登录的情况下,点击普通方式的连接,跳转到

image 登录页

点击ajax方式,并不是调转到登陆页去登陆,而是登陆页在下面显示了

image

当你的登录页是一个比较复杂的页面时,他整个加到了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之后效果如下

image

注意浏览器并没有后退按钮,说明他是js调转的

image 登陆后点击则正常显示,在下面读取了页面的内容并显示

 

观察普通连接的未登录调转和ajax的未登录跳转我们发现,普通的登录的会多一个参数 ReturnUrl 通过这个参数,我们可以在登录时返回到之前的页面

但对于ajax连接来说,我们不应该返回被请求的/home/needlogin页,而是应该返回调用此页的主页面/home/index页。

如何获取到这个页面呢

 

image

查看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 });

image

再来看发起的ajax请求,就通过参数附带了当前页面地址信息

如此,我们可以在程序中获取此参数然后构造ResultUrl 参数信息了

 

注意当使用Ajax.BeginForm时,此参数是post过去的,而Ajax.ActionLink则是get传递

posted @ 2012-01-16 11:59  czcz1024  阅读(5253)  评论(0编辑  收藏  举报