Custom UrlRewriting leads to AjaxControlToolkit UpdatePanels wrong request url on second postback - asp.net

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.

Related

Validation of ViewState MAC failed and Page.MaintainScrollPositionOnPostback

I know there are at least 20 questions related to "Validation of ViewState MAC failed", but mine is a bit unique (at least i think it is)
My website was working fine before I had introduced this code on code-behind of my master page.
protected override void OnInit(EventArgs e)
{
Page.MaintainScrollPositionOnPostBack = true;
base.OnInit(e);
}
This obviously brings a section of a page into view after postback. After adding this code my website starting giving me "Validation of ViewState MAC failed" exception on click of a button which calls the following JS code.
function SelectorSubmitOld(targetUrl) {
var f = jQuery('form').get(0);
jQuery("#__VIEWSTATE").remove();
f.action = targetUrl;
f.submit();
}
As soon as I comment the code written in code-behind of MasterPage, everything comes back to normal.
The following I tried other than the above mentioned (which was obviously not required)
My application is hosted on just 1 server
Machinekey is present in web.config and removing/changing it did not solve my problem
Setting EnableViewStateMAC=false in web.config or at page level did not solve my problem
My question is, I am unable to understand what is the relation between my code and ViewStateMAC?
Please let me know if you need any further information from my side.
Thanks in advance!!
ASP.NET Web Forms (.aspx) pages are meant only to post back to themselves, not to any other page. In your case, you have A.aspx posting to B.aspx by changing the <form action> parameter at submission time.
What's the scenario you're trying to accomplish by changing the POST URL dynamically? Perhaps we can suggest a better way to do this.
From this post, I would try to remove references to postback posiiton with :
function SelectorSubmitOld(targetUrl) {
var f = jQuery('form').get(0);
jQuery("#__VIEWSTATE").remove();
jQuery("#__SCROLLPOSITIONX").remove();
jQuery("#__SCROLLPOSITIONY").remove();
f.action = targetUrl;
f.submit();
}

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 404 page and Invalid Viewstate errors

As you all know it seems like ASP.NET applications is always throwing some Invalid Viewstate errors but now i actually find a way to reproduce one at my site.
What is happening is that a user is trying to access a page that doesn't exist and i do a:
if (CurrentItem == null) {
throw new HttpException(404, "Page not found");
}
This will redirect the user to our custom 404 page. This 404 page is just a regular page in our system that we redirect to via web.config. The search functionality is visible on this page. But when i do a postback from this page the error seems to happen. So if you go to for example.
http://alternativeto.net/software/doesntexist
And then use the search form in the upper right corner and type for example Dropbox, hit enter (if you get a auto-suggestion don't click that cause it will just link you to that app) and baam, you get an error that is "Invalid Viewstate" bla bla.
Anyone know how i can fix this? Is it beacuse how i throw the 404 error? I can imagine it has something todo with the redirect to the custom 404 page and the viewstate and asp.net magic is in some invalid state in some way? Maybe i can change something in my web.config to correct this?
Thanks for any help i can get! Want to get rid of as many errors as possible of course :)
UPDATE
Seems like i solved it myself. When MS had that security bug they recommended to change the error redirect to redirectMode="ResponseRewrite" when i changed it to redirectMode="ResponseRedirect" it seems to work fine!
UPDATE 2
But i also realize that i rather want to have the ResponseRewrite solution since it will stay on that URL that got the error and that is much more cleaner. So i would still be happy to find a solution that works with ResponseRewrite.
A search box should ALWAYS use GET, never POST (!!). So don't use postback for searching, decorate your textbox with a form method="get" action="searchpage" and you are home free, and all your visitors will be happier
I had the same issue, I believe it's because using responseMode="ExecuteURL within <httpErrors> uses Server.Transfer which is why the url will not change from e.g. /contact to /404.
This means the action on the main form will remain as /contact and will postback to that page but since we've transfered to /404.aspx it will throw invalid viewstate.
My solution was to set the form action on prerender of the 404 & 500 pages to the path of the request instead of the RawUrl.
protected void Page_PreRender(object sender, EventArgs e)
{
var form = (HtmlForm)this.Master.FindControl("Form1");
if (form != null)
form.Action = Request.Path;
}
Even though this question is pretty old, I had to post this as it might save someone a few hours of headache in the future.

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

Why does Application_BeginRequest() fire twice when refreshing browser?

I'm observing some really confusing behavior with the Application_BeginRequest event in my Global.asax file (in an ASP.NET MVC app). When running through the debugger, if I Refresh my browser (IE7), this event fires twice. If I click a link or otherwise manually request a page, it fires once - as expected.
Why does a refresh cause BeginRequest to fire twice?
I'm observing this with a brand new MVC project with the following addeded to Global.asax.cs
protected void Application_BeginRequest() {
//executed twice
}
For context, I'm trying to add a new object to the HttpContext.Current.Items collection during this event, so it will persist through the entire request process. Obviously, I don't want this to happen twice for a single refreshed request!
Are you sure it's really 2 request to the same URL? I would think that the second is probably some dynamic JS, CSS or image file. Try to find out either with Fiddler or by looking at HttpContext.Current.Request.Uri in the debugger
Something that surprised me a while back was that if you have an img tag in your html that doesn't have a proper image path, some browsers will make a request to the original page. Here is a related blog post.
I'm not sure why this is occuring but I find it's easier to create a BaseController class and have all my controllers inherit from it. Alter the constructor to add your item to the HttpContext.
Do you have a reference in your HTML to something that also passes the ASP.NET pipeline, like a dynamically generated image or something like that?

Resources