El resultado de la llamada AJAX todavía es probable que terminan apareciendo con éxito (aunque, no se preocupe, no será realmente ejecutar su método de acción), y invoque su controlador success
. Esto se debe a que esperas HTML, y eso es lo que estás recibiendo (aunque es probable que el HTML resultante sea tu página de inicio de sesión y no el HTML que deseas). Por otro lado, si esperaba JSON (usando dataType:'JSON'
), desencadenaría un error, ya que estaría analizando HTML como JSON.
Lo que debe hacer es evitar que FormsAuth redirija la página de inicio de sesión para las solicitudes AJAX. Ahora, AuthorizeAttribute
devuelve fielmente un NotAuthorizedResult
, que envía una respuesta HTTP 401 no autorizada al cliente, que es ideal para su cliente AJAX.
El problema es que el módulo FormsAuth comprueba el código de estado y si es 401, realiza la redirección. He combatido este problema de esta manera:
1) Crear mi propio tipo de derivado de AuthorizeAttribute
que coloca una bandera en HttpContext.Items
que me permita saber autorización falló, y yo debería obligar a un 401 en lugar de una redirección:
public class AjaxAuthorizeAttribute : AuthorizeAttribute
{
/// <summary>
/// Processes HTTP requests that fail authorization.
/// </summary>
/// <param name="filterContext">Encapsulates the information for using <see cref="T:System.Web.Mvc.AuthorizeAttribute"/>. The <paramref name="filterContext"/> object contains the controller, HTTP context, request context, action result, and route data.</param>
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest()) filterContext.HttpContext.Items["AjaxPermissionDenied"] = true;
base.HandleUnauthorizedRequest(filterContext);
}
}
2) Añadir a Global.asax.cs:
protected void Application_EndRequest(Object sender, EventArgs e)
{
if (Context.Items["AjaxPermissionDenied"] is bool)
{
Context.Response.StatusCode = 401;
Context.Response.End();
}
}
3) agregar un controlador statusCode a la configuración de jQuery AJAX:
$.ajaxSetup({
statusCode: {
401: function() {
window.location.href = "path/to/login";
}
}
});
4) Cambiar los controladores o acciones en las que desea este comportamiento usando AuthorizeAttribute
a AjaxAuthorizeAttribute
:
[AjaxAuthorize]
public string SaveEmployee(string Location, string dateApplied, string Status, string mailCheck, ...)
{
objEmpMain.FirstName = firstName;
objEmpMain.LastName = lastName;
objEmpMain.Initial = Initial;
objEmpMain.Address1 = Address;
...
...
...
}
En realidad, mi clase actual parece que sigue "public class EmployeeController: Controller". ¿Me dices que cambie como sigue "clase pública AjaxAuthorizeAttribute: AuthorizeAttribute" ???? –
Simplemente intercambie 'AuthorizeAttribute' por' AjaxAuthorizeAttribute' que decoró en sus controladores o acciones del controlador. Ver # 4 que acabo de agregar. – HackedByChinese
Disculpe, ¿puede explicarme dónde necesito crear la clase "public class AjaxAuthorizeAttribute: AuthorizeAttribute" ??? –