Redirect to webapp default document when another page is specified?

IIS6, ASP.NET 2.0, No Forms Authentication

I’m calling Response.Redirect(“~/foo.aspx”), but the default document (“Default.aspx”) for my site is appearing. To make matters worse, it only happens intermittently. Sometimes the redirect displays the right page.

I’ve checked session state, and I don’t see any values in the web.config (that is, I’m assuming I’m using the 20-minute defaults).

I wish I had more relevant information to share (I’ll do my best to answer any questions).

Any ideas? Why isn’t it redirecting to the specified page?

EDIT: I’ve looked deeeeeper into the code and learned more details.

Ok. There’s foo.aspx and foo2.aspx (and the default document, Default.aspx). All pages extend from BasePage, which extends Page.

BasePage has a property named ReturnPage:

protected string ReturnPage {
    get {
        if (Session["ReturnPage"] == null) {
            Session["ReturnPage"] = "";
        }
        return Session["ReturnPage"].ToString();
    }
    set { Session["ReturnPage"] = value; }
}

Users click on a LinkButton on foo.aspx, and the click event handler ends with two lines of code:

ReturnPage = ResolveUrl("~/foo.aspx");
Response.Redirect(ResolveUrl("~/foo2.aspx"));

The Page_Load of foo2.aspx has problems, and its error handling calls Response.Redirect(ReturnPage).

When I view the response headers of foo2.aspx, the 302 location is string.Empty (that is, there isn’t one). That same response header has the same ASP.NET Session ID as the response of foo.aspx.

And remember — this is intermittent. Sometimes, you can click on that LinkButton and go effortlessly to foo2.aspx, no problem. You can process the click with the exact same data once, and it will fail. You’ll navigate from the default document (Default.aspx, where you were sent by the “bug”) back to foo.aspx, click again with the same data (the same row in the grid/table — the same LinkButton, essentially), and you’ll be redirected to foo2.aspx without issue.

Here is Solutions:

We have many solutions to this problem, But we recommend you to use the first solution because it is tested & true solution that will 100% work for you.

Solution 1

Placing a value in the session immediately before a Response.Redirect() is risky.

Changing foo.aspx’s Response.Redirect() to the following might retain the session value more reliably:

Response.Redirect("~/foo2.aspx", false);

UPDATE: This ended up being fixed only by moving our session state into SQL Server. See related question: Why/when are session writes vulnerable to thread termination?

Solution 2

When you say:

Sometimes the redirect displays the right page.

Does it just happen, and you are not sure if there are certain pages that are affected by the problem? If this is the case, then you probably have a addressing problem. You can use either a relative path or an absolute path rather than an Application-relative path. I would also guess that you are trying to either direct to a page from a subdirectory on your site or to a subdirectory on your site. If you choose to stick with the Application-relative path make sure that are taking the subdirectory into account. (ex: ~/FooPages/Foo.aspx)

Here is a good reference page I just found:
http://nathanaeljones.com/129/types-of-asp-net-paths/

Solution 3

I’m a little confused here. What exactly are you trying to accomplish? You’re getting the default document exactly because the 302 is blank. Your “inconsistent” behavior is almost certainly due to the way you are saving data in the Session.

The real issue here is why you’re redirecting when foo2.aspx “has problems”. What’s the problem here? Why redirect? If you really need to redirect, why is the redirect target changed? Make it a static error reporting page and you’ll be fine.

Solution 4

Once you redirect and get a new instance of the BasePage from foo2.aspx, won’t that ReturnPage property be null again? Then once your page load errors out and tries to redirect it will be accessing a null string. Maybe try throwing that property in the Session

Session.Add("ReturnPage","~/foo.aspx") 

instead of

ReturnPage = ResolveUrl("~/foo.aspx");

Ofcourse you would have to modify that error handling in the page load to grab it out of session rather than the property and you may have to rethink how the whole redirect is working in your system if this turns out to be the issue.

EDIT:
To test this idea about the property not getting set, or getting set correctly….(just to test I am not suggesting you should hard code the path in there), change your getter to the example below, then check to see if it works. Hope this helps, I am curious to find out what the problem is if this is not the issue.

get { 
   if (Session["ReturnPage"] == null) { 
        Session["ReturnPage"] = "~/foo.aspx"; 
    } 
    return Session["ReturnPage"].ToString(); 

} 

Note: Use and implement solution 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply