I have a web form of Asp.Net, in which I want JavaScript to count how many time i have refreshed the page.
If you want to do it on clientside just save (and retrieve) the information on localstorage every time load event occurs
Do you want to count this per user ? Or for whole application ?
If you are doing for whole application you can use application variable in Global.asax on each page request . But that might get lost if your application recycles .
If you want to do for each user You can use server side sessions or cookies on clientside .
You can set the value in a cookie using js or asp, or in a session value (for a single user) or in application value (for all the users), is not necessary javascript.
You have to put this code server side on page load.
For all users:
Application["refresh_count"] =
Convert.ToInt64(HttpContext.Current.Application["refresh_count"]) + 1;
For a single user with session:
Session["refresh_count"] = Convert.ToInt64(Session["refresh_count"]) + 1;
OR
Response.Cookies["UserSettings"]["refresh_count"] = Convert.ToInt64(Response.Cookies["UserSettings"]["refresh_count"]) + 1;
Response.Cookies["UserSettings"].Expires = DateTime.Now.AddDays(1d);
You can save this in the Session Object.
You can use jQuery calling prepared address.
For example:
$.ajax({
url: ".../countPageRefreshes.aspx",
data: { page: "thisPageAddress" }
})
Then, in countPageRefreshes you can increase number of times, page was refreshed and save it somewhere.
Related
We have a website in classic asp that we are slowly migrating to ASP.NET as necessary.
The problem of course is how classic asp and ASP.NET handle Sessions. After spending the last few hours researching the web, I found many articles, but not one that stood out over the others.
Is there a best practice for transferring session variables from and to classic asp and asp.net? Security is a must and any explanation with examples is much appreciated.
A simple bridge to pass a single session variable from classic asp to .net serverside (hiding your sessionvalue from the client), would be this:
On the ASP end: An asp page to output your session, call it e.g. asp2netbridge.asp
<%
'Make sure it can be only called from local server '
if (request.servervariables("LOCAL_ADDR") = request.servervariables("REMOTE_ADDR")) then
if (Request.QueryString("sessVar") <> "") then
response.write Session(Request.QueryString("sessVar"))
end if
end if
%>
On the .net end, a remote call to that asp page. :
private static string GetAspSession(string sessionValue)
{
HttpWebRequest _myRequest = (HttpWebRequest)WebRequest.Create(new Uri("http://yourdomain.com/asp2netbridge.asp?sessVar=" + sessionValue));
_myRequest.ContentType = "text/html";
_myRequest.Credentials = CredentialCache.DefaultCredentials;
if (_myRequest.CookieContainer == null)
_myRequest.CookieContainer = new CookieContainer();
foreach (string cookieKey in HttpContext.Current.Request.Cookies.Keys)
{
' it is absolutely necessary to pass the ASPSESSIONID cookie or you will start a new session ! '
if (cookieKey.StartsWith("ASPSESSIONID")) {
HttpCookie cookie = HttpContext.Current.Request.Cookies[cookieKey.ToString()];
_myRequest.CookieContainer.Add(new Cookie(cookie.Name, cookie.Value, cookie.Path, string.IsNullOrEmpty(cookie.Domain)
? HttpContext.Current.Request.Url.Host
: cookie.Domain));
}
}
try
{
HttpWebResponse _myWebResponse = (HttpWebResponse)_myRequest.GetResponse();
StreamReader sr = new StreamReader(_myWebResponse.GetResponseStream());
return sr.ReadToEnd();
}
catch (WebException we)
{
return we.Message;
}
}
I've used an ajax bridge (for want of a better term), specifically, a classic asp page that reads all session vars into a database with a guid, it then redirects to a .net page passing the guid in the querystring, the asp.net page reads from sql for the given guid and created those vars as sessions.
Eg, in classic asp (pseudocode code - just to give you an idea, use parameterised queries in yours etc):
'#### Create GUID
Dim GUID 'as string
GUID = CreateWindowsGUID() '#### Lots of methods on http://support.microsoft.com/kb/320375
'#### Save session to sql
For Each SessionVar In Session.Contents
db.execute("INSERT INTO SessionBridge (GUID, Key, Value) VALUES ('" & GUID & "', '" & SessionVar & "', '" & session(SessionVar) & "')")
Next
Then, in a .net page:
'#### Fetch GUID
Dim GUID as string = Request.QueryString("GUID")
session.clear
'#### Fetch from SQL
db.execute(RS, "SELECT * FROM SessionBridge WHERE GUID = '" & GUID & "'")
For Each db_row as datarow in RS.rows
Session(db_row("Key")) = db_row("Value")
Next
As i say, this is very rough pseudocode, but you can call the asp with a simple background ajax function, then call the .net page for the given GUID.
This has the advantage of not exposing all your vars and values to the client (as post methods do etc).
They use different sessions, so you'll need to devise some way of transferring the vars yourself. You could include them in cookies, or send them via HTTP POST (i.e. a form with hidden fields) to the asp.net side.
Alternatively, you could scrap using session storage and stick everything in a database for each user/session, then just pass a session key from classic ASP to ASP.NET via one of the above suggestions. I know this sounds like you're reinventing the wheel, but this might be one of those cases where you just can't get around it.
I have a website that does that exact action. The secret is to use an intermediate page with the asp function response.redirect
<%
client_id = session("client_id")
response.redirect "aspx_page.aspx?client_id=" & client_id
%>
This is an example to pull the classic asp session variable client_id and pass it to an aspx page. Your aspx page will need to process it from there.
This needs to be at the top of a classic asp page, with no HTML of any type above. IIS will process this on the server and redirect to the aspx page with the attached query string, without sending the data to the client machine. It's very fast.
In case anyone else stumbles here looking for some help, another possible option is to use cookies. The benefit of a cookie is that you can store reasonable amounts of data and then persist that data to your .Net application (or another web application). There are security risks with exposing a cookie since that data can be easily manipulated or faked. I would not send sensitive data in a cookie. Here the cookie is only storing a unique identifier that can be used to retrieve data from a table.
The approach:
Grab the session data you need from your classic asp page. Store
this data in a table along with a unique hash and a timestamp.
Store the value of the hash in a short-lived cookie.
Redirect to whatever page you need to go and read the hash in the cookie.
Check that the hash in the cookie hasn't expired in the database. If it is valid, send back the data you need to your page and then expire the hash so it can't be reused.
I used a SHA 256 hash that was a combination of the user's unique identifier, session ID, and current timestamp. The hash is valid for only a few minutes and is expired upon reading. The idea is to limit the window for an attacker who would need to guess a valid hash before it expired.
I am creating an online quiz application and need server side timer. For example if the user opens another browser or refresh the page or leave and back time shoud be proper.
Now i am using jquery timer and in every 5 minutes send ajax request to store proper information into the database. Also when the user answers the question i immediately send again ajax requst for the same purpose.
Should i use signalr instead? What would be more proper way to handle server side timer in asp.net mvc?
As long as you have a session, you could simply store the timestamp of when the user began taking the quiz in session state.
You could tell the time of any future event by looking at the timestamp of that event, minus the timestamp of when the user took the survey.
Example (server-side code):
if (Session["startTime"] == null)
{
Session["startTime"] = DateTime.Now;
}
var ticksRemaining = DateTime.Now - Session["startTime"];
// Use ticksRemaining to populate the start value for the count-down timer
// Works just fine even if they reload the page or open a new browser tab.
// You won't catch if they open a brand-new browser and start a new session,
// but that's a different kind of problem.
Lots and lots of examples out there as to how to set and redirect when the session times out. But nothing that I could find for this situation.
A typical situation where a timeout control monitors the session timeout and displays a window warning the user of that when there is 1 minute left. When the session times out, the user is redirected to a page (sessionexpired.aspx) that clears the session and displays information informing the user that they are required to login again.
I would like to log the page the user was on when the session actually timed out and do that in the code behind of the sessionexpired.aspx page.
Any help would be very welcome!
Try looking at the Referer from the current Request object. It's usually found using this:
Request.UrlReferrer
I hope this helps.
You can use one of these code examples to get the current page the user is on:
// Returns something like "http://www.example.com/myUrl/MyPage.aspx"
string page = HttpContext.Current.Request.Url.AbsoluteUri;
// Returns something like "/myUrl/MyPage.aspx"
string page = HttpContext.Current.Request.Url.AbsolutePath;
// Returns something like "MyPage.aspx"
string page = HttpContext.Current.Request.Url.AbsolutePath.Substring(url.LastIndexOf('/') + 1);
So wherever your code is to log you out when your session expires (probably in your master page), just add one of these lines.
Once you have it, you can add it as a query string parameter to your login page or you can save it in a database.
I need to get the url of the site so that I render a user control on only the main page. I need to check for http://foo.com, http://www.foo.com, and foo.com. I am a bit stumped as to how check for all 3. I tried the following which does not work.
string domainName = Request.Url.Host.ToString();
if (domainName == "http://nomorecocktails.com" | Request.Url.Host.Contains("default.aspx"))
{ //code to push user control to page
Also tried
var url = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority) + "/";
Any thoughts?
You need to check if the Request.Path property is equal to / or /Default.aspx or whatever your "main page" is. The domain name is completely irrelevant. What if I accessed your site via http://192.56.17.205/, and similarly, what if your server switched IP addresses? Your domain check would fail.
If you utilize the QueryString to display different content, you'll also need to check Request.QueryString.
Documentation for Request.Path:
http://msdn.microsoft.com/en-us/library/system.web.httprequest.path.aspx
Documentation for Request.QueryString:
http://msdn.microsoft.com/en-us/library/system.web.httprequest.querystring.aspx
If you need the user control to only appear on the main page (I'm assuming you mean home page), then add the code to call the user control to the code behind of that file.
If this code is stored in the master page, then you can reference it like:
Master.FindControl("UserControlID");
If you are only using the one web form (ie. just Default.aspx), then you can check that no relevant query strings are included in the URL, and display only if this is the case:
if (Request.QueryString["q"] == null){
//user control code
}
However if you are using this technique then I would recommend using multiple web forms using master pages in the future to structure your application better.
The ASP.NET website has some good tutorials on how to do this:
http://www.asp.net/web-forms/tutorials/master-pages
I have a web page written in ASP.NET and I need to retrieve the end user's local time at Page_Load. I thought about using Javascript to get the local time (by using new Date()) but the problem is that the script is run after the server events.
Any ideas on how to accomplish this?
EDIT: My page is quite complex: it displays a chart with lots of calculated fields from a database, object/fields selection lists, etc; The customer now requested that it should consider the user's timezone and that the timezone should be determined automatically by the web page. The user date is important to determine the chart interval (which day to display data on).
Data loading (since it is so complicated) is done in both Page_Load and Page_PreRender. Giving up these events would require a full page rewrite.
FINAL SOLUTION INSPIRED BY ANSWER:
Here is how I solved the problem eventually. I am keeping the local date in a cookie. Here is the method that sets the cookie:
function SetLocalDateCookie() {
var cookieName = 'LOCALDATE';
var localDate = new Date();
var realMonth = localDate.getMonth() + 1;
var localDateString = localDate.getFullYear() + "/" + realMonth + "/" + localDate.getDate();
setCookie(cookieName, localDateString, 2);
try {
var exdate = new Date();
exdate.setDate(exdate.getDate() + 2);
document.cookie = cookieName + "=" + escape(localDateString) + ";expires=" + exdate.toGMTString();
}
catch (e)
{ }
}
In my Master page I call this method on $(document).ready.
On the page where I use this cookie I added the following code to Page_Init:
if (string.IsNullOrEmpty(CookieHandler.Instance.GetCookie(CookieKeys.LocalDate)))
{
Response.ClearContent();
Response.Write(#"<form id='local' method='post' name='local'>
<script type='text/javascript'>
SetLocalDateCookie();
document.getElementById('local').submit();
</script>
</form>");
Response.Flush();
Response.End();
}
Then I can just use the cookie value in the C# code.
Thank you for your answers/comments!
I'll explain a bit the following code and what lefts for you to do.
At the first request off this page, the code checks if the LocalTime is not already stored in Session and if not it will write a form element, a hidden input and a javascript which will post that form with the local time. The response ends, so your report won't get the chance to be generated.
This submit will immediately create a POST request with the localTime set, then ASP .Net stores this POST value into the Session.
I also added a 302 redirect (Response.Redirect) to the original page, because of the usability. The User made initially a GET request, not a POST, so if he/she wants to refresh the page, the browser will reiterate the last action, which was that form.submit() and not the GET request.
You have now the local time. But you don't have to read it at every request since it can be compared to the UTC time, then with the server's time.
edit: You need to parse the UTC time into a DateTime, but probably it's easy to find the format, though might depend on the user's culture (not sure about this statement).
public ReportPage()
{
this.Init += (o, e) =>
{
// if the local time is not saved yet in Session and the request has not posted the localTime
if (Session["localTime"] == null && String.IsNullOrEmpty(Request.Params["localTime"]))
{
// then clear the content and write some html, a javascript code which submits the local time
Response.ClearContent();
Response.Write(#"<form id='local' method='post' name='local'>
<input type='hidden' id='localTime' name='localTime' />
<script type='text/javascript'>
document.getElementById('localTime').value = new Date();
document.getElementById('local').submit();
</script>
</form>");
//
Response.Flush();
// end the response so PageLoad, PagePreRender etc won't be executed
Response.End();
}
else
{
// if the request contains the localtime, then save it in Session
if (Request.Params["localTime"] != null)
{
Session["localTime"] = Request.Params["localTime"];
// and redirect back to the original url
Response.Redirect(Request.RawUrl);
}
}
};
}
I don't think this would be possible, you can't get the time off the client's local machine at server side.
The only way to achieve this would be using some javascript (as this is client based, so it will use the client's current date/time). But as you've stated, this will be after your server events have been ran, and your web page has been rendered into HTML and sent to the client.
One alternative would be to capture the clients time before the Post Back, but it wouldn't be possible to do this with an inital Page_Load.
How about you place a hidden textbox on the page, attach an OnChange-eventhandler to it in C# and use an OnLoad JavaScript function to set the value to the value you need from the client?
As far as I'm aware, there isn't any way to get the users local time in the Page_Load event as that is executed on the server-side, and would therefore only be aware of the server's local date time.
To get the user's local time you would need to either execute an asynchronous call to the server upon the page loading in JavaScript, or store the local time in a hidden field and then read it on post-back.
Or just use an interstitial page that contains nothing but the js to get local time and redirects to your current page passing the time information via query string or session variable or post