How do I redirect to the previous action in ASP.NET MVC?
Asked Answered
U

10

134

Lets suppose that I have some pages

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

that can call a common utility controller like

locale/change/es or authorization/login

How do I get these methods (change, login) to redirect to the previous actions (details, info, bar) while passing the previous parameters to them (5, bob, 7)?

In short: How do I redirect to the page that I just visited after performing an action in another controller?

Unrivaled answered 2/5, 2009 at 17:18 Comment(0)
E
167

try:

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

alternatively, touching on what darin said, try this:

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

then:

public ActionResult MyNextAction()
{
    return Redirect(Request.QueryString["r"]);
}
Erdmann answered 2/5, 2009 at 17:37 Comment(6)
Just a suggestion: you can use "Redirect" explictly is harder to unit test your controller. You are better off using a "RedirectToAction" instead.Opening
I'd recommend using Request.Url.AbsolutePath.ToString() as the AccountController's LogOn method contains checks for URL's beginning with '/', etc.Ewan
@Ewan Request.Url.AbsolutePath will redirect to the same action. Which is not the desired output. We have to return to the second last action. For that we could write: return Redirect(ControllerContext.HttpContext.Request.UrlReferrer.ToString());Riding
@nathanridley: This does not work for POST requests. Say the user is on GET Index then GET Edit. The referring URL then is Index but then when the user does POST Edit the referrer is now Edit from the preceding GET request. How can I make sure POST Edit knows the URL that referred the user to GET Edit?Ordeal
UrlReferrer is NULL when I was in the some page and want to get to view I know got error just by entering URL in address bar. Why when I enter URL in Address Bar it can't determine UrlReferrer?Saulsauls
Putting the redirect URL on the query string is a smart thing to do. If your authentication scheme does redirects, it will get in the way of this feature.Nutmeg
R
48

If you want to redirect from a button in the View you could use:

@Html.ActionLink("Back to previous page", null, null, null, new { href = Request.UrlReferrer})
Radioluminescence answered 1/8, 2013 at 9:28 Comment(0)
R
28

If you are not concerned with unit testing then you can simply write:

return Redirect(ControllerContext.HttpContext.Request.UrlReferrer.ToString());
Riding answered 5/11, 2012 at 15:18 Comment(0)
H
11

A suggestion for how to do this such that:

  1. the return url survives a form's POST request (and any failed validations)
  2. the return url is determined from the initial referral url
  3. without using TempData[] or other server-side state
  4. handles direct navigation to the action (by providing a default redirect)

.

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

You could use the redirect within the view like this:

<% if (!String.IsNullOrEmpty(Request.QueryString["returnUrl"])) %>
<% { %>
    <a href="<%= Request.QueryString["returnUrl"] %>">Return</a>
<% } %>
Hermilahermina answered 3/5, 2009 at 16:41 Comment(0)
M
9

In Mvc using plain html in View Page with java script onclick

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

This works great. hope helps someone.

@JuanPieterse has already answered using @Html.ActionLink so if possible someone can comment or answer using @Url.Action

Mesomorph answered 2/9, 2015 at 11:22 Comment(0)
J
8

I'm using .Net Core 2 MVC , and this one worked for me, in the controller use HttpContext.Request.Headers["Referer"];

Jaine answered 22/11, 2017 at 14:34 Comment(0)
B
7

Pass a returnUrl parameter (url encoded) to the change and login actions and inside redirect to this given returnUrl. Your login action might look something like this:

public ActionResult Login(string returnUrl) 
{
    // Do something...
    return Redirect(returnUrl);
}
Blakney answered 2/5, 2009 at 17:30 Comment(0)
G
1

You could return to the previous page by using ViewBag.ReturnUrl property.

Glandular answered 9/7, 2016 at 20:44 Comment(0)
M
1

To dynamically construct the returnUrl in any View, try this:

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

This also works in Layout Pages, Partial Views and Html Helpers

Related: MVC3 Dynamic Return URL (Same but from within any Controller/Action)

Mummer answered 25/4, 2017 at 9:40 Comment(0)
R
1

For ASP.NET Core You can use asp-route-* attribute:

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

Other in details example: Imagine that you have a Vehicle Controller with actions

Index

Details

Edit

and you can edit any vehicle from Index or from Details, so if you clicked edit from index you must return to index after edit and if you clicked edit from details you must return to details after edit.

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

In your controller:

// 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);
    }
Revivalism answered 24/12, 2019 at 8:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.