¿Cómo obtener una respuesta ASP.NET MVC Ajax para redirigir a una página nueva en lugar de insertar una vista en UpdateTargetId?

Estoy usando Ajax.BeginForm para crear un formulario que hará una devolución de datos ajax a una determinada acción del controlador y luego, si la acción es exitosa, el usuario debería ser redirigido a otra página (si la acción falla, se muestra un mensaje de estado usando AjaxOptions UpdateTargetId).

using (Ajax.BeginForm("Delete", null, new { userId = Model.UserId }, new AjaxOptions { UpdateTargetId = "UserForm", LoadingElementId = "DeletingDiv" }, new { name = "DeleteForm", id = "DeleteForm" })) { [HTML DELETE BUTTON] } 

Si la eliminación es exitosa, estoy devolviendo un resultado Redirigir:

 [Authorize] public ActionResult Delete(Int32 UserId) { UserRepository.DeleteUser(UserId); return Redirect(Url.Action("Index", "Home")); } 

Pero la vista Índice de controlador de inicio se está cargando en UpdateTargetId y, por lo tanto, termino con una página dentro de una página. Dos cosas en las que estoy pensando:

  1. O estoy diseñando esto mal y debería manejar este tipo de acción de manera diferente (no usando ajax).
  2. En lugar de devolver un resultado Redirigir, devuelve una vista que tiene javascript que hace la redirección en el lado del cliente.

¿Alguien tiene comentarios sobre el # 1? O si el # 2 es una buena solución, ¿cómo sería la “redirección de la vista de JavaScript”?

Puede usar JavascriptResult para lograr esto.

Para redirigir:

 return JavaScript("window.location = 'http://www.google.co.uk'"); 

Para volver a cargar la página actual:

 return JavaScript("location.reload(true)"); 

Parece la opción más simple.

Puede devolver un JSON con la URL y cambiar la ubicación de la ventana usando JavaScript en el lado del cliente. Prefiero esta manera que llamar a una función de JavaScript desde el servidor, que creo que está rompiendo la separación de las preocupaciones.

Lado del servidor:

 return Json(new {result = "Redirect", url = Url.Action("ActionName", "ControllerName")}); 

Lado del cliente:

 if (response.result == 'Redirect') window.location = response.url; 

Por supuesto, puede agregar más lógica porque podría haber un error en el lado del servidor y en ese caso la propiedad del resultado podría indicar esta situación y evitar la redirección.

El comportamiento que intentas producir no se hace mejor con AJAX. AJAX se usaría mejor si solo desea actualizar una parte de la página, no redirigir completamente a otra página. Eso derrota el propósito de AJAX en realidad.

Sugeriría que simplemente no use AJAX con el comportamiento que está describiendo.

Alternativamente, puede intentar usar jquery Ajax, que enviaría la solicitud y luego especificará una callback cuando la solicitud finalice. En la callback puede determinar si falló o si tuvo éxito, y redirigir a otra página si tiene éxito. He descubierto que jquery Ajax es mucho más fácil de usar, especialmente porque ya estoy usando la biblioteca para otras cosas.

Puede encontrar documentación sobre jquery ajax aquí , pero la syntax es la siguiente:

 jQuery.ajax( options ) jQuery.get( url, data, callback, type) jQuery.getJSON( url, data, callback ) jQuery.getScript( url, callback ) jQuery.post( url, data, callback, type) 

Si bien no es elegante, funciona para mí en ciertas situaciones.

Controlador

 if (RedirectToPage) return PartialView("JavascriptRedirect", new JavascriptRedirectModel("http://www.google.com")); else ... return regular ajax partialview 

Modelo

  public JavascriptRedirectModel(string location) { Location = location; } public string Location { get; set; } 

/Views/Shared/JavascriptRedirect.cshtml

 @model Models.Shared.JavascriptRedirectModel  

Usar JavaScript definitivamente hará el trabajo.

También puede usar Content si este es más su estilo.

Ejemplo:

Controlador MVC

 [HttpPost] public ActionResult AjaxMethod() { return Content(@"http://www.google.co.uk"); } 

Javascript

 $.ajax({ type: 'POST', url: '/AjaxMethod', success: function (redirect) { window.location = redirect; } }); 

Simplemente puede escribir en Ajax Success como se muestra a continuación:

  $.ajax({ type: "POST", url: '@Url.Action("GetUserList", "User")', data: { id: $("#UID").val() }, success: function (data) { window.location.href = '@Url.Action("Dashboard", "User")'; }, error: function () { $("#loader").fadeOut("slow"); } }); 

Necesitaba hacer esto porque tengo un formulario de inicio de sesión de Ajax. Cuando los usuarios inician sesión con éxito, me redirigen a una nueva página y finalizo la solicitud anterior porque la otra página maneja la redirección hacia la parte dependiente (porque es un sistema STS SSO).

Sin embargo, también quería que funcionara con JavaScript desactivado, que era el inicio de sesión central y todo, así que se me ocurrió esto,

  public static string EnsureUrlEndsWithSlash(string url) { if (string.IsNullOrEmpty(url)) throw new ArgumentNullException("url"); if (!url.EndsWith("/")) return string.Concat(url, "/"); return url; } public static string GetQueryStringFromArray(KeyValuePair[] values) { Dictionary dValues = new Dictionary(); foreach(var pair in values) dValues.Add(pair.Key, pair.Value); var array = (from key in dValues.Keys select string.Format("{0}={1}", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(dValues[key]))).ToArray(); return "?" + string.Join("&", array); } public static void RedirectTo(this HttpRequestBase request, string url, params KeyValuePair[] queryParameters) { string redirectUrl = string.Concat(EnsureUrlEndsWithSlash(url), GetQueryStringFromArray(queryParameters)); if (request.IsAjaxRequest()) HttpContext.Current.Response.Write(string.Format("", redirectUrl)); else HttpContext.Current.Response.Redirect(redirectUrl, true); } 

Simplemente puede hacer algún tipo de filtro de respuesta ajax para las respuestas entrantes con $ .ajaxSetup . Si la respuesta contiene la redirección MVC, puede evaluar esta expresión en el lado JS. Código de ejemplo para JS a continuación:

 $.ajaxSetup({ dataFilter: function (data, type) { if (data && typeof data == "string") { if (data.indexOf('window.location') > -1) { eval(data); } } return data; } }); 

Si los datos son: “window.location = ‘/ Acount / Login'”, el filtro de arriba detectará y evaluará para hacer la redirección.

No estoy satisfecho con la mejor respuesta de Joseph, en lugar de solucionar el problema correcto, dijo que este es el caso de uso incorrecto. De hecho, hay muchos lugares, por ejemplo, si está convirtiendo una antigua base de código en un código oculto y allí lo NECESITA, entonces lo NECESITA. En la progtwigción no hay excusa porque no solo tú codificas a todos sus malos y buenos desarrolladores y tienes que trabajar codo con codo. Entonces, si no codigo la redirección en ajax, mi compañero desarrollador puede obligarme a tener una solución para eso. Al igual que me gusta usar todos los sitios con diseño de AMD o mvc4, y mi empresa puede mantenerme alejado de ella durante un año.

Entonces, hablemos de la solución ahora.

He hecho muchísimo trabajo de solicitud y respuesta ajax y la forma más sencilla que descubrí fue enviar códigos de estado al cliente y tener una función javascript estándar para comprender esos códigos. Si simplemente envío, por ejemplo, el código 13, podría significar una redirección.

Entonces una respuesta json como {statusCode: 13, messsage: ‘/ home / logged-in’} por supuesto que hay toneladas de variaciones propuestas como {status: ‘success’, code: 13, url: ‘/ home / logged-in ‘, mensaje:’ Usted está conectado ahora ‘}

etc., hasta su propia elección de mensajes estándar

Por lo general, heredo de la clase de controlador base y pongo mi elección de respuestas estándar como esta

 public JsonResult JsonDataResult(object data, string optionalMessage = "") { return Json(new { data = data, status = "success", message = optionalMessage }, JsonRequestBehavior.AllowGet); } public JsonResult JsonSuccessResult(string message) { return Json(new { data = "", status = "success", message = message }, JsonRequestBehavior.AllowGet); } public JsonResult JsonErrorResult(string message) { return Json(new { data = "", status = "error", message = message }, JsonRequestBehavior.AllowGet); } public JsonResult JsonRawResult(object data) { return Json(data, JsonRequestBehavior.AllowGet); } 

Acerca de usar $ .ajax intead de Ajax.BeginForm Me encantaría usar Jquery ajax y lo hago, pero de nuevo no soy yo en todo el mundo para tomar decisiones. Tengo una aplicación llena de Ajax.BeginForm y por supuesto que no hice eso. Pero tengo que vivir con eso.

Entonces hay una callback de éxito en forma de inicio también, no es necesario usar jquery ajax para usar devoluciones de llamada Algo sobre esto aquí Ajax.BeginForm, Acción de Llamadas, Devuelve JSON, ¿Cómo accedo al objeto JSON en mi función OnSuccess JS?

Gracias

Si eres redirigido desde la clase de JavaScript

misma vista – controlador diferente

 window.location.href = `'Home'`; 

no es la misma vista

 window.location.href = `'Index/Home'`; 

Agregue una clase de ayuda:

 public static class Redirector { public static void RedirectTo(this Controller ct, string action) { UrlHelper urlHelper = new UrlHelper(ct.ControllerContext.RequestContext); ct.Response.Headers.Add("AjaxRedirectURL", urlHelper.Action(action)); } public static void RedirectTo(this Controller ct, string action, string controller) { UrlHelper urlHelper = new UrlHelper(ct.ControllerContext.RequestContext); ct.Response.Headers.Add("AjaxRedirectURL", urlHelper.Action(action, controller)); } public static void RedirectTo(this Controller ct, string action, string controller, object routeValues) { UrlHelper urlHelper = new UrlHelper(ct.ControllerContext.RequestContext); ct.Response.Headers.Add("AjaxRedirectURL", urlHelper.Action(action, controller, routeValues)); } } 

Luego llame a su acción:

this.RedirectTo (“Índice”, “Cemento”);

Agregue código JavaScript a cualquier archivo o archivo de diseño incluido javascript global para interceptar todas las solicitudes ajax:

  

Como ben foster dice, puedes devolver los Javascripts y te redirigirá a la página deseada.

Para cargar la página en la página actual:

 return JavaScript("window.location = 'http://www.google.co.uk'");' 

Para cargar la página en la nueva pestaña:

 return JavaScript("window.open('http://www.google.co.uk')"); 

Puede obtener una redirección que no esté basada en js desde una llamada ajax colocando una de esas tags meta refresh. Esto aquí parece estar funcionando: return Content("");

Nota: Descubrí que las actualizaciones de meta son desactivadas automáticamente por Firefox, haciendo que esto no sea muy útil.

Qué tal esto :

 public ActionResult GetGrid() { string url = "login.html"; return new HttpStatusCodeResult(System.Net.HttpStatusCode.Redirect,url) } 

Y entonces

 $(document).ajaxError(function (event, jqxhr, settings, thrownError) { if (jqxhr.status == 302) { location.href = jqxhr.statusText; } }); 

O

 error: function (a, b, c) { if (a.status == 302) { location.href = a.statusText; } }