Here's how I do:
public class ReturnPointAttribute : Attribute
{
}
public class BaseController: Controller
{
private string returnPointUrl = null;
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
if (filterContext.ActionDescriptor.IsDefined(typeof(ReturnPointAttribute), true))
returnPointUrl = filterContext.HttpContext.Request.Url.ToString();
}
public ActionResult RedirectOrReturn<T>(Expression<Action<T>> action) where T : BaseController
{
return returnPointUrl.IsNullOrEmpty()
? MyControllerExtensions.RedirectToAction(this, action)
: (ActionResult)Redirect(returnPointUrl);
}
}
Now, you mark you X actions with [ReturnPoint] and call RedirectOrReturn() if you want to return back.
I do not use UrlReferrer because it can be wrong and I have no control over its value. With ReturnPoint, you can also have groups, e.g. [ReturnPoint("Orders")] and RedirectOrReturn("Orders").
Of course, you can have more automatic behaviour in OnActionExecuted - e.g. it can check if returned result is Redirect, and automatically go to ReturnPoint if it has value. Or you can control this with [ReturnPoint(Automatic=true)], and so on.