处理ajax调用中的会话超时
我正在使用 jquery 对 asp.net mvc 控制器操作进行 ajax 调用:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult GetWeek(string startDay)
{
var daysOfWeek = CompanyUtility.GetWeek(User.Company.Id, startDay);
return Json(daysOfWeek);
}
当会话超时时,此调用将失败,因为 User 对象存储在会话中。我创建了一个自定义授权属性,以检查会话是否丢失并重定向到登录页面。这适用于页面请求,但不适用于 ajax 请求,因为您无法从 ajax 请求重定向:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AuthorizeUserAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (!httpContext.Request.IsAjaxRequest())
{//validate http request.
if (!httpContext.Request.IsAuthenticated
|| httpContext.Session["User"] == null)
{
FormsAuthentication.SignOut();
httpContext.Response.Redirect("~/?returnurl=" + httpContext.Request.Url.ToString());
return false;
}
}
return true;
}
}
我在另一个线程上读到,当用户未经身份验证并且您发出 ajax 请求时,您应该将状态码设置为401(未经授权),然后在js中检查并重定向到登录页面。但是,我无法使其正常工作:
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (Request.IsAjaxRequest() && (!Request.IsAuthenticated || User == null))
{
filterContext.RequestContext.HttpContext.Response.StatusCode = 401;
}
else
{
base.OnActionExecuting(filterContext);
}
}
基本上,它会将其设置为 401,但随后它将继续进入控制器操作并抛出一个未设置为对象实例的对象引用错误,然后返回错误 500回到客户端js。如果我更改自定义 Authorize 属性来验证 ajax 请求,并为未经过身份验证的请求返回 false,这会使 ajax 请求返回我的登录页面,这显然不起作用。
我该如何让它发挥作用?
I'm making an ajax call using jquery to an asp.net mvc controller action:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult GetWeek(string startDay)
{
var daysOfWeek = CompanyUtility.GetWeek(User.Company.Id, startDay);
return Json(daysOfWeek);
}
When session times out, this call will fail, as the User object is stored in session. I created a custom authorize attribute in order to check if session was lost and redirect to the login page. This works fine for page requests, however it doesn't work for ajax requests, as you can't redirect from an ajax request:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AuthorizeUserAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (!httpContext.Request.IsAjaxRequest())
{//validate http request.
if (!httpContext.Request.IsAuthenticated
|| httpContext.Session["User"] == null)
{
FormsAuthentication.SignOut();
httpContext.Response.Redirect("~/?returnurl=" + httpContext.Request.Url.ToString());
return false;
}
}
return true;
}
}
I read on another thread that when the user isn't authenticated and you make an ajax request, you should set the status code to 401 (unauthorized) and then check for that in js and redirect them to the login page. However, I can't get this working:
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (Request.IsAjaxRequest() && (!Request.IsAuthenticated || User == null))
{
filterContext.RequestContext.HttpContext.Response.StatusCode = 401;
}
else
{
base.OnActionExecuting(filterContext);
}
}
Basically, it'll set it to 401, but then it'll continue into the controller action and throw an object ref not set to an instance of an object error, which then returns error 500 back to the client-side js. If I change my custom Authorize attribute to validate ajax requests as well and return false for those that aren't authenticated, that makes the ajax request return my login page, which obviously doesn't work.
How do I get this working?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
您可以编写一个自定义
[Authorize]
属性,该属性将返回 JSON,而不是在未经授权的访问时抛出 401 异常,这将允许客户端脚本优雅地处理该场景:然后用它装饰您的控制器/操作并在客户端上:
You could write a custom
[Authorize]
attribute which would return JSON instead of throwing a 401 exception in case of unauthorized access which would allow client scripts to handle the scenario gracefully:then decorate your controller/actions with it and on the client:
我不会将 JsonRequestBehavior 更改为 AllowGet。相反,我建议:
并添加全局 js ajax 错误处理程序:
I wouldn't change JsonRequestBehavior to AllowGet. Instead I suggest:
and add global js ajax errors handler:
尽管这个答案早已过去,但我认为如果您使用 .NET 4.5,这是最短、最甜蜜的答案。添加了名为 SuppressFormsAuthenticationRedirect 的小属性。设置为true,则不会执行302重定向到登录页面。
http://msdn.microsoft.com/en-us/library/system。 web.httpresponse.suppressformsauthenticationredirect.aspx
假设您计划处理 ajax 请求失败/错误回调,您将收到 401 Unauthorized。
Even though this is well past answered, I think this is the shortest and sweetest answer if you are using .NET 4.5. Little property called SuppressFormsAuthenticationRedirect which was added. Set to true and it will not perform the 302 Redirect to login page.
http://msdn.microsoft.com/en-us/library/system.web.httpresponse.suppressformsauthenticationredirect.aspx
Assuming you plan on handling the ajax requests fail/error callback, in which you will get a 401 Unauthorized.
在母版页上添加这个jquery脚本 ------------
在项目中添加一个以TraceFilter命名的cs文件,并编写一个继承于ActionFilterAttribute的密封类TraceFilterAttribute。
通过编写以下行,在项目的 App_Start 文件夹中可用的 FilterConfig.cs 中添加 TraceFilterAttribute 类。
过滤器.Add(new TraceFilterAttribute());
重写 TraceFilterAttribute 类中的 OnActionExecuting() 方法。这将自动检查会话,如果发现会话为空,则调用母版页中可用的脚本,您可以从它们转到您选择的页面。
On Master page add this jquery script ------------
Add a cs file named with TraceFilter in your project and write a seald class TraceFilterAttribute inheriting to ActionFilterAttribute.
Add TraceFilterAttribute class in FilterConfig.cs available in App_Start folder of your project by writing below line.
filters.Add(new TraceFilterAttribute());
Override method OnActionExecuting() in TraceFilterAttribute class. This will automatically check session and if finds session null then calls script available in master page and from their you can go to your choice page.
我遇到了类似的问题,发现 this
而不是返回任何 JSON,就在之前响应被发回,强制 ASP.NET 返回 401 代码。在
Global.asax
中:然后你可以让客户端用 JavaScript/jQuery 或你正在使用的任何东西来处理它
I was having a similar issue and found this
Instead of returning any JSON, just before the response is sent back, force ASP.NET to return a 401 code. In
Global.asax
:Then you can let the client deal with it in JavaScript/jQuery or whatever you are using
这是我在自定义授权中以如此简单的方式处理此问题的方法,我检查会话是否已退出,并使用布尔值将其处理为未授权,以检查它是否确实经过身份验证但未授权(重定向到未经授权的页面)或者由于会话超时而未经过身份验证(重定向到登录)
希望这是否可以指导某人,如果有评论,我们很高兴了解他们。
here is how I handle this in so simple way in my custom authorization , I check if session is out and handle this as un-authorized with a boolean to check if it is really authenticated but not authorized (to redirect to un-authorized page) or it is not authenticated due to session time out ( redirect to Login)
Hope if this guides someone and please if there're comments its appreciated to know them though.
您可能想尝试抛出 HttpException 并在 JavaScript 中捕获它。
You might want to try to throw HttpException and catch it in your javascript.
在 ajax 调用中,如果会话过期,则返回类似这样的内容
哈哈...
on ajax call if session expired return something like this
haha...