我有一个ASP MVC页面,当会话过期时需要重定向到登录页面 . 如果用户在页面中并且会话到期并且用户刷新页面,则用户被重定向到登录页面 . 但是,如果用户单击按钮,则页面永远不会重定向到登录页面 . 我在每个控制器操作方法中都有一个自定义ActionFilter来检查会话,我使用'RedirectToRouteResult'对象来重定向页面,但是只有当用户刷新页面而不是单击按钮时它才会起作用 .
这是我的自定义操作过滤器:
public class CustomCheckSessionOutAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
string actionName = filterContext.ActionDescriptor.ActionName.ToLower().Trim();
//Check Start with
if (!actionName.StartsWith("Login") && !actionName.StartsWith("LogOff"))
{
var session = HttpContext.Current.Session["LoggedInUserInfo"];
//Redirects user to login screen if session has timed out
if (session == null)
{
base.OnActionExecuting(filterContext);
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new
{
controller = "Account",
action = "Login",
returnUrl = ((HttpRequestWrapper)((HttpContextWrapper)filterContext.HttpContext).Request).Url
}));
}
}
}
}
以下是Controller中的操作方法示例:
[Authorize(Roles = "Client")]
[CustomCheckSessionOut]
public ActionResult GetOrders([DataSourceRequest] DataSourceRequest request, string orderId)
{
}
如果会话过期并且点击按钮,我有什么建议如何将用户重定向到登录页面?谢谢 .
UPDATE: 感谢Fabien,我用他的方法让它像这样解决:
Global.asax.cs
protected void Application_EndRequest()
{
var context = new HttpContextWrapper(Context);
// If we're an ajax request, and doing a 302, then we actually need to do a 401
if (Context.Response.StatusCode == 302 && context.Request.IsAjaxRequest())
{
Context.Response.Clear();
Context.Response.StatusCode = 401;
Context.Response.StatusDescription = "expiredSession";
}
}
Javascript:
$(document).ajaxComplete(function (e, xhr, options) {
if (xhr != null) {
if (xhr.getResponseHeader('X-Responded-JSON') != null) {
var responseHeader = jQuery.parseJSON(xhr.getResponseHeader('X-Responded-JSON'));
if (responseHeader.status === 401) {
e.stopPropagation();
window.location.href = responseHeader.headers.location;
}
}
if (xhr.status === 401 && xhr.statusText === "expiredSession") {
// Prevents the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the event
e.stopPropagation();
location.reload();
}
}
});
1 回答
看起来你的控制器动作是由Kendo组件使用AJAX调用的 . 您无法从AJAX调用重定向页面 . 您可以返回一个HttpUnauthorizedResult而不是返回RedirectToRouteResult,在客户端使用javascript调用捕获它,如果状态代码为401 - Unauthorized,则触发页面重定向到您的登录操作 .
您可以像这样更新自定义操作过滤器以处理这两种情况:
编辑1:
Kendo网格使用DataSource组件从远程源读取数据,它有一个名为“Error”的事件,您可以使用该事件来捕获您的401 - Session过期错误 .
剃刀代码:
Javascript代码:
如果要在窗口小部件启动后绑定到错误事件,可以这样做:
Javascript代码:
您可以替换"Session expired"错误消息以更好地满足您的需求,只是不要忘记更换javascript代码中的检查,已在documentation上显示 .
编辑2:
您可以使用jQuery 1.0和更高版本在应用程序范围内执行此操作,将此代码段添加到每个页面上加载的javascript文件中(在_Layout.cshtml中):
我已更新动作过滤器和kendo javascript代码,以更优雅的方式设置重定向位置 .