Why is Request.QueryString readonly? - asp.net

I thought you couldn't change the QueryString on the server without a redirect.
But this code works* for me:
Request.QueryString edit
I'm so amazed.
So here are my questions regarding this:
Why is Request.QueryString readonly?
Why does this code/hack work*?
How safe is it, if you change to readonly as soon as you are done editing, both regarding bad errors or unexpected behaviour, and regarding maintaining and understanding the code?
Where in the event cycle would it make most sense to do this crazy edit if you are only using PageLoad and OnPageRender?
*More details:
I have a page with items that are grouped into tabs. Each tab is an asp:LinkButton
I want to be able to link directly to a specific tab. I do that with a QueryString parameter 'tab=tabName'. It works. But when I then click a new tab, the querystring is still in the Url, and thus the tab specified in the Querystring gets activated and not the one I clicked.
By using Request.QueryString edit this does not happen. Then my solution 'works'.
Thanks in advance.

Well the QueryString property is readonly because it cannot be changed on a single request. Obviously the browser sends only one request with only one string so only one collection is created. The hack uses reflection (i.e. manipulates the code and the memory) to change stuff that you cannot change normally. This hack breaks the encapsulation and the design of the QueryString property. You should not use it. It makes no sense from design standpoint. Your query DOES NOT change so why change the object that represents it? Only the browser can send new query string so you are basically lying to your own code about what the browser sent.
If you want the tabs to use the URL just use Hyperlinks instead of LinkButton.

From what I remember reading, this is a security standard that all browsers adhere to. It's main purpose is to stop phishing attacks, where someone could have the website www.MyLameWarcraftPhishingSite.com" and when someone hits the page, rewrite the url to look like www.blizzard.com. The only way to get to that url is to actually redirect to it.
mmm, last post was in Feb 11 - hope its ok to post in this.

Related

disable a direct access to a specific web page in ASP.NET

Is there a trusted way to disable the direct access to an special web page? I mean I want to open it only by clicking on a Button for example. I know I can access to the webpage by using this code but It can not prevent accessing to the web page directly (Pasting the url or typing it):
Response.Redirect("~/Code.aspx")
Thanks
This is a long shot because I don't have the time to test this now (I can see some downvotes coming already!), but...
In the "Code.aspx" page, check for Session["allowed"]. If the value is not there, end the response.
Next, make another page (from where Code.aspx can be accessed). In this page, set Session["allowed"] and then do a Server.Transfer() to Code.aspx, which will then run OK.
Finally, at the end of processing Code.aspx., remember to clear the Session["allowed"] variable again.
Hope this makes even vague sense :)
You may be able to write a piece of code on page load that checks the contents of HttpContext.Current.Request.ServerVariables("HTTP_REFERER") - if it's blank, a user has navigated to the page directly and you can handle it that way.
On the source page create a token into a hiddenfield. To your button add PostBackUrl property and let it point to your destination page.
On the destination page you can validate that the request was made from your allowed source page. And you dont need to use session and all its drawback.
Check this Link for detailed information about how to use the mentioned property.

Possible to only update part of page and change query string parameters at same time in asp.net?

Is there a way to only update part of the page and update the query string parameters at the same time without completely refreshing the whole page in ASP.NET?
I only need to update the "main" section of my page and not the whole page. I understand I can do a partial page postback (or use asp ajax) to do the partial page update, but then how do I update the query string parameters in the URL at the same time? Is that even possible?
Or is it not possible and I'll have to just do a Response.Redirect in the code behind of the partial page postback redirecting to the same page with new query params and just let the whole page refresh?
Use pushState.
This new feature offers you a way to change the URL displayed in the browser* through javascript without reloading the page. It will also create a back-button event and you even have a state object you can interact with.
window.history.pushState(“object or string”, “Title”, “/new-url”);
Described here
You have absolutely zero programmatic access to the address bar. The only way to change it is to redirect.
You could, however, do it like some sites do and provide a "send a link to this page to your friends" area. Youtube comes to mind - see how it provides a URL, querystring parameters included, for you to copy, should you wish to send someone a link to a video starting from some specific point.
Also check the handy "Share" link right under your question. You could provide a link like that, with the target URL, so for the user it's just a matter of right-clicking and copying from the context menu. A link well structured into your site is more user friendly than having the user copy directly from the bar, or from a text box. Specially for mobile browsers, where the sequence is usually press-and-hold, then copy. Copying from the address bar, on the other hand, may involve selecting the address bar text, which in some Android devices is a pain in the ass.

Output caching a page except a user control in it

I have a page which contains a user control. The structure of the page is as shown below:
Incase your not able to see the above image, please check it at http://i54.tinypic.com/2r4id5f.jpg Now, apart from the contents of the UserControl, I'd like to cache the entire page. I tried using the OutputCache attribute in the .aspx page, however it caches the contents of the UserControl as well.
Kindly let me know how will I be able to cache the contents of the page except that of the user control.
Thanks in advance.
I think you can use the asp.net Substitution control to achieve this. Here is a link to ScottGu walking through an example.
The basic idea is that you cache you whole page as per usual, but mark parts for substitution that can be replaced for each request.
I think you are looking for VaryByControl. Also check out this post on fragment caching
Look at using substitutions.
This should help
However, the snag is, since substitution is done outside of the Page lifecycle, you can't render a user control for your substitution. You have to write a method that returns a string for the substitution. But this may work for you.
Have you tried adding the #OutputCache to both the usercontrol and the page but the usercontrol set the varyByParam="qsvalue;postvalue" where qsvalue is a generated query string you make random for every call of the page and postvalue is the same for postback.
The user control will still get cached, but in theory it should never get a chache hit as the qsvalue/postvalue is always different from that cached. It may not scale well - best set duration to the minimum as well, to prevent large numbers of them building up in the cache.

Can a URL change on postback?

I only need to parse URL Request.Querystrings on GET, not on postback, right?
if(!IsPostBack)
{
Viewstate["magic_number"] = Parse(Request.Query);
}
The user can't be expected to modify the URL in the Request for subsequent postbacks, or can they?
Motivation for question-- I don't control the javascript snippet that does the postback, so it's something of blackbox to me.
The URL is not expected to change. But remember that each postback is a new instance of your page class. So if you didn't save the results somewhere on the first view you need to be prepared to do it again on the next one, and so on. In this case you saved it to ViewState, and so that should be fine.
However, I suspect you wouldn't be asking the question unless you had observed behavior that led you to suspect otherwise. So let's consider for a moment what things could cause this to break:
It is possible to modify ViewState at the client where you saved your results (though not trivial and definitely not recommended).
You can fake a postback before the initial page view.
You can use javascript to alter the posted url.
However, for all these things you would certainly know if you have written anything to do that.
Your assumption is correct, the URL is not expected to be modified in subequent post backs and you need to parse the query string only on the GET, which happens the first time the page is loaded.
The URL does not normally change for a postback.
It's of course possible to use a tool like FireBug to edit the URL in the form tag before the postback, but then you probably don't want the value that the user injected anyway, but the original value.
As others have pointed out, The URL is not expected to change. Of course if we lived in a perfect world you would never get email spam and noone would ever attempt to do anything malicious to your website.
In the real world you should expect that malicious people will attempt to hijack your website and need to be concerned with things like injection attacks
You should never make any assumptions that the data received on a postback is valid.

Is there any way to modify query strings without breaking an ASP.Net postback?

From reading here and around the net, I'm close to assuming the answer is "no", but...
Let's say I have an ASP.Net page that sometimes has a query string parameter. If the page has the query string parameter, I want to strip it off before, during, or after postback. The page already has a lot of client-side script (pure JavaScript and jQuery).
As an example, say I load:
http://myPage.aspx?QS=ABC
The QS parameter is necessary to control what appears on the page when it first loads and is set by the page that "calls" it. myPage.aspx has form elements that need to be filled in and has a submit button that does a postback. When the page completes the postback, I need to returned URL to be:
http://myPage.aspx
in order to avoid the client-side code that is called when the query string is present. In other words, after a submit I don't want the client side actions associated with the query string parameter to fire. I know I could append the form contents to the URL as query string parameters themselves and just redirect to the new URL and avoid the submit/postback, but that will require a lot more type checking on the codebehind to avoid bad data and casual spoofing. I supposed I could also set a hidden field in the codebehind and look at it along with the query string to cancel the client-side behavior if I am coming back from the postback, but that still leaves the query string intact basically forever and I want to get rid of it after the initial page load.
Any ideas or best practices?
PS - Is there anything I can do with the Form.Action property that won't break the postback behavior?
I would use an HTTPModule to intercept and rewrite the URL and query as it came in. I'm not 100%, but I don't believe this has any impact with viewstate.
It sounds (and looks) complex, but it's actually fairly trivial and open to a ton of refinement and extension (as per .NET in general).
iam not sure this is what you are looking for, but if understand correctly you could do this:
-on page load check for the QS value, if its not there use a hidden input field.
-first time page loads with QS, do your normal processing and store QS value in a hidden input field.
-if no QS then use the hidden input value
-after postback, you could redirect to the same page, at that point you could user Request.Form[] to retrieve the hidden input field, still load the data properly but get rid of the QS.
it made sense in my head, i am not sure it make sense now, but i'll let you decide.
It is probably bad practice, but in those cases (and ones I just need to 'reset' the page), I simply do a Response.Redirect to the same page.

Resources