Whenever you need a page to return to the previous page when you get an form submit or some other action, this can be used:
Have a base controller that is inherited by all your controllers. That is always a good idea – you can easily add things that work site-wide.
In you base controller have a OnActionExecuting overriden – here we are going to store the previous page.
Something like this:
public abstract partial class MyController : Controller
{
public ActionResult RedirectToPrevious(String defaultAction, String defaultController)
{
if (Session == null || Session["PrevUrl"] == null)
{
return RedirectToAction(defaultAction, defaultController);
}
String url = ((Uri)Session["PrevUrl"]).PathAndQuery;
if (Request.Url != null && Request.Url.PathAndQuery != url)
{
return Redirect(url);
}
return RedirectToAction(defaultAction, defaultController);
}
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
var httpContext = filterContext.HttpContext;
if (httpContext.Request.RequestType == "GET"
&& !httpContext.Request.IsAjaxRequest()
&& filterContext.IsChildAction == false) // do no overwrite if we do child action.
{
// stop overwriting previous page if we just reload the current page.
if (Session["CurUrl"] != null
&& ((Uri)Session["CurUrl"]).Equals(httpContext.Request.Url) )
return;
Session["PrevUrl"] = Session["CurUrl"] ?? httpContext.Request.Url;
Session["CurUrl"] = httpContext.Request.Url;
}
}
}
Now, as I figured, it is not the best idea for redirecting everything by default. For validation purposes you would like not to redirect
Then you can reference Session[“PrevUrl”] in controllers, but there is a better way of doing it – create attribute!
public class RedirectToPreviousPageAttribute : ActionFilterAttribute
{
///
/// Place [RedirectToPreviousPage] attribute on Controller action
/// and when you do submit of form, this functionality will kick in.
/// We check if Session has Previous URL set and force to redirect
/// to whatever it says.
/// If no Session variable is set, just do what it is supposed to do in the first place.
///
///
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
var httpContext = filterContext.HttpContext;
if (httpContext.Session == null || httpContext.Session["PrevUrl"] == null)
{
base.OnResultExecuted(filterContext);
return;
}
String url = ((Uri)httpContext.Session["PrevUrl"]).PathAndQuery;
if (httpContext.Request.Url != null && httpContext.Request.Url.PathAndQuery != url)
{
httpContext.Response.Redirect(url);
}
base.OnResultExecuted(filterContext);
}
}
And now, wherever you are put this attribute on a controller action (or entire controller), it will redirect to the previous page:
[HttpPost]
public virtual ActionResult Edit(Model model)
{
if (!ModelState.IsValid)
{
return View(model);
}
_repository.InsertOrUpdate(model);
_repository.Save();
return RedirectToPrevious("Index", "Controller");
}
VoilĂ ! Good to go!