How to empty ASP.net postback cache? - c#

I just read What is a postback?
I have an asp.net webform on which I click a button to fill server side C# variables. If I am correct this occurs by an HTTP POST (a postback since I resend the user supplied data with the webform back to the server using the body of the HTTP request)
When the server recieves the postback, it will send some instructions bac to the client (for instance "display an alert message").
My problem here is that when I refresh (F5) the webform, what ever action that was performed last is reexecuted. Hence, a postback is reexecuted when I refresh the page, thus triggering a response from the server.
How can I disable this behavior ? By this I mean that how could hitting F5 just reload the page as if it was the first time (I guess all my code behind variables will be restoredto default too...)

This is default browser behavior. F5 will always trigger a repost if the form was submitted (PostBack).
You can get around this behavior by redirecting to the same page again after a PostBack
Response.Redirect(Request.RawUrl, false);
But if you use this, you cannot get a response to the client like you normally would. Only setting a Session before the redirect and then deal with it on the page after redirect would be the only way to get a response from the server to the client.
Better is making sure a repost will not create any problems, like duplicate database entries etc.

Related

Can we call Page_Load event in static web method using C# and ASP.NET

I have googled about this question but I didn't get the relevant answer so I want to know, is it possible to call a page_load event when the web method triggered ?
[WebMethod]
public static string AutoFillData(string entredsmbl)
{
// List<string> data = new List<string>();
try
{
// Once this event hit and I want to call the page_load event
// Page_Load(null, null);
entredsymbol = entredsmbl;
return entredsymbol;
}
catch (Exception)
{
throw;
}
}
Why I'm calling the page_load event ?
Because, instead of getting that returned data from static WebMethod and writing some logic in Ajax and load that data where I want (to avoid this process I want to call the page_load event).
I don't think so this is a good question but I want to know is this possible or not.
Give me your best suggestion
Well, lets say you cooked up some way to call that code?
You can't!!1
The reason why is that without a post-back, then all of the values of controls are NOT available.
A web method is static, and you don't even have to place that web method on the same page!!! All you are doing is calling a server side chunk of code. But, without a post-back, then all of the controls and their values are STILL setting on your desktop browser - not server side. So, even if you could call page load, without a post-back, then it can't change values of anything on the page - since the page is still setting on the users desktop - not on the server.
Remember, code behind and its value(s) does NOT exist until you do a post-back.
You can (even should) think of your web page code behind like calling a function or sub, and once you exit that function, then all values and varialbes have go out of scope.
The web server does NOT keep a active copy of your code behind page class in memory. The web server is wafting for you, or ANY other user to post-back.
when you post-back, THEN and ONLY then is a instance of your page class created in memory. Your code behind then runs, page is rendered, sent back to client AND THEN THE PAGE is disposed - removed from memory. Web server is now waiting for the next post-back.
So, you have this:
Note how your page class - code behind is NOT in memory on the server.
YOU DO NOT have this:
NOTE VERY careful here - the web page is ON CLIENT computer - it is NOT existing at all on the web server side.
And you DO NOT EVEN have this:
So, when you click on a button, or do a post-back, then you get this:
our web page is sent up to the server. You now have this:
So NOW your page is sitting on the server.
NOW a instance of the page class is created, and your code behind starts running.
Your code behind can modify controls (even controls to be visible or not), but the page is NOT interacting with the user - ONLY code can MODIFY the web page. So, one change, or MANY changes to the web page can occur, but AS YOU update things like a text box etc., the user does NOT see these changes just yet. So, you can't say run a loop to flash a text box on and off - since the changes are occurring on the server - the client side browser does not have the web page anymore!!!
It is THEN sent back to the client side, and the server side class instance and code is TOSSED OUT - DOES NOT exist!!! Your server side page class is disposed - removed from memory, and the web page code behind does NOT exist anymore.
So, page travels back to the client side, is re-displayed, JavaScript is loaded, and THEN JavaScript starts running.
Ok, so, with above in mind?
Then your question:
load that data where I want
You can't load or change or do anything to the web page , since the whole web page is still sitting on the client browser side - it DOES NOT exist on the server. You can't touch controls, or change the web page - it does NOT exist on the server side. That web page is sitting on the client side.
So, as above shows, it shows you don't grasp how a web page works. You can't call any non static method on the web page, since you don't have the web page on the server, do you?
If you need a few controls to be ONLY updated? Then drop in those controls you want to change + the button inside of a update panel. That will then post-back ONLY what is inside of the update panel, code behind runs, and then the update panel comes back to the client and only that part of the web page will update.
Keep in mind when using a up-date panel, that the page load event runs, but it does not make sense to have the page load do much, since again only controls in the update panel can be changed. But, page load does and will trigger each time.
With above in mind, then you can how and why your question does not make sense. The simple answer is that the controls and values are still sitting on the client side computer browser - and without the page being posted back to server, then the server has no means to update your browser.
The server can no more reach out to your web page on your computer anymore then it trying to reach out to some web pages on your computer doing your banking!!!!
If web servers could reach out to any browser page you have - and control that web page, then the web would be too high risk to use!!!
So, the server NEVER modifies anything on your desktop!!! You SEND it what you want to be change, and then code behind can modify that page now up on the server. When code behind is done, then the page is sent back to the client side for display.
I think update panel may well work for you case - but you need to grasp how the web works.

how to prevent data from sending if user press F5 or refresh in asp.net?

I had asp.net form app I have a bug when the user click F5 or refresh it will enter the data from last data entry .is their is away to Prevent sending data if user click click F5 or refresh?
It's easy to reset a page to it's initial state in ASP.NET by redirecting to itself. Here are 3 ways you can do it:
Response.Redirect(Request.Path);
In which the path to the request is presented in the following form: /MyApp/MyFile.aspx
Response.Redirect(Request.RawUrl);
In which not only is the path exposed, but also any querystring parameters like:
/MyApp/MyFile.aspx?foo=bar
Response.Redirect(Request.Url.ToString());
In which not only is the path and querystring parameters exposed, but made available as an absolute reference in the form:
MyServer/MyApp/MyFile.aspx?foo=bar
A common solution to this is called Post Redirect Get (PRG), where the browser is immediately redirected to a HTTP Get page after any post. See Post Redirect Get in asp.net for a web forms implementation.
There are multiple ways to prevent this from happening. The simplest is to Response.Redirect to a another page, which can be refreshed without consequence.
// process form post
Response.Redirect("anotherpage.aspx");

C# - If user refreshes page after inserting a record, a duplicate record is created. How can I prevent this?

This is true with any other functionality present on the page. I don't want the last event that happened before post back to happen again.
I believe you should take a look at the PRG Pattern (Post/Redirect/Get)
Post/Redirect/Get (PRG) is a common design pattern for web developers
to help avoid certain duplicate form submissions and allow user agents
to behave more intuitively with bookmarks and the refresh button
In ASP.NET:
POST - Submit button click causes HTTP POST
REDIRECT + GET - HttpResponse.Redirect()
MSDN, Redirecting Users to Another Page
In server code, you can programmatically redirect by calling the
Redirect method. The method sends a command to the user's browser that
causes the browser to issue an HTTP GET command for the target page.
Few important notes regarding PRG pattern:
!!! The PRG pattern cannot address every scenario of duplicate form
submission. Some known duplicate form submissions that PRG cannot
solve are:
if a web user goes back to the web form and resubmits it.
if a web user clicks a submission button multiple times before the server response loads (may be prevented by using JavaScript to disable
the button after the first click).
if a web user refreshes before the initial submission has completed because of server lag, resulting in a duplicate HTTP POST request in
certain user agents.
if a malicious web user submits the form twice despite client-side safeguards and typical browser behavior.
You should learn about the PRG (Post/Redirect/Get) pattern:
Post/Redirect/Get (PRG) is a common design pattern for web developers
to help avoid certain duplicate form submissions and allow user agents
to behave more intuitively with bookmarks and the refresh button.
Source: http://en.wikipedia.org/wiki/Post/Redirect/Get
Basically you'll want to redirect via a GET request after the user has done a POST.
you can check already exist condition before inserting record in Database.
like in stored procedure you can check
if not exists (select id from table where column name ='test' )
begin
inser statement..
end
This is about PRG. The simple way to avoid this is redirect user to same page again:
Page: Update.aspx
void btnUpdate_click(object sender, EventArgs e){
// do your update here
Response.Redirect("Update.aspx");
}
This will create a redirect-header in Resoinse and browser will create a GET request to Update.aspx page. And if the User refresh the page, a GET will be sent. Look:
User submit the form : POST
Server do updates, return a redirect-header
Browser receives the response as a redirect-command : REDIRECT
Browser sends a GET request for same page to server : GET
Browser receives the response answered by a GET
If user refreshes the page: Browsers last command was GET, so will not fires a submit again
A simple way is to use javascript to disable the button when the users click it.
A way I use to avoid refreshes when high security is needed, is the use of a small "token" in session.
Let's say, we put a small 32 bit integer in our session.
The page will contain an hidden input containing our small integer token.
Each time we receive the page request, we increment that token by one, and, before doing so, we check for equality with the one received in the request.
If they match, it is not a refresh.
If they don't match, it is a refresh.
This will also block attempt to do back and next with browser buttons.
Of course at the point that token don't matches, the page should change or you'll have again the refresh problem.
It should show something like "hey, refresh back or next not allowed, press here to continue".
For increased security, you can xor that integer with a costant value dependant for example on some other value that is constant in session.

How would you overcome this issue? Jquery + ajax + server timeout

I am using asp.net mvc, C# and jquery. My site is uses ajax heavily. This has lead to a problem and I am not sure how to fix it (well fix it better than my current solution).
Scenario.
User logins into my site - cookie set, server has timeout of 30mins
User walks away for 30 mins
User comes back and clicks on one my ajax enabled jquery tabs
Request sent to server
Server goes nope user timed out send them back to signin page.
since it is a an ajax request the redirect gets rendered in the tab. It look ugly(an entire page rendered in a tab), user is probably extremely confused at this point.
Problem
As far as the server and ajax is concerned the ajax request is valid and success response is sent back. So I can't go check for an error as the request was successful just not the right data coming back.
Solution 1
User logins into site.
Jquery ajax request made to find out users timeout
timeout is 60 seconds less than server timeout
Once timeout on javascript side is hit. Jquery dialog box comes up and tell them their session expired and forces them to be redirect to sign in pack.
A user can't click on anything as the dialog box blocks that. If some users firebug or something they can remove it but then server timeout will still be effect and they will get the ugly version(don't care then).
If a user makes an ajax request the timeout on the server side is reset as well as the one on the client side.
Problems
User could walk away and another person could come and the timeout message could be up but they still could have a potential of 45 seconds of trying to make a new request and reset the timeout. This is very low and not too worried about it.
Sometimes I have observed is it just times out( the client side) and I don't know why. I never can recreate the problem( seems to happen to other people but not when I am testing). So I am guessing something did not hit write or something else went wrong.
So number 2 is really the big reason why I would want to find another solution.
Solution 2 (speculation).
I was thinking maybe if I can make my own response header or something so if the server times out then I can send some 303 redirect or something in that nature that I could check for then do a jquery redirect based on that.
However I am not sure where to do that in my C# code or if I can do something like that.
You could always add a custom HTTP header in your LogOn action which could be intercepted by AJAX calls and act accordingly:
public ActionResult LogOn()
{
Response.AddHeader("X-LOGON", "LogOn");
return View();
}
And in the success callback check for the presence of this header:
$.ajax({
url: '/home/someaction',
success: function (data, textStatus, XMLHttpRequest) {
if (XMLHttpRequest.getResponseHeader('X-LOGON') === 'LogOn') {
// the LogOn page is being displayed
// probably timeout or unaithorized => act accordingly
}
}
});
I don't see why your authentication handler (action filter) can't handle this by returning 403 (forbidden) which AJAX handler will then process by setting window.location to /login.
I basically do solution 1, except that (1) I've encapsulated it into a plugin and (2) I inject the session timeout in the page when it renders. You can see details on my blog, http://farm-fresh-code.blogspot.com, in this article. One addition is that, when the client-side times out, it automatically invokes the logout action to actually terminate the session.

Possible to get return url back from javascript/jquery?

I have a problem that when a user times out on my site they are still logged in. So they can still do an ajax request. If they do an ajax request on my site my asp.net mvc authorization tag will stop this.
The authorization normally then redirects the user back to the signin page if they fail authorization.
Now since this is an ajax request what seems to be happening is it send the entire page back rendered as html. So the user never gets redirect since I just got the entire page send to me as html.
However firebug says this in the console:
http://localhost:3668/Account/signIn?ReturnUrl="return" ( this is not in the actual url bar in the web browser so I can't go up there and get it. I only can seem to see it through firebug.)
So I am not sure but maybe if I could somehow grab this url from inside my errorCallback area that would be great.
Since from my testing no error code is sent back(200 OK is sent). Instead I just get parsing error(hence why errorCallback is called) but I can't assume that every time I get parsing error it means the user timed out.
I need something better. The only other option is too look at the response and look for key works and see if it is the signin page what I don't think is that great of away to do it.
You probably want to do one of two things:
Write your server code such that ajax requests return an ajax error when a session is expired. That way the javascript will expect a return code that indicates a session timeout, and you can tell the user the session expired.
If an elegant solution isn't forthcoming because of how your framework handles this stuff, just put a chunk of HTML comment in your login page like Uth7mee3 or something; then check for the existence of that string in your ajax code.
Alternative, you can also set a timer on the web page that figures out when the session is about to time out and warn the user with a little message that lets them renew their session. Once it times out, blank out the page and give them a link to login again.
How about having a script in the Loginpage
if(document.location.href != "/Account/Login")
{
document.location.href = "/Account/Login"
}
This would work if you try to render partials in an ajax request.
(Not if you expect json)
What is the status code of the response in this situation? I think you should be able to check for a 302 here. If not, the Location header would be the next best way to check for the sign-in page.
This isn't an answer to your specific question, but the way I deal with this is to have a some client-side code that understands about the session length and prompts the user to renew a session just prior to it being ready to expire if they haven't moved off the page. If the user doesn't respond to the prompt in time, it invokes the logout action of the site -- taking the user to the login page.
You can find more information on the exact implementation, including some code, on my blog: http://farm-fresh-code.blogspot.com.

Categories