¿Cómo redirijo a la acción anterior en ASP.NET MVC?

122

Supongamos que tengo algunas páginas

  • some.web/articles/details/5
  • some.web/users/info/bob
  • some.web/foo/bar/7

que puede llamar a un controlador de utilidad común como

locale/change/es o authorization/login

¿Cómo consigo estos métodos ( change, login) para redirigir a las acciones anteriores ( details, info, bar) mientras pasa los parámetros anteriores a ellos ( 5, bob, 7)?

En resumen: ¿cómo redirijo a la página que acabo de visitar después de realizar una acción en otro controlador?

adolfojp
fuente

Respuestas:

156

tratar:

public ActionResult MyNextAction()
{
    return Redirect(Request.UrlReferrer.ToString());
}

Alternativamente, tocando lo que dijo Darin, prueba esto:

public ActionResult MyFirstAction()
{
    return RedirectToAction("MyNextAction",
        new { r = Request.Url.ToString() });
}

luego:

public ActionResult MyNextAction()
{
    return Redirect(Request.QueryString["r"]);
}
Nathan Ridley
fuente
Solo una sugerencia: puede usar "Redirigir" explícitamente, es más difícil probar la unidad de su controlador. Es mejor usar un "RedirectToAction" en su lugar.
Syd
Recomiendo usarlo Request.Url.AbsolutePath.ToString()ya que el método AccountController's LogOncontiene comprobaciones de URL que comienzan con '/', etc.' '
Fulvio
1
@gotnull Request.Url.AbsolutePath redirigirá a la misma acción. Cuál no es la salida deseada. Tenemos que volver a la segunda última acción. Para eso podríamos escribir: return Redirect (ControllerContext.HttpContext.Request.UrlReferrer.ToString ());
Rahatur
22
@nathanridley: Esto no funciona para solicitudes POST. Digamos que el usuario está encendido GET Indexentonces GET Edit. La URL de referencia es entonces, Indexpero cuando el usuario lo hace, POST Editla referencia ahora es Editde la solicitud GET anterior. ¿Cómo puedo asegurarme de que POST Editconoce la URL a la que remitió al usuario GET Edit?
one.beat.consumer
UrlReferrer es NULL cuando estaba en alguna página y quiero ver que sé que obtuve un error simplemente ingresando la URL en la barra de direcciones. ¿Por qué cuando ingreso la URL en la barra de direcciones no puede determinar UrlReferrer?
QMaster
46

Si desea redirigir desde un botón en la Vista, puede usar:

@Html.ActionLink("Back to previous page", null, null, null, new { href = Request.UrlReferrer})
I Desconocido
fuente
28

Si no le preocupan las pruebas unitarias, simplemente puede escribir:

return Redirect(ControllerContext.HttpContext.Request.UrlReferrer.ToString());
Rahatur
fuente
9

Una sugerencia sobre cómo hacer esto de manera que:

  1. la URL de retorno sobrevive a la solicitud POST de un formulario (y cualquier validación fallida)
  2. la URL de retorno se determina a partir de la URL de referencia inicial
  3. sin usar TempData [] u otro estado del lado del servidor
  4. maneja la navegación directa a la acción (al proporcionar una redirección predeterminada)

.

public ActionResult Create(string returnUrl)
{
    // If no return url supplied, use referrer url.
    // Protect against endless loop by checking for empty referrer.
    if (String.IsNullOrEmpty(returnUrl)
        && Request.UrlReferrer != null
        && Request.UrlReferrer.ToString().Length > 0)
    {
        return RedirectToAction("Create",
            new { returnUrl = Request.UrlReferrer.ToString() });
    }

    // Do stuff...
    MyEntity entity = GetNewEntity();

    return View(entity);
}

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(MyEntity entity, string returnUrl)
{
    try
    {
        // TODO: add create logic here

        // If redirect supplied, then do it, otherwise use a default
        if (!String.IsNullOrEmpty(returnUrl))
            return Redirect(returnUrl);
        else
            return RedirectToAction("Index");
    }
    catch
    {
        return View();  // Reshow this view, with errors
    }
}

Puede usar la redirección dentro de la vista de esta manera:

<% if (!String.IsNullOrEmpty(Request.QueryString["returnUrl"])) %>
<% { %>
    <a href="<%= Request.QueryString["returnUrl"] %>">Return</a>
<% } %>

fuente
9

En Mvc usando html simple en Ver página con java script onclick

<input type="button" value="GO BACK" class="btn btn-primary" 
onclick="location.href='@Request.UrlReferrer'" />

Esto funciona muy bien. La esperanza ayuda a alguien.

@JuanPieterse ya ha respondido usando @Html.ActionLinkasí que si es posible alguien puede comentar o responder usando@Url.Action

shaijut
fuente
6

Pase un parámetro returnUrl (codificado en url) a las acciones de cambio e inicio de sesión y redirija dentro a este returnUrl dado. Su acción de inicio de sesión podría verse así:

public ActionResult Login(string returnUrl) 
{
    // Do something...
    return Redirect(returnUrl);
}
Darin Dimitrov
fuente
5

Estoy usando .Net Core 2 MVC, y este funcionó para mí, en el uso del controlador HttpContext.Request.Headers["Referer"];

Saad Hasan
fuente
1

Puede volver a la página anterior utilizando la ViewBag.ReturnUrlpropiedad

almaceleste
fuente
1

Para construir dinámicamente returnUrl en cualquier vista, intente esto:

@{
    var formCollection =
        new FormCollection
            {
                new FormCollection(Request.Form),
                new FormCollection(Request.QueryString)
            };

    var parameters = new RouteValueDictionary();

    formCollection.AllKeys
        .Select(k => new KeyValuePair<string, string>(k, formCollection[k])).ToList()
        .ForEach(p => parameters.Add(p.Key, p.Value));
}

<!-- Option #1 -->
@Html.ActionLink("Option #1", "Action", "Controller", parameters, null)

<!-- Option #2 -->
<a href="/Controller/Action/@[email protected](ViewContext.RouteData.Values["action"].ToString(), ViewContext.RouteData.Values["controller"].ToString(), parameters)">Option #2</a>

<!-- Option #3 -->
<a href="@Url.Action("Action", "Controller", new { object.ID, returnUrl = Url.Action(ViewContext.RouteData.Values["action"].ToString(), ViewContext.RouteData.Values["controller"].ToString(), parameters) }, null)">Option #3</a>

Esto también funciona en páginas de diseño, vistas parciales y ayudantes HTML

Relacionado: URL de retorno dinámico MVC3 (igual pero desde cualquier controlador / acción)

Matthew Hudson
fuente
0

Para ASP.NET Core Puede usar el atributo asp-route- *:

<form asp-action="Login" asp-route-previous="@Model.ReturnUrl">

Otro ejemplo detallado: imagine que tiene un controlador de vehículo con acciones

Índice

Detalles

Editar

y puede editar cualquier vehículo desde el índice o desde los detalles, por lo que si hizo clic en editar desde el índice, debe volver al índice después de la edición y si hizo clic en editar desde los detalles, debe volver a los detalles después de la edición.

//In your viewmodel add the ReturnUrl Property
public class VehicleViewModel
{
     ..............
     ..............
     public string ReturnUrl {get;set;}
}



Details.cshtml
<a asp-action="Edit" asp-route-previous="Details" asp-route-id="@Model.CarId">Edit</a>

Index.cshtml
<a asp-action="Edit" asp-route-previous="Index" asp-route-id="@item.CarId">Edit</a>

Edit.cshtml
<form asp-action="Edit" asp-route-previous="@Model.ReturnUrl" class="form-horizontal">
        <div class="box-footer">
            <a asp-action="@Model.ReturnUrl" class="btn btn-default">Back to List</a>
            <button type="submit" value="Save" class="btn btn-warning pull-right">Save</button>
        </div>
    </form>

En tu controlador:

// GET: Vehicle/Edit/5
    public ActionResult Edit(int id,string previous)
    {
            var model = this.UnitOfWork.CarsRepository.GetAllByCarId(id).FirstOrDefault();
            var viewModel = this.Mapper.Map<VehicleViewModel>(model);//if you using automapper
    //or by this code if you are not use automapper
    var viewModel = new VehicleViewModel();

    if (!string.IsNullOrWhiteSpace(previous)
                viewModel.ReturnUrl = previous;
            else
                viewModel.ReturnUrl = "Index";
            return View(viewModel);
        }



[HttpPost]
    public IActionResult Edit(VehicleViewModel model, string previous)
    {
            if (!string.IsNullOrWhiteSpace(previous))
                model.ReturnUrl = previous;
            else
                model.ReturnUrl = "Index";
            ............. 
            .............
            return RedirectToAction(model.ReturnUrl);
    }
Mohamed Elamin
fuente