6

I have a main page which has a few filters that I want to keep when I return to this main url. But after loading another pages I want to go back. It could be easily done by getting the @Request.UrlReferrer. However, it only works when returning to the previous page, I need it for the previous 2 pages.

I could do it by using Session["ReturnToMainUrl"] = Request.UrlReferrer but setting it only when getting off the first page.

So If I have 3 levels:

  1. WebSite\page1?Filter=ABC
  2. WebSite\page2
  3. Website\page3

  4. I am on page2 or page3 now and I want to go back to Website\page1?Filter=ABC

When I am on the page 3 I can use Request.UrlReferrer to go back to page 2, but when I go back to page 1 I need to keep the parameters so I am loading from the Session.

How can I do it in a smarter way, not using sessions?

Roger Oliveira
  • 1,589
  • 1
  • 27
  • 55
  • 3
    use a parameter `returnUrl` and pass it on across the pages you want to return from. In your case you have to pass it from `page1 -> page2->page3` . On page3 now redirect to the returnUrl – Ruchan May 28 '15 at 05:00
  • 1
    This may be applicable: http://stackoverflow.com/questions/18402684/create-breadcrumbs-path-in-asp-net-mvc – Brendan Green May 28 '15 at 05:07
  • Yeah, however, from page3 it only goes to page2, so I can use the urlrefferer.. the only problem is when back to page 2 going to page1. So I think it is too bad to pass twice the returnUrl :(. @Ruchan – Roger Oliveira May 28 '15 at 05:08
  • @BrendanGreen It is slighly different from that question, that is like killing a mosquito with a gun, I need some good practice in a simple way. – Roger Oliveira May 28 '15 at 05:10
  • 1
    there is no harm in passing the returnUrl multiple times. If you don't feel ease with the method then other might be to use `session` or `cookie` – Ruchan May 28 '15 at 05:14

2 Answers2

2

You should recursively build onto a returnUrl query string parameter as you progress from page to page.

For example: https://dotnetfiddle.net/HtoX6b

var page0 = new Uri("http://www.example.com/page0");
Console.WriteLine("Page 0: {0}", page0);

var page1 = new Uri("http://www.example.com/page1?paramA=foo&paramB=bar&returnUrl=" + HttpUtility.UrlEncode(page0.ToString()));
Console.WriteLine("Page 1: {0}", page1);

var page2 = new Uri("http://www.example.com/page2?paramC=baz&paramD=qux&returnUrl=" + HttpUtility.UrlEncode(page1.ToString()));
Console.WriteLine("Page 2: {0}", page2);


var page2ReturnUrl = HttpUtility.ParseQueryString(page2.Query)["returnUrl"];
Console.WriteLine("Return to page 1 from page 2: {0}", page2ReturnUrl);

var page1ReturnUrl = HttpUtility.ParseQueryString(page1.Query)["returnUrl"];
Console.WriteLine("Return to page 0 from page 1 : {0}", page1ReturnUrl);

Page 0: http://www.example.com/page0
Page 1: http://www.example.com/page1?paramA=foo&paramB=bar&returnUrl=http:%2f%2fwww.example.com%2fpage0
Page 2: http://www.example.com/page2?paramC=baz&paramD=qux&returnUrl=http:%2f%2fwww.example.com%2fpage1%3fparamA%3dfoo%26paramB%3dbar%26returnUrl%3dhttp:%252f%252fwww.example.com%252fpage0

Return to page 1 from page 2: http://www.example.com/page1?paramA=foo&paramB=bar&returnUrl=http:%2f%2fwww.example.com%2fpage0
Return to page 0 from page 1 : http://www.example.com/page0

This could go on for many levels deep, yet the process for deriving the previous page's URL is always the same -- simply decode the returnUrl parameter.

kspearrin
  • 10,238
  • 9
  • 53
  • 82
2

Try this solution, it work's.

ClassIndex Model:

public class ClassIndex { public int Id { get; set; } }

View:

_Layout.cshtml

<body>

    <a href="/Home/Back/">Back</a>
    <br />
    <a href="/Home/Index/1">Index 1 </a> | <a href="/Home/Index/2">Index 2 </a> | <a href="/Home/Index/3">Index 3 </a>
    @RenderBody()
</body>

Index.cshtml

@model MvcApplication1.Models.ClassIndex @{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_Layout.cshtml"; }

Index @Model.Id

Home Controller

public class HomeController : Controller { string key = "ItemKey";

    public ActionResult Index(ClassIndex idx)
    {
        return View(idx);
    }

    public ActionResult Back()
    {
        var pageNumber = getPageUrl();
        if (pageNumber == "/") pageNumber = "1";

        return View("Index", 
             new ClassIndex { Id = Convert.ToInt32(pageNumber) });
    }

    string getPageUrl()
    {
        Dictionary<int, string> items = (Dictionary<int, string>)ControllerContext.RequestContext.HttpContext.Items[key];
        var lastItem = items.LastOrDefault();
        var returnUrl = lastItem.Value;
        if (string.IsNullOrEmpty(returnUrl)) returnUrl = "1";

        items.Remove(lastItem.Key);

        return returnUrl.Replace("/Index/", "");
    }
}

Global.asax

Delcare this variables.

IDictionary indexes = new Dictionary(); int counter = 0;

Application_BeginRequest: The event occurs when new request is triggred.

 void Application_BeginRequest(object sender, EventArgs e)
        {
            var key = "ItemKey";
            if (!HttpContext.Current.Request.RawUrl.Contains("Back"))
            {
                indexes.Add(++counter, HttpContext.Current.Request.RawUrl.Replace("/Home", ""));
            }
            HttpContext.Current.Items[key] = indexes;
        }
Kamalesh
  • 21
  • 3
  • 2
    Apart from using the javascript code history.go(-1), this solution gives more control to the functionality. – Kamalesh Jun 19 '15 at 10:17