views:

1170

answers:

5

Let's say I have a controller action that deletes an item out of a user's shopping basket. This controller action is triggered by performing a POST to the url ~/delete/{id}. If I have several pages on my application that will post to this url, how do I construct the controller action to redirect back to the page that posted to it?

A: 

I've never tried it but you can use the Referer header to know where the post or get comes from and try to match the URL with a route.

Eduardo Campañó
+5  A: 

You should provide a RedirectToUrl parameter from the posting page.

Relying on referrer headers is not a good practice.

Instead, do something like this:

public ActionResult Delete(int id, string RedirectToUrl)
{
  // check if RedirectToUrl is null or empty and redirect accordingly
}

On the posting view or partial view you can provide the parameter in several ways:

<%= Html.Hidden("RedirecToUrl","/my/lovely/url") %>

or

<form action="/item/delete/22?RedirectToUrl=/my/lovely/url">

I'd prefer the first option.

Christian Dalager
Most statistics systems rely on the referer header to know where the request comes from. It's not reliable but if I have to choose between changing every link in a website and relying in the referer header to redirect, I'd go for the last one, or make some ajax actionlink as tvanfosson suggests.
Eduardo Campañó
yeah it's always a tradeoff. Changing every link in a website sounds like a lot like bad design to me though. If you are testing your controllers the redirect parameter will also be easier to test.
Christian Dalager
This is what we do, but I strongly advise "sanitizing" the passed redirect URL, and ignoring it if it's not part of your site. This applies also to referrer headers.
Craig Stuntz
+1  A: 

The first thing that I would do is use Ajax.ActionLink, then if the user has Javascript turned on, you'd never actually leave the page. This is the best solution. If you don't want a link, you could also have an Ajax form. Either of these could use the DELETE or POST method.

In order to handle the case where Javascript is turned off, when you detect in the controller that the POST was not done with Ajax (Request.IsAjaxRequest is false), you could look at the Request.UrlReferer property to get the Url of the referring page. If this is not null, you can use a RedirectResult to go back to this page. If it is null, choose a default landing page -- probably something like "Your item has been removed, click here to continue shopping." This latter will probably only rarely get hit.

tvanfosson
A: 

Just use the URL Referer [sic] header.

var requestFrom = Request.UrlReferrer

You can find the documentation at: http://msdn.microsoft.com/en-us/library/system.web.httprequest.urlreferrer.aspx

The only time this wouldn't work is when the page is requested directly, but in that case you wouldn't have any place to redirect to anyways.

There is also the option of doing the only thing async using AJAX, so that your Delete action only does what it describes and isn't responsible for doing something outside of its intended purpose of deleting.

Nick Berardi
A: 

If you are using WCSF (Web Client Software Factory) to implement MVC pattern, you could use PageFlow to do all navigation.

Eg:-

PageFlow.Next(); or PageFlow.Previous();

Bhaskar