Tratamento do tempo limite da sessão em chamadas ajax
Estou fazendo uma chamada ajax usando jquery para uma ação do controlador asp.net mvc:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult GetWeek(string startDay)
{
var daysOfWeek = CompanyUtility.GetWeek(User.Company.Id, startDay);
return Json(daysOfWeek);
}
Quando o tempo limite da sessão expirar, esta chamada falhará, pois o objeto Usuário é armazenado na sessão. Criei um atributo de autorização personalizado para verificar se a sessão foi perdida e redirecionar para a página de login. Isso funciona bem para solicitações de página, no entanto, não funciona para solicitações de ajax, pois você não pode redirecionar de uma solicitação de 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;
}
}
Li em outro tópico que, quando o usuário não estiver autenticado e você fizer uma solicitação ajax, defina o código de status como 401 (não autorizado), verifique o js e redirecione-o para a página de login. No entanto, não consigo fazer isso funcionar:
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (Request.IsAjaxRequest() && (!Request.IsAuthenticated || User == null))
{
filterContext.RequestContext.HttpContext.Response.StatusCode = 401;
}
else
{
base.OnActionExecuting(filterContext);
}
}
Basicamente, ele será definido como 401, mas continuará na ação do controlador e lançará um ref de objeto não definido para uma instância de um erro de objeto, que retornará o erro 500 de volta aos js do lado do cliente. Se eu alterar meu atributo personalizado Authorize para validar solicitações ajax e retornar false para aqueles que não são autenticados, isso fará com que a solicitação ajax retorne minha página de logon, o que obviamente não funciona.
Como faço para isso funcionar?