views:

88

answers:

3

I don't think title is making any sense, so I hope that I can explain it well enough.

I have Controler Item with Action EditItem. EditItem is routed to from many places, such as

/Item/Browse/ByCategory
/Item/Browse/ByType
/Item/Browse/ByWhatever

What I'd really like is to return the user to page from where he clicked Edit on an item.

I know I can do this by passing an ?ReturnUrl parameter for EditItem action, but I keep wondering, is it possible to find out from where did user came from, something like referer...

+1  A: 

There is no other way except passing returnUrl or checking HttpContext.Current.Request.Referer property. But Referer gives you string value that needs parsing to exctract Action.

Gopher
+1 for being first :)
Vnuk
ReferrerUrl may not working in some environments. For example, if browser like IE has strong security options and not sending this info to server. This wouldn't work in that case. Also, using HTTPS may not send this info on server too.
Lion_cl
A: 

Ah, but of course everything is possible. In your controller (or preferably base controller) override OnActionExecuted and OnActionExecuting and place your previous URL into session. Use your session variable in any controller that inherits from the one with this implementation (or just this controller if you don't inherit from a custom base).

 protected string NextBackUrl {get; set;}
 protected override void OnActionExecuted(ActionExecutedContext filterContext)
        {

            HttpContext.Current.Session["PreviousURL"] = NextBackUrl;
            base.OnActionExecuted(filterContext);
        }

 protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {

                if (Request.Url != null && Request.UrlReferrer != null && Request.Url != Request.UrlReferrer)
                {
                    NextBackUrl = Request.UrlReferrer.AbsoluteUri;
                }

            base.OnActionExecuting(filterContext);
        }
kmehta
Very elegant solution, thanks!
Vnuk
Session may expire and you will lost back page address info.
Lion_cl
+1  A: 

Just created test solution, so i'm sure this would work. 1) Create new route before default one:

routes.MapRoute("EditItem",
   "EditItem/{referrer}/{id}",
   new {controller = "Item", action = "EditItem",id = "",referrer = "ByCategory"}
);

2) Use this link to EditItem on any of your 3 views:

<%= Html.RouteLink("Edit Item 1", "EditItem", 
    new {referrer = ViewContext.RouteData.Values["action"], id = 1}) %>

3) Use this Back button on the EditItem view:

<%= Html.RouteLink("Back", "Default", 
    new { action = ViewContext.RouteData.Values["referrer"]})%>

Working with Routes makes URLs more beautiful and user-friendly.

Lion_cl