Is there a bug with PostbackUrl and URL Rewriting? - asp.net

I have a page where I set the PostBackUrl property on a login button. I am using the IIS7 Url Rewriting Module. I am also rewriting the Page.Form.Action attribute to match the rewritten url, so that postbacks work properly. When I have the PostBackUrl property set, the page adds a "__PREVIOUSPAGE" hidden input. The problem is that ALL postbacks are now broken, such that the request is seen as a new request, and Page.IsPostback == false. Removing the line of code that sets PostBackUrl fixes all my postback issues.
I don't think I can rewrite the encrypted __PREVIOUSPAGE value to match the current rewritten url, but I suspect that is the issue. Has anyone else encountered and solved this problem?

ASP.NET webforms and url rewriting have never played particularly well. You might want to look at routing, which will work loads better . . .

Related

IsPostback=false even though Request.HttpMethod is "POST"?

I've recently been hacking with webforms seeing if it's possible to use one of my (routing) projects with it. So far, it's been nothing but trouble, but I'm almost to the point that it "works"
I made a page "Test.aspx". At Global.asax, I made it so that it's served at /test instead of /Test.aspx. This works completely. It descends from a custom page class of mine. The custom class finds HtmlForms in the page and rewrites their Action attribute with the proper value: /test.
Now I hit the great brick wall titled Viewstate and ASP.Net events. I added a button to Test.aspx with an OnClick handler. I can click the button, and the page will postback and such, but the OnClick event will not occur. I'm not understanding how a simple URL change can break viewstate like this, as I was not under the impression that Viewstate would track such a thing. Also, IsPostback will be false, even though HttpMethod==true. This is not making any sense to me.
Also, I've disabled EventValidation because I figured that'd be trouble, but this problem persists.
How can I make viewstate and postbacks work as usual when rewriting URLs?
(Note, my form of URL rewriting does all rewriting internally, there is never a HTTP redirect sent to the user)
You might need to tell the HttpContext that the URL is being rewritten as well.
Try doing something like this:
HttpContext.Current.RewritePath("/test");
The IsPostBack is used for check whether the request is from the control of the page itself.
And the HttpMethod is used for check the request type.

Custom UrlRewriting leads to AjaxControlToolkit UpdatePanels wrong request url on second postback

I'm trying to implement custom urlrewriting in the global.asax of my website and i'm experiencing some troubles with updatepanels from the ajaxcontroltoolkit:
second post back of my updatepanels seems to request the wrong url (ie : if my rewrited url is /en-US/parentPage/myPage.html and the physical url is /default.asp?ln=en-US&page=myPage, the second post back request /en-US/parentPage/default.asp?ln=en-US&page=myPage, which leads to file not found ...)
I dont know if it matter but i desactivated the viewstate on the page by setting Page.EnabledViewState to false.
To implement urlrewriting i used Server.Transfert(physicalUrl, true)
Also i tried to set the form action to my rewritted url to solve the problem but then none of the postback are working anymore even those from controls not in an updatepanel.
How can i solve my updatepanels problem ?
Is it possible to do it with form action set to rewritted url ?
Thanks a lot ;)
i find a solution to my problem, it seems the problem came from the viewstate of the page not being reloaded correctly due to the server.transfert so i implemented a custom viewstate save/load functin as follow and then everything worrked perfectly ;) :
protected override object LoadPageStateFromPersistenceMedium()
{
object viewstate = Session["__VIEWSTATE"];
return viewstate;
}
protected override void SavePageStateToPersistenceMedium(object state)
{
Session["__VIEWSTATE"] = state;
}
I found that Server.Transfer() caused this issue. I replaced with Response.Redirect(). Now it is working fine.

why does autopostback from button click duplicate part of url

Example: url is http://www.mydoman.com/test.aspx/88
I click an asp:Button which cause a postback, but now the url comes up:
www.mydoman.com/test.aspx/test.aspx
There is nothing special in the button, just id and runat.
This only happens when I start with the "/88" in the starting url?
Why, and how can I prevent the duplication. After the postback I want the url to be the same as when started.
We probably need more detail to help here.
For example: What is the definition of your form, and do you use any sort of routing?
I don't believe http://www.mydoman.com/test.aspx/88 is valid syntax though, shouldn't it be
http://www.mydoman.com/88 or http://www.mydoman.com/test.aspx?ID=88 ?

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.
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?
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/
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.
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();
}

url rewriting + Asp.Net Login Form = Death

on our site we do url rewriting to generate massive amounts of database generated pages. on every page, there is a Login control for users. like this:
Internal aspx page: /DB.aspx?id=123
User visible url: /ABC/123.aspx, /ABC/456.aspx ... (url rewritten)
unfortunately, the tag on each page has an action attribute of "DB.aspx?id=123". when the user clicks the button the browser is posting to /ABC/DB.aspx?id=123 which of course does not exist.
solutions i tried:
1. change the action attribute by subclassing HtmlForm. this destroys the all other forms on the site.
2. remove the action attribute (so that the browser is always posting to the same url). this works on the rewritten pages but on "/" (the default.aspx in the root dir) i get a message that the verb post is not allowed on "/" (iis 6 and i have no control over mappings)
anybody?
Check this really nice blog post from scott gu, http://weblogs.asp.net/scottgu/archive/2007/02/26/tip-trick-url-rewriting-with-asp-net.aspx.
"Specifically, you can take advantage of the new ASP.NET 2.0 Control Adapter extensibility architecture to customize the rendering of the control, and override its "action" attribute value with a value you provide. This doesn't require you to change any code in your .aspx pages"
Check the section: "Handling ASP.NET PostBacks with URL Rewriting", I have used the adapter he posted successfully.
Ps. be aware there are some issues on asp.net when using url rewrite when using cookieless session, and the rewritten url is deeper than the original page, just like the one you have. (/abc/apage vs. /db?). The issue is right into the source code of the framework, there are workarounds but that's a whole subject (with tradeoffs :( ... you might want to have them at the same level).
Semantics maybe, but does the action attribute = "DB.aspx?id=123" or "/DB.aspx?id=123"? Assuming your URL rewriting allows pass-through to physical pages, this might be your issue.
I never did it, but I saw the code using Reflector and I guess you can fix it this way:
On the page:
this.Form.Action = null;
or:
this.Form.SetAttribute("action", null);
If that doesn't work, just set the path you want:
this.Form.SetAttribute("action", "ABC/123.aspx");
If you upgrade to ASP.NET 3.5 SP1, the action property is now properly recognized and can be set from codebehind.

Resources