简体   繁体   中英

Clever way to store previous url's in querystring (ASP.NET C#)

I'm looking for a clever way to store previous url's (in the correct order) in a value (preferably an integer) that I store in the querystring.

So for example, I have 4 pages. You can navigate from each page to another, also in loops.

public enum Pages
    {
        [Url("/_layouts/A.aspx")]
        A = 1,
        [Url("/_layouts/B.aspx")]
        B = 2,
        [Url("/_layouts/C.aspx")]
        C = 3,
        [Url("/_layouts/D.aspx")]
        D = 4,
    }

The value I want to store in my querystring is for example 'Ref=123456'. From this value I should know what the previous page is, but also what the pages before this were, AND in the correct order!

First I thought about using a Flags enum, but then I got stuck on the loops... You can go from (A->B->C->D->A->C->A->B->A->....)

Anyone who knows a good solution to this?

-- Update --
In this example I use Pages, which isn't maybe the best example (can't come up with something better :-) ), but I do need this in the QueryString, so that I could refer to this from another website

Maybe I am over simplifying this, but why not store them in a list and just keep adding everytime your user goes to a new page just add to your list. Then when you want to figure out where they've been, you just count backwards from the end of the list.

var pages=new List<int>();
pages.Add(1);
pages.Add(2);

int previousPage= pages[pages.count-2];// -2 because -1 would be the last page, I think
MessageBox.Show(previousPage.ToString());

should display 1;

I've written a Navigation framework that might help you, http://navigation.codeplex.com/

First step is to configure your pages:

<state key="A" page="~/A.aspx">
    <transition key="AB" to="B">
    <transition key="AC" to="C">
</state>
<state key="B" page="~/B.aspx">
    <transition key="BA" to="A">
    <transition key="BC" to="C">
</state>
<state key="C" page="~/C.aspx">
    <transition key="CA" to="A">
    <transition key="CB" to="B">
</state>

Then, to move from A.aspx to B.aspx in code:

StateController.Navigate("AB");

To move from B.aspx to C.aspx:

StateController.Navigate("BC");

And to move back from C to A:

StateController.NavigateBack(2);

The number 2 is passed because you need to go back 2 pages, if you wanted to go back from C to B you'd pass 1 instead.

I don't think it does exactly what you want because of the way I handle loops. For example, if you got from A->B->C->B, then I don't allow you to go back to C, only back to A. This is because as soon as I see a repeated page (in this case it's B), then I truncate the history to the original occurrence of that Page (this stops the list getting infinitely long).

If you're interested or want any help, just let me know.

I see two parts to this

  1. getting a list of urls required for the navigation
  2. providing a display of the navigation.

personally I think storing this in the query string is a terrible idea. all you need for the query string is the previous, and next steps key, which could be as simple as the previous and next index in the collection of the urls.

displaying the urls to the user in some manner on screen would provide a nice UX. in which case you would want an enumeration of display text and url. in it's simplest form

var steps = new[] {
    new {Name = "", Url = ""},
    new {Name = "", Url = ""},
    new {Name = "", Url = ""},
    ...
};

this can then be stored in session and used to navigate from one resource to the next. at some point you will need to clear/reset the steps in session.

And as @Pete mentioned in the comments. "Clever" isn't what your looking for. I think what you mean is simple & maintainable :)

Using stack solves the purpose is what i feel, Whenever user navigates from one page to another just push the current page path onto the stack and when user clicks on cancel button, read the previous page from the stack and redirect him there.

Have a class PreviousPath with one property Path in it

public class PreviousPath
{
    public string Path { get; set; }
}

And have a Stack of this class.

System.Collections.Generic.Stack<PageFrame> PageStack { get; set; }

Maintain this stack in a Context.

Push the path when user navigates from one page to another:

public void CurrentPath(string url)
    {
        // Push the current page on to the navigation stack
        if (PageStack == null)
        {
            PageStack = new Stack<PreviousPath>();
        }

        var pageFrame = new PageFrame { Path = url };
        PageStack.Push(pageFrame);
        }

    }

And when you want to go back by one page then just pop the path from the stack:

public string GetPreviousPage()
    {
        string url;
        if (PageStack != null && PageStack.Count > 0)
        {
            url = PageStack.Pop().Path;
        }
        else
        {
            url = "/default.aspx";
        }
        return Redirect(url);
    }

Everyone's suggestions are great, but what I am getting from your question is that, you may want to store this value and in the future read it back.

As above, everyone elses suggestions are great for temporary solutions but not so good when it comes to storing the path with as little information as possible.

That said, using your solution would work, but it would be restricted to a manual set of pages.

With that in mind, I think you were on the right track.

On each page, you will have links to the other pages. You know those pages link to a, b, c or d, so you can do:

<a href="~/a.aspx?Ref=<%= Request.QueryString["Ref"]; %><%= (string)(int)Pages.B; %>">Go to page A</a>

Each page will contain links to the other pages, and you will simply append the current pages ID to the Ref QueryString.

As you move along, it will build the Path for you.

Edit: For reading back purposes, you may have to change it slightly. Instead of having ?Ref=123456789

You may need to separate the pages to prevent single numbered pages conflicting with double numbered pages.

ie ?Ref=1,2,3,4,5,6,7,8

<a href="~/a.aspx?Ref=<%= Request.QueryString["Ref"]; %>,<%= (string)(int)Pages.B; %>">Go to page A</a>

Then you can use:

string[] pages = Request.QueryString["Ref"].Split(',');

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM