Jak przekierować do poprzedniej akcji w ASP.NET MVC?

122

Załóżmy, że mam kilka stron

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

który może wywołać typowy kontroler narzędzi, taki jak

locale/change/es lub authorization/login

Jak mogę dostać te metody ( change, login), aby przekierować do poprzednich działań ( details, info, bar) podczas przechodzenia dotychczasowe parametry do nich ( 5, bob, 7)?

W skrócie: jak przekierować na stronę, którą właśnie odwiedziłem, po wykonaniu akcji w innym kontrolerze?

adolfojp
źródło

Odpowiedzi:

156

próbować:

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

alternatywnie, dotykając tego, co powiedział Darin, spróbuj tego:

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

następnie:

public ActionResult MyNextAction()
{
    return Redirect(Request.QueryString["r"]);
}
Nathan Ridley
źródło
Tylko sugestia: możesz użyć opcji „Przekierowanie”, co jest trudniejsze do przetestowania kontrolera. Lepiej zamiast tego użyć „RedirectToAction”.
Syd,
Polecam przy użyciu Request.Url.AbsolutePath.ToString()jako AccountController„s LogOnmetoda zawiera kontrole na początku adresu URL z '/'itp
Fulvio
1
@gotnull Request.Url.AbsolutePath przekieruje do tej samej akcji. Co nie jest pożądanym wyjściem. Musimy wrócić do przedostatniej akcji. W tym celu moglibyśmy napisać: return Redirect (ControllerContext.HttpContext.Request.UrlReferrer.ToString ());
Rahatur
22
@nathanridley: To nie działa w przypadku żądań POST. Powiedz, że użytkownik jest GET Indexwtedy włączony GET Edit. Odsyłający adres URL jest Indexwtedy, gdy użytkownik wykona, POST Editże strona odsyłająca pochodzi Editz poprzedniego żądania GET. Jak mogę się upewnić, że POST Editzna adres URL, do którego odesłał użytkownika GET Edit?
one.beat.consumer
UrlReferrer ma wartość NULL, gdy byłem na jakiejś stronie i chcę zobaczyć, że wiem, że wystąpił błąd, po prostu wpisując adres URL w pasku adresu. Dlaczego po wpisaniu adresu URL na pasku adresu nie mogę określić adresu URLReferrer?
QMaster
47

Jeśli chcesz przekierować z przycisku w Widoku, możesz użyć:

@Html.ActionLink("Back to previous page", null, null, null, new { href = Request.UrlReferrer})
Nieznany
źródło
28

Jeśli nie interesują Cię testy jednostkowe, możesz po prostu napisać:

return Redirect(ControllerContext.HttpContext.Request.UrlReferrer.ToString());
Rahatur
źródło
9

Sugestia, jak to zrobić, aby:

  1. zwrotny adres URL przetrwa żądanie POST formularza (i wszelkie nieudane weryfikacje)
  2. URL zwrotny jest określany na podstawie początkowego adresu URL odsyłającego
  3. bez użycia TempData [] lub innego stanu po stronie serwera
  4. obsługuje bezpośrednią nawigację do akcji (poprzez podanie domyślnego przekierowania)

.

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
    }
}

Możesz użyć przekierowania w widoku w następujący sposób:

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

źródło
9

W Mvc przy użyciu zwykłego html w widoku strony ze skryptem java onclick

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

To działa świetnie. nadzieja pomaga komuś.

@JuanPieterse już odpowiedział, używając, @Html.ActionLinkwięc jeśli to możliwe, ktoś może komentować lub odpowiadać za pomocą@Url.Action

shaijut
źródło
6

Przekaż parametr returnUrl (zakodowany w adresie url) do akcji zmiany i logowania oraz wewnątrz przekierowania do podanego returnUrl. Twoja akcja logowania może wyglądać mniej więcej tak:

public ActionResult Login(string returnUrl) 
{
    // Do something...
    return Redirect(returnUrl);
}
Darin Dimitrov
źródło
5

Używam .Net Core 2 MVC, a ten działał dla mnie, w użyciu kontrolera HttpContext.Request.Headers["Referer"];

Saad Hasan
źródło
1

Możesz wrócić do poprzedniej strony, używając ViewBag.ReturnUrlwłaściwości.

almaceleste
źródło
1

Aby dynamicznie skonstruować returnUrl w dowolnym widoku, spróbuj tego:

@{
    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>

Działa to również na stronach układu, widokach częściowych i pomocnikach HTML

Powiązane: Dynamiczny zwrotny adres URL MVC3 (taki sam, ale z poziomu dowolnego kontrolera / akcji)

Matthew Hudson
źródło
0

W przypadku ASP.NET Core można użyć atrybutu asp-route- *:

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

Inne szczegóły przykład: Wyobraź sobie, że masz kontroler pojazdu z akcjami

Indeks

Detale

Edytować

i możesz edytować dowolny pojazd z indeksu lub szczegółów, więc jeśli kliknąłeś edytuj z indeksu, musisz powrócić do indeksu po edycji, a jeśli kliknąłeś edytuj ze szczegółów, musisz powrócić do szczegółów po edycji.

//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>

W kontrolerze:

// 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
źródło