Custom cache not caching querystring - asp.net

I'm using custom cache on a page, leaving a timestamp to follow cached versions.
I have
<%# OutputCache Duration="1200" VaryByParam="None" VaryByCustom="myCache" Location="ServerAndClient" %>
on the page, and the code-behind of Global.asax has (simplified)
Public Overrides Function GetVaryByCustomString(context As HttpContext, arg As String) As String
If (arg = "myCache") Then
If context.Request.QueryString("Type").ToString() = "1" Then Return "cache-1"
If context.Request.QueryString("Type").ToString() = "2" Then Return "cache-2"
If context.Request.Cookies("Type").Value = "1" Then Return "cache-1"
Return "cache-2"
End If
cache-2 is default state for when no querystring request has been made and cookie doesn't say otherwise. The page saves the cookie with value of Type.
When I call the page with either ?Type=1 or ?Type=2 the page isn't saved to cache - each refresh the timestamp changes.
I found that if I call the page without the Type parameter cache is saved and then exists when I call the page with the parameter as well.
Is there an explanation? Moreover - in Global.asax I couldn't access Response object or file system to log what's happening. Is there a way?
UPDATE
e.g. calling <url>?Type=1, then <url> gives me cache for next calls of <url>?Type=1, but gives same cache for <url>?Type=2.
UPDATE
I now have Return "cache" & context.Request.QueryString("Type"). While sending a request without Type in the querystring gives a cached version of the page, sending Type does not cache, though the result (cache1 or cache2) is the same and page should get cached.
follow up
I've found sending Type=3, or anything besides 1 and 2 does cache the page as desired. Page_Load acts upon values 1 & 2 - could there be any connection?

Answers to this question seem to explain a lot. Workaround is a separate question.

Related

Property in viewstate different on one page to another

This is really weird error i'm getting and i'll try and explain as best I can.
I have two pages - Page 1 (form) and Page 2 (completed page)
From page 1 I put a variable into a database and then do a server.transfer to page two like so...
Server.Transfer("Page2.aspx", True)
On page 2 I then grab the variable called paymentOnHold which is set on Page 1 and goes into the database...
Here is how I set paymentOnHold on Page 1
Public Property paymentOnHold() As String
Get
Dim _paymentOnHold As Object = ViewState("paymentOnHold")
If _paymentOnHold IsNot Nothing Then
Return CType(_paymentOnHold, String)
Else
Return Nothing
End If
End Get
Set(ByVal value As String)
If Not String.IsNullOrEmpty(value) Then
ViewState("paymentOnHold") = value
Else
ViewState("paymentOnHold") = Nothing
End If
End Set
End Property
...
paymentOnHold = Date.Now.ToString("yyyyMMddHHmmss")
Here's how I grab the value on Page 2...
Dim myValue As String
If TypeOf PreviousPage Is Page1 Then
myValue = DirectCast(PreviousPage, Page1).paymentOnHold
End If
In my development environment where the databases are local the value in the DB and the value on page 2 both match - as you would expect...
In live environment the DB value is 3 or 4 seconds different (before) the one on Page 2 - even though I do not reset it or anything?
This has been driving me crazy for the last few hours and cannot work it.
Does anyone have any ideas/suggestions as to what might be causing this?
Thanks in advance
This could be an issue of saving the view state in first Page (form-1)
In asp.net Page lifecycle
1. Initalization (controls raise their Init event)
2. Load ViewState (Only on post back)
3. Load PostbackData
4. Load
5. Raise PostbackEvent
6. Save View State
7. Render
Server.Transfer() stops rendering the current page and starts rendering another one.That's why Server.Transfer() cannot be used to redirect to pages served by another server.
If you are doing Server.transfer before Event--> 6. Save View State you are not saving viewstate on the form-1
Solution
Response.redirect and session cache, as it is intended to exist per user and across multiple pages in the application.
Using ViewState in this manner is a brittle solution, because ViewState is not intended to exist outside of the scope of the page it was initiated in, much less passed between pages, which I realize you are not quite doing, but you are getting dangerously close to doing it.
The better approach is to use Session cache, as it was intended to exist per user and span multiple page requests.
Try this:
To store in Session, do this:
Session("PaymentOnHold") = [Date].Now.ToString("yyyyMMddHHmmss")
To retrieve a value from Session, do this:
' First check to see if the value is in Session cache or not
If Session("PaymentOnHold") IsNot Nothing Then
' Everything in Session cache is stored as an object so you need to cast it to get it out
Dim datePaymentOnHold As DateTime = TryCast(Session("PaymentOnHold"), DateTime)
End If
Now the Session value will be available no matter how you navigate to pages (Server.Transfer or Response.Redirect).

Passing data between different URLs

I need to check where did the incoming request came from before loading a page
ex:
for user to view www.mysite/page1.aspx
request should come through www.othersite/page1.aspx
so on page1 load in mysite i need to check whether the request came from page1 in othersite.
i have tried Page.Request.UrlReferrer but i saw there some posts which tells every browser might not support Page.Request.UrlReferrer.
i can not pass visible parameters on URL.
This is a common issue when you do not want to allow request from arbitrary sites.
What you can do is, create a variable in session and put this variable in the Page1.aspx. When the page posts back, you should get that variable back and it should also match the one stored in the session. If it does not, you can be sure that the request is from some other server.
You can use PostBackUrl on the start page
And access your parameters with PreviousPage in the arrived page
if (this.PreviousPage != null)
{
var control = Page.PreviousPage.FindControl("..."); //Adjust your Id and add cast
}
Nota : This was also created to provide greater security redirection setting.

Why is the Request.Form.AllKeys collection empty after a POST and Redirect?

I have an aspx page where I want to post values to a new page and then redirect to that new page. I don't get any errors and the redirection occurs but the AllKeys collection is always empty.
Here's an example of my code:
Try
With strPost
.Append("User=" & strUserName)
.Append("&Session=" + strValue)
End With
Dim objRequest As Net.HttpWebRequest = _
Net.WebRequest.Create("http://localhost:57918/testproject/test.aspx")
With objRequest
.Method = "POST"
.ContentType = "application/x-www-form-urlencoded"
.ContentLength = strPost.ToString().Length
End With
Dim objStream As IO.StreamWriter = _
New IO.StreamWriter(objRequest.GetRequestStream())
objStream.Write(strPost.ToString)
objStream.Close()
Catch ex As Exception
Debug.Print(ex.Message)
Exit Sub
End Try
Response.Redirect("http://localhost:57918/testproject/test.aspx")
I have seen a few articles similar to this problem but none of them have helped. What am I doing wrong?
Why don't you just have your main page post directly to this other page?
If the process is:
Page A rendered to client
Client posts back to Page A
Page A code behind generates a request to Page B
Page A code behind redirects user to Page B
Page B rendered to client
Then between steps 4 and 5 you will lose all the post params. That's just how it works.
However, you could do the following:
Page A rendered to client, with the form post action set to Page B
Clients enters information and clicks submit
Post values go to page B for handling.
Another path would be to have Page A perform a redirect and pass the values on the query string. For example, Response.Redirect("/PageB.aspx?param1=value&param2=value")
If I'm correct in understanding this, you are expecting the POST values to be available in /testproject/test.aspx after the redirect.
Unfortunately it won't work like that. When you perform the WebRequest it's a one-shot post. A new request is created your page executes and then the request ends and all data associated with that page will be discarded.
When you redirect at the end of the example given that is a completely new GET request to a new instance of test.aspx. Your previous request's POST data will never be available.
You can either:
Redirect to the page and pass the User and Session values in the querystring
Store User and Session in the Session collection then redirect
If strUserName and strValue originate from another postback your could use Server.Transfer to transfer control to test.aspx and keep the current request's Form and QueryString collections intact.
The code above will result in two requests being made to http://localhost:57918/testproject/test.aspx
The webserver itself POSTs the values to the url. When the page runs this time the AllKeys collection will contain the values you posted.
The client's web-browser will perform a GET request against the page. Nothing will be posted. This time the keys will be blank.
In order to pass the parameters to the other page you could encode the values in the redirect URL:
Dim url as String = "http://localhost:57918/testproject/test.aspx"
url = url + "?User=" + strUserName
url = url + "&Session=" + strValue
Response.Redirect(url)
The values would then be available using the request object (e.g. Request["User"]).
update
If you don't want to show the data to the user; then you've really only got two other options:
Move the processing that was being carried out by test.aspx to the page that was generating the original query.
Save the User and Session values the the session state.

Server.Transferrequest() and getting the current URL

Say in my 'Page_init()' of "a.aspx" i just have 'server.transferrequest("b.aspx").
This works great, displays the content for "b.aspx" and the browserurl still stays at "a.aspx".
Happy days.
However does anyone know how to see this url from my "b.aspx" (the resulting page)?.
The usual request.rawurl and request.url.absoluteuri both return the current page as "b.aspx".
Server.TransferRequest performs an asynchronous execution of the specified URL. This means that your client has no clue of was is going on at the server so from your client perspective it's the same page.
If you need to change the actual page (which is the most common) then use Response.Redirect.
Maybe before you do the transfer you could save the information you need somewhere, then retrieve it when it's needed again.
You can use PreviousPage to get source page that makes server transfer :
string previousPagesUrl = PreviousPage.Request.RawUrl;
EDIT : #maxp, as an answer to your comment, PreviousPage only works for Server.Transfer and cross page postback.
You'll get null for PreviousPage if :
the source page redirects to the destination page.
a link at source page forwards the page to destination page.
NameValueCollection headers = new NameValueCollection();
headers["RawUrl"] = HttpContext.Current.Request.RawUrl;
Server.TransferRequest("b.aspx", true, null, headers);
And then use Headers["RawUrl"] in b.aspx.
Have you tried this method:
public void Transfer(string path, bool preserveForm )
http://msdn.microsoft.com/en-us/library/caxa892w.aspx
I currently got in the same problem, and I found out that Server object has this parameter on transfer method that gives you the posibility to preserve the original request form or not.

Setting cookie by calling webpage by Microsoft.XMLHTTP

The situation:
I have 2 webpages with 2 domains (backoffice.myurl.com & www.myurl.com).
The backoffice is written in classic asp, the frontend in asp.net 3.5 (vb.net)
When I hit a button in the backoffice, I want to set a cookie on the frontend.
I do this by calling a page on the frontend via Microsoft.XMLHTTP
Dim GetConnection
Set GetConnection = CreateObject("Microsoft.XMLHTTP")
GetConnection.Open "POST", webserviceLocation, False
GetConnection.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
GetConnection.Send("data=" &value)
In the aspx code I read the posted value and put it in a cookie:
If Not Request.Cookies("mytest3") Is Nothing Then
Response.Cookies("mytest3").Expires = Now.AddYears(-23)
End If
Response.Cookies.Set(New HttpCookie("mytest3", Request.Form.Item("data")))
Response.Cookies("mytest3").Expires = DateTime.Now.AddYears(30)
On another page on the frontend I want to read that cookie:
Request.Cookies("mytest3").Value
but the Request.Cookies("mytest3") is 'nothing' there.
Apparently the cookie is not set. What am I doing wrong or how can I solve this?
The pages are called (my debugger hits the breakpoints)
Is this even possible at all?
When creating the cookie you need to explicitly set the domain:
' I do not remember if the value should be set to myurl.com or .myurl.com
' Please test
Response.Cookies("mytest3").Domain = "myurl.com"
This way the browser will send the cookie along each request to *.myurl.com
Darin has answered your question but you have another problem with this line:-
Response.Cookies("mytest3").Expires = Now.AddYears(-23)
The response Cookie collection is a differentc collection to that of the Request collection. The response cookies is always empty until code specifically adds a cookie to it. Hence the above line will fail.

Resources