I have a .Net 3.5 website which uses windows authentication and expires the session using a meta tag on the prerender of my base masterpage class.
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
if (Response.ContentType == "text/html")
this.Page.Header.Controls.Add(new LiteralControl(
String.Format("<meta http-equiv='refresh' content='{0};url={1}'>",
SessionLengthMinutes * 60, SessionExpireDestinationUrl)));
}
This works well for pages that do full post backs. However there are a few pages in my application where the user does a lot of work that is inside of an update panel. My company's policy is a timeout of 15 minutes. Which means, after 15 minutes of working inside of an update panel page, the user gets redirected to the application splash page.
Is there a way to reset or extend the meta tag on an async postback? Or perhaps a better way to accomplish this entirely?
A better way to accomplish this entirely would be to use javascript. This will prevent meta refresh related issues if your page is bookmarked.
In place of the page META REFRESH use this javascript:
<script type="text/javascript">
var _timerID = setTimeout("window.location='splash-url'", 900000); //15 mins
</script>
When you make a request from the update panel use this javascript:
<script type="text/javascript">
clearTimeout(_timerID);
_timerID = setTimeout("window.location='splash-url'", 900000); //15 mins
</script>
In the past I have used the WebMethod(EnableSession = true) attribute on the methods that respond to AJAX calls
You could use an AJAX request to keep the session alive as well. This will work as long as the user has opened your page in the browser.
See http://808.dk/?code-ajax-session-keepalive
Related
I've created a socket listener, and I need to display a div (keep it hidden, then make it visible), when the server detects a certain socket data.
I've tried to use a thread, but it doesn't update the UI in realtime, only if the page is reloaded or if you do a post back.
Here is an example of what I want to do, in this case I only want to update a textbox with codebehind data, I would like to do it without ajax, javascript or jQuery, if possible.
Code Behind:
protected void Page_Load(object sender, EventArgs e)
{
Thread t = new Thread(TestThread);
t.Start();
}
private void TestThread()
{
for (int i = 0; i <= 1000000000; i++)
{
myTextbox.Text += "1";
}
}
Webpage:
<asp:UpdatePanel runat="server" ID="myPanel" >
<ContentTemplate>
<asp:TextBox runat="server" ID="myTextbox" />
</ContentTemplate>
</asp:UpdatePanel>
what you are trying to do is change the UI (modify client components) from server code (code behind) in asp.net when the server already sent the data to the client.
you have to use client side scripting/coding.
As far as I know, this is not possible without using ajax or JavaScript.
ASP.NET is only responsible for generating the html that is sent from your web-server to the client. Once that html is rendered in the browser, the only way to update the html is via JavaScript.
You can do a Partial Render in WebForms using their AJAX handler without having to write jQuery by enabling a partialRenderingEnabled attribute in the ScriptManager tag. There's no way to do this without scripting or AJAX, the content has to get back to the server to run your code-behind somehow, but at least this way you don't have to write any JavaScript yourself.
For real-time web functionality check out :
SignalR
In a web enviornment, there is no way for the server side to reach out for the client except in the request-response scenario, where the client has to send a request to the server side, the server side handles the request and replies with a response.
EDIT :
SignalR uses the best available technique, websockets when available, if not, AJAX long polling technique in which the client polls(sends a request) to the server, and the server replies only when a certain change to the observed data happens, else SignalR tries repetitve AJAX requests, polling the server over and over until the server replies with the change on the observed data (Worst scenario !).
Also, HTML 5 contains web-sockets, i don't have enough information about it, but it maybe interesting to check out.
With minimal JavaScript you could utilise Server Sent Events for simplex data (from server to client) It doesn't have the overhead of Websockets which has a bit of cost in terms of establishing a connection. However I don't think all browsers are supported but there might be polyfill available for it (library to provide functionality in absence of native support)
Checkout:
http://www.html5rocks.com/en/tutorials/eventsource/basics/
In ASP.NET Threads gets aborted as soon as the page unloads, so this is not possibler you way, sorry.
Your approach could be using AJAX to poll the status from the server on regular intervals. Server on the other hand, will reply according to change in data.
in your ASP.NET Page, add the following script
<head>
<script type="text/javascript" language="javascript">
function poll()
{
var ajax;
if(window.XMLHttpRequest)
ajax = new XMLHttpRequest();
else
ajax = new ActiveXObject("Microsoft.XMLHTTP");
url = "yourPageOrHandler.aspx";
ajax.onreadystatechange = function()
{
if (ajax.readyState == 4 && ajax.status == 200)
{
// success
var receivedText = ajax.responseText;
}
else
{
// error, do the needful
}
}
ajax.open("GET", url, true);
ajax.send();
setTimeout("poll()", 1000); //polls every 1 second, you can change the duration here.
}
</script>
</head>
Start the polling before page finishes
<body>
.
.
.
.
<script type="text/javascript" language="javascript">
poll();
</script>
</body>
Alternatively, you can use the ASP.NET AJAX controls, but that will be heavier compared to JavaScript AJAX.
Glad to help! Please remember to accept the answer if you found it helpful.
I am using MVC2 and VS2010.
We have created a web application but want to stop any browser re-visiting pages after the page has been left.
We want to do this so that someone who is using a public computer who then leaves can feel safe. We dont want the scenario that a following user can just use the back button to view the first uses pages.
I have tried [OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
This seems to work fine and I get a Web Page Expired. But if I press the browser back button again, the page will be displayed.
I have quite a similar situation myself in wanting to prevent a browser back situation and have researched a few different solutions. The first and worst being a Java script function which takes the user back to the page they were on if they click the back button in the browser. It hides the problem rather than solving it but thought id mention it. The code as follows:
<script type="text/javascript" language="javascript">
function disableBackButton() {
window.history.forward()
}
disableBackButton();
window.onload = disableBackButton();
window.onpageshow = function (evt) { if (evt.persisted) disableBackButton() }
window.onunload = function () { void (0) };
</script>
This works for Firefox, Chrome and IE ok. You can just put this in your master page.
Many people will tell you this is not the way to do things however as it intrudes on the well known browser behaviour etc etc
So my second suggestion is something I have seen here:
Disable browser cache for entire ASP.NET website
Which will not cache anything which is more inline with what you are wanting I think.
Another idea would be to pass a page or session token around and on actions check the token - if its invalid reroute to an error page. That would at least prevent a new user doing anything with the previous page.
Id be interested to know how you solved this, if you have solved it.
We have a function that changes the iframe height at the window.onload event so we can adjust it to the page contents. The problem is that after clicking in an asp:menu the height its restored to its default and the window.onload event doesnt fire...so we need the event that would fire in subsequent loads (tried window.unload but didnt trigger)
The resize function cant be called on the asp:menu click because the window wouldnt have finished loading so the height calculation would fail...
Any ideas??
ASP.Net AJAX exposes a client event model. To execute code after the content is refreshed, use this to bind to the pageLoaded event:
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(pageLoadedFunction);
Learn more about all of the ASP.Net AJAX JavaScript events here: http://msdn.microsoft.com/en-us/library/bb386417.aspx
ASPNet uses background calls via AJAX and then updates the interface.
You should use servr-side code. Inspect the AJAX resolver you're using and look for its declared events. I'm sure there's one event that triggers after updating a webpage and you can attach an eventListener to it.
I had this same problem with a similar script 2 years ago. I solved it using JavaScript in the newly loaded page's window.onload to call up to the parent document and execute the script. In the child page we had this script:
function goSetHeight(){
if (parent == window) return;
else parent.setIframeHeight('iframe_name');
}
// Edit: Forgot to add the window.onload call
window.onload = goSetHeight;
This script called up to the parent page where we had a script file included that had this function:
function setIframeHeight(iframename) {
var iframeEl = document.all[iframename];
var iframeWin = window.frames[iframename];
if(iframeEl && iframeWin) {
//var docHt = getDocHeight(iframeWin.document);
//if(docHt) iframeEl.style.height = docHt + 30 + "px";
iframeEl.style.height = iframeWin.document.body.offsetHeight + 30 + "px";
}
}
Please note that the above function was written solely with IE in mind (it was an application specification), so to be usable cross browser it would need modification. The only real problem we encountered with it were 2 particular cases:
We had a couple of instances where the pages that were loaded in the iframe were from a different domain than the page holding the iframe. This causes a JavaScript security error because the browser thinks this is an XSS attack and denies it.
We also encountered several situations where the iframe was nested 2 deep. It was a hack-job work-around that I came up with that I was extremely unhappy about, but it worked while we refactored from classic asp into .Net. I have since lost the script that was used to perform the pass through, but it wasn't complicated, it simply performed a similar parent check and kept going.
In the end we used a hiddenfield where we saved the height calculated in the window.onload
document.getElementById("iframex").value = document.getElementById("iframeheight").height;
...then in the Menu1_MenuItemClick(object sender, MenuEventArgs e) we reassigned the height to the iframe: iframex.Attributes["height"] = iframeheight.Value;
This works for us (Because in our case luckily the page height doesnt change on each option selected) but doesnt resolve the original question about getting fired the window.onload event or something similar after subsequent loads in order to recalculate the new height...
We will wait so someone can give the best answer to this problem...
Hai frnds..How to add the Ajax Timer Control in Master Page. Its Possible? In my application I added but the event is not fired. can any one help me plz
It may be easier to use standard javascipt intervals to initiate ajax events? We will need more info on the problem.
You could try something like:
when page loads call, showAlert()
function showAlert()
{
alert("Hello Users");
setTimeout('showAlert()', 10000);
}
I'm writing a program which has both an ASP.NET configuration system and a Silverlight application. Most users will remain on the Silverlight page and not visit the ASP.NET site except for logging in, etc.
The problem is, I need the session to remain active for authentication purposes, but the session will timeout even if the user is using the features of the silverlight app.
Any ideas?
On the page hosting the silverlight control, you could setup a javascript timer and do an ajax call to an Http Handler (.ashx) every 5 minutes to keep the session alive. Be sure to have your Handler class implement IRequiresSessionState.
I recommend the Handler because it is easier to control the response text that is returned, and it is more lightweight then an aspx page.
You will also need to set the response cache properly to make sure that the browser makes the ajax call each time.
UPDATE
Here is the sample code for an HttpHandler
public class Ping : IHttpHandler, IRequiresSessionState
{
public void ProcessRequest(HttpContext context)
{
context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
context.Response.ContentType = "text/plain";
context.Response.Write("OK");
}
public bool IsReusable
{
get { return true; }
}
}
Then if you use jQuery, you can put this on your host aspx page
setInterval(ping, 5000);
function ping() {
$.get('/Ping.ashx');
}
The interval is in milliseconds, so my sample will ping every 5 seconds, you probably want that to be a larger number. Fiddler is a great tool for debugging ajax calls, if you don't use it, start.
I've actually found a pretty cool hack which essentially embeds an iframe on the same page as the silverlight application. The iframe contains an aspx webpage which refreshes itself every (Session.Timeout - 1) minutes. This keeps the session alive for however long the silverlight app is open.
To do this:
Create an asp.net page called "KeepAlive.aspx". In the head section of that page, add this:
<meta id="MetaRefresh" http-equiv="refresh" content="18000;url=KeepAlive.aspx" runat="server" />
<script language="javascript" type="text/javascript">
window.status = "<%= WindowStatusText%>";
</script>
In the code behind file, add this:
protected string WindowStatusText = "";
protected void Page_Load(object sender, EventArgs e)
{
if (User.Identity.IsAuthenticated)
{
// Refresh this page 60 seconds before session timeout, effectively resetting the session timeout counter.
MetaRefresh.Attributes["content"] = Convert.ToString((Session.Timeout * 60) - 60) + ";url=KeepAlive.aspx?q=" + DateTime.Now.Ticks;
WindowStatusText = "Last refresh " + DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString();
}
}
Now, on the same page as the silverlight app, add this:
<iframe id="KeepAliveFrame" src="KeepAlive.aspx" frameborder="0" width="0" height="0" runat="server" />
Now the asp.net session will remain active while the silverlight app is being used!
The ajax ping / HttpHandler approach is good, but the JQuery $.get function is expecting a json result and throws a javascript parse error.
I modified the Ping HttpHandler to return "{}" instead of "OK" and this worked better.