asp.net mvc 3 - editar - jQuery Mobile/MVC: obtener la URL del navegador para cambiar con RedirectToAction
mvc 5 controller (4)
Mi primer mensaje ...
Cuando uso RedirectToAction, la URL en el navegador no cambia. ¿Cómo puedo conseguir esto?
Estoy cambiando a ASP.NET MVC 3.0 (también usando jQuery Mobile) después de más de 10 años utilizando formularios web. Tengo alrededor de 8 semanas, y después de varios libros y buscar en Google una respuesta, me voy a secar.
Tengo una ruta única definida en Global.asax:
routes.MapRoute(
"Routes",
"{controller}/{action}/{id}",
new { controller = "Shopping", action = "Index", id = UrlParameter.Optional }
Tengo un ShoppingController con estas acciones:
public ActionResult Cart() {...}
public ActionResult Products(string externalId) {...}
[HttpPost]
public ActionResult Products(List<ProductModel> productModels)
{
// do stuff
return RedirectToAction("Cart");
}
La url cuando hago un get y post (con la publicación que tiene el RedirectToAction) siempre es:
/Shopping/Products?ExternalId=GenAdmin
Después de la publicación y RedirectToAction, quiero que la URL en el navegador cambie a:
/Shopping/Cart
Intenté Redirect y RedirectToRoute, pero obtuve los mismos resultados.
Cualquier ayuda sería muy apreciada.
[Actualización] Descubrí que las publicaciones jQuery Mobile AJAX son las culpables aquí. Si apago el AJAX de jQuery Mobile, funciona.
<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
<script type="text/javascript">
// do not handle links via ajax by default
$(document).bind("mobileinit", function () { $.mobile.ajaxEnabled = false; });
</script>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0rc2/jquery.mobile-1.0rc2.min.css" />
El orden de los scripts anteriores es importante. Primero tuve que incluir el script en jQuery, luego incluir el script para desactivar el uso de AJAX por parte de jQuery Mobile y luego incluir el script en jQuery Mobile.
Todavía me gustaría encontrar una forma de usar AJAX y tener la actualización de URL correctamente. O al menos poder llamar al mensaje de "carga" de jQuery Mobile (o hornear el mío).
Creo que encontré una respuesta. Enterrada profundamente en la documentación de jQuery Mobile , hay información sobre cómo configurar la data-url
en el div con data-role="page"
. Cuando hago esto, obtengo las cosas agradables de jQuery Mobile AJAX (mensaje de carga de página, transiciones de página) Y obtengo la url en el navegador actualizada correctamente.
Esencialmente, así es como lo estoy haciendo ...
[HttpPost]
public ActionResult Products(...)
{
// ... add products to cart
TempData["DataUrl"] = "data-url=/"/Cart/"";
return RedirectToAction("Index", "Cart");
}
Luego, en mi página de diseño, tengo esto ...
<div data-role="page" data-theme="c" @TempData["DataUrl"]>
En mis acciones HttpPost
ahora configuro TempData["DataUrl"]
para que las páginas se configuren y se llenen en la página de diseño. Las acciones "Get" no configuran TempData ["DataUrl"] para que no se llene en la página de diseño en esas situaciones.
Lo único que no funciona con esto es cuando hace clic derecho ... ver fuente ... en el navegador, el html no siempre es para la página en la que se encuentra, lo cual no es inusual para AJAX .
David, esto fue una gran ayuda para mí. Solo quería agregar que en mi caso tuve que usar el siguiente formato para que la URL se muestre en la forma correcta como mis otras URL:
TempData["DataUrl"] = "data-url=/appName/controller/action";
return RedirectToAction("action", "controller");
Como nota al margen, también encontré que al asignar el valor a TempData ["DataUrl"] pude omitir las comillas escapadas e ingresarlas exactamente como arriba y parece estar funcionando bien para mí. De nuevo, gracias por tu ayuda.
Hay un problema en github https://github.com/jquery/jquery-mobile/issues/1571
Tiene una buena solución sin la necesidad de TempData
No estoy seguro si todavía es real, pero en mi caso escribí el siguiente método de ayuda
public static IHtmlString GetPageUrl<TModel>(this HtmlHelper<TModel> htmlHelper, ViewContext viewContext)
{
StringBuilder urlBuilder = new StringBuilder();
urlBuilder.Append("data-url=''");
urlBuilder.Append(viewContext.HttpContext.Request.Url.GetComponents(UriComponents.PathAndQuery, UriFormat.UriEscaped));
urlBuilder.Append("''");
return htmlHelper.Raw(urlBuilder.ToString());
}
Y luego úselo de la siguiente manera:
<div data-role="page" data-theme="d" @Html.GetPageUrl(ViewContext) >
De esta forma no necesito cada acción de redirección almacenar un TempData. Funcionó bien para mí tanto para Redirect como para RedirectToAction. Esto no funcionaría correctamente en caso de que use el método "View ()" dentro del controlador y devuelva un nombre de vista diferente, lo que cambiará la interfaz de usuario, pero retendrá la url.
Espero que ayude a Artem