Ajax FileUpload is hijacking the aspx - asp.net

I have a very simple page I'm intending to use to show the contents of a network file. The target file is brought in with the Ajax Toolkit AjaxFileUpload control. It works, and I can see the file contents when stepping through the debugger. The offending behavior, however, is that once the file is uploaded, the codebehind loses all ability to update the page. I cannot write the file contents to a multi-line TextBox. I cannot even update a label on the page. Neither can I write hard-coded "Test Text" to the TextBox or Label.
There are no errors or exceptions throw. The code runs to completion without writing the contents to the TextBox.
<h2>
Encrypted File Viewer
</h2>
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:Label ID="ViewingLabel" runat="server" Font-Bold="false" ForeColor="Green"></asp:Label>
<br /><br />
<asp:Button ID="UnauthorizedExitButton" runat="server" Visible="true" OnClick="DoExit" Text=" Exit " />
<br /><br />
<Ajax:AjaxFileUpload ID="AjaxUploader" runat="server" OnUploadComplete="FileOpen" width="800px"></Ajax:AjaxFileUpload>
<br /><br />
<asp:TextBox ID="Viewer" runat="server" Width="800px" Height="500px" TextMode="MultiLine"></asp:TextBox>
In FileOpen()
string tempPath = Path.GetTempFileName();
string tempPath2 = Path.GetTempFileName();
AjaxUploader.SaveAs(tempPath);
myStrUtility.DecryptFile(tempPath, tempPath2);
Viewer.Text = File.ReadAllText(tempPath2); //Fails
// For testing - Debugging
ViewingLabel.Text = File.ReadAllText(tempPath2); //Fails
Response.Write (File.ReadAllText(tempPath2)); //Fails
I'm completely baffled by this, since I can see the decrypted contents of tempPath2.
Thank you in advance for any insights you can offer.

Ok, I have a few minutes.
If you have a bunch of text boxes on your screen. You fill them out.
(no postback has occured yet). So, ANY server side code that runs will NOT have use nor see nor be able to get use of those controls.
So, you enter some stuff into text boxes. You then select a file to upload. You then hit the upload button.
Now, your 3 server side events will run. But the WHOLE idea of AJAX is you don't have to do nor want a page post back to have occurred. And a page post back has NOT occured!
So, now when the 3 server side events (from ajax file upload run), we have:
Start of upload event - server side runs. But again, that code in the form behind will NOT have use of any controls changed.
Single file upload compilate - your server side event code runs. But again, due to no post back having occurred - then any control changed or text entered into controls is NOT available yet.
Final all files upload event - again server side event code runs, and again you can't get or use any controls on the form that changed.
Several solutions:
Any text boxes, or data entered or changed? You need some kind of "ok buttion", and that button does the post back - in that routine, you THEN turn on (display) the up-loader.
Now the user can select file(s), and start the upload. For the 3 ajax events (start of up-loading), single file done, and then all done event can all run server side with use of your controls.
So, just keep in mind that you can enter a bunch of data into the form, and then use the up-loader (select files, then upload button). For this whole process no page post back occurs
Worse? If you put a submit button on the page, and the user has selected files, and then decides to hit the post back? Well the ajax uploader does NOT persist the files selected during a post back. This is why I strong suggest you hide the up-loader (can't use visible, you have to use style).
The most simple solution is if you have a group or bunch of controls on the form that you need to set or will have data/changes made before they start a upload?
Put the group of controls in a up-date panel. And set auto post back for each of the controls. So, any control you edit will now cause a post-back. Now, such data is available in server side code. (and that includes the 3 ajax up-loader server side events).
Do keep in mind that this up-date panel will result in what is called a partial post back (the on-load event will fire).
So, the behavior you are seeing is not a surprise at all. You also can NOT hide/show or change values of controls in the 3 up-loader events because as noted, you will be changing values of controls, but the page has NOT been posted back. If you attempt to change controls in the 3 events, whatever you do will be lost if/when you/users do eventually post back the page. Remember, you have a stateless web page on the desktop.
If that stateless page has not (yet) been posted back, then the 3 ajax server side events can't see the client side browser controls at this point in time. And if your change controls in those 3 events, you are changing the controls sitting server side, but the web page is not going to be updated.
So, you either have the controls on the page do a post back BEFORE they select files and start up-load. As noted, I often "hide" the ajax file up-load. Let user enter some stuff, and then have a "ok - now lets up-load files". When they click that button, your server side code runs, you do whatever, and then turn on (display) the ajax up-loader. At that point then ajax upload events (the 3 server side events) can run, and that code now has a posted back copy of the client browser.
Now, assume the very last ajax event (all files uploaded) has occured. You can now try and modify controls on the page, but the page is still sitting client side. It has NOT been posted back. And you not going to be able to post that page back between the start of the up-loads, and when you finish. If you simply run a bunch of code in the final event and try to update controls and values on the page - you can't!! Because no post back has occurred and the controls and their values are still sitting client side.
Another way to achieve this goal is to use a client side javescript event tied to the LAST ajax event (all files done). However, that means the 2nd event (one file done, and save-as file) will NOT have use of controls if you start the up-load BEFORE the page has been posted back.
So, this means that if you going to use controls during the up-load (start to finish events), or run code in that final event that modifies controls? You need the page posted BEFORE you run the up-load process.
You can try can change all and any controls with code in that 3rd final server side event, but you modifying controls in the server side browser copy. You not see ANY changes take effect. It will thus seem like you cant modify anything.
So, in a good deal of up-loads? Well I want something to occur AFTER all is said and done. This means that the 3rd final event of the up-loader needs a client side event (and it will have a __dopostback() js command. The up-loader is VERY well built in that the client side JS events ONLY fire AFTER the server side events are complete.
So that final post-back trick/tip is ONLY of use if you want something to occur after all is said and done. But this tip don't help you get at controls in the 3 events, and as noted, unless you send the browser page back to the server, then any code you run server side will NOT show up in the browser. In other words, if you want some updates, or message boxes on the screen to update at the end of the load? You cannot use that 3rd final ajax code stub. You have to do a post back BEFORE you attempt to modify anything on the page.
(else you be modifying the server side copy of the browser without having posted back the client side browser copy that is "different" and not the same.
So, those 3 events can't modify any controls, since the page not been posted, and when you eventually do post the page, what controls you modify will be lost/overwritten when the client side browser post back occurs.
So you not losing the ability to modify controls on the page in that 3rd last event, but you modifyng a copy of the server side page - and you never see the changes.
So, with a standard asp.net buttion:
we have:
Post back (browser page goes to server)
Your code (any code behind) can run, can see, can grab/set/see/change any control on the form.
Now browser is re-sent back to client and displayed. (so you can see your server side code changes in those controls.
With the ajax uploader, no page post back has occured, and no re-rendering of the browser will occur. (those controls and events don't cause a post-back). So, you can't run server side code to change things, since you don't have a copy of the client side. And even if you do modify controls, no page is sent back to the client side to re-display.
So, based on the above asp.net model and code behind? You can't change controls unless your server side code runs as a RESULT of a post-back.
So, either get your post back all done and wrapped up BEFORE uploader runs, since those 3 server side events can't modify controls, and will not see client side changes unless you do/did a post back BEFORE the upload starts.
Just put auto-post backs in the controls. But then auto post backs for the several controls does cause a whole page post back. So, you can "mitigate" this by placing the group of controls in a update panel. Or, as noted get all your controls loaded up and set with a post back that THEN displays the up-loader for the user to start.

Related

Create dialog confirm in server site ASP.NET

I want to create a dialog confirm in ASP.NET.
I'm doing it with this code:
protected void Button1_Click(object sender, EventArgs e)
{
ClientScriptManager CSM = Page.ClientScript;
string strconfirm = "<script>if(!window.confirm('Are you sure?')){window.location.href='Default.aspx'}</script>";
CSM.RegisterClientScriptBlock(this.GetType(), "Confirm", strconfirm, false);
if (the condition to yes clicked)
{
// do something ....
}
else
{
// do something else ....
}
}
How can I get the yes / no condition in this case?
Thanks for reading my post
You can't do it this way. Your code behind NEVER interacts with the user. Your code behind ONLY interacts with the web page, and ONLY does so WHILE the page is making the round trip.
Before a post back? You have this setup:
You do NOT have this:
And you do not have this either:
So, when a user clicks a button - this occurs CLIENT side. The page - whole web page is sent up to the server - and THEN your code interacts with the web page - NOT the user!!!
so, you click on a button - (browser). The page THEN starts the all important round trip. Like this:
the page travels up to server,
You now have this:
Now and THEN your code behind runs. When done, your code behind MUST finish, else the page stays stuck up on the server side. When done, the whole page page makes the trip down back to the browser. And THEN the page is re-displayed and THEN any js code can run.
So when done? Your page makes the trip back down to the browser like this:
And only AFTER the page makes that trip, can the browser display what your code behind changed. So your code behind NEVER interacts with the user, but in fact can ONLY interact with the web page and ONLY do so for the short time that the web page is up on the server.
So, how can you pop a dialog and get a yes/no answer? Well, you require the dialog to run and launched client side. And based on the user hitting ok, or cancel, you can THEN have a code stub run.
So you can say have code that flows like this:
ClientScriptManager CSM = Page.ClientScript;
string strconfirm = "<script>if(!window.confirm('Are you sure?')){window.location.href='Default.aspx'}</script>";
CSM.RegisterClientScriptBlock(this.GetType(), "Confirm", strconfirm, false);
Function OkCode - runs on user click or seleciton.
Function Cancel Code - runs on user click of cancel button.
So, you need 3 code stubs. One to inject the script that will pop the dialog. And then the ok or cancel button in that script/dialog can THEN launch the server side code again. This will of course require that round trip (as all server side button event code does).
There are a few short cuts. Say I have a standard asp.net button, and I want a confirm dialog? Well, you can do this:
<asp:Button ID="Button1" runat="server" Text="Delete"
OnClientClick="return confirm('Delete record');"/>
The above works, since the confrim in js returns true or false and that will prevent the button code (code behind server side) from running.
You could of course have a script that you call from code behind. Keep in mind that your register script quite much has to be the LAST thing you do and inject into that page before it travels back down to the client. The page dispays and THEN your script you added THEN runs!
You could say then have two buttons on your form - hide them. And then have a js dialog that clicks either button based on what you pass.
So, say we build that function. We will pass it the question/text, and then say two buttons (one for ok click, and one for cancel click). And you could set the style of those buttons as display:none. This will still not get you a server side if/then result from that dialog. So, you have to quite much in near ALL cases break your code out to 3 seperate parts.
The part that triggers the dialog.
And the two buttons that run code behind stubs based on the choice(s) the user makes. In other words, adding the dialog by script would STILL require you to have TWO separate code stubs behind to run (the one for ok, and the one for cancel). You simply can't pop a dialog server side and wait. That would result in the web page being stuck up on the server in the above round trip concept. That round trip dialog MUST be absorbed into your mind - without that model of how the round trip works, then you make mistakes in your design assumptions - and thus your question which is actually not really possible to achieve.
You could create a generalized dialog that you set the text in code behind along with your register script idea. but the button choices and code it runs would also have to be setup in that register script, and you would still require two separate code behind stubs (one for cancel, and one for ok). So it would be possible to setup something that requires you to NOT have special code in each page, but you would require a js function routine you build up, and you would have to supply it the name of the two code stubs, and then that js routine could send a __DoPostBack passing the choice made.
But even again, note how you need separate routines, since that web page is sitting on the users desktop, and your code behind is not waiting for a dialog, but in fact a WHOLE PAGE post back.
So just keep mind that code behind does not interact with the user - it ONLY interacts with the web page, and ONLY does so during that short round trip and in fact ONLY during the time that the web page is up on the server, and your code behind runs and then is finished. And THEN the web page starts that trip back to the client side - the page is re-loaded, changes you made are displayed, and THEN the js in that page starts to run again.

Need help trying to enter 1 or 2 digits in a textbox before focusing to next textbox

Hi i am trying to enter 1 or 2 digits in a text box in asp.net c#. I want to focus in the next text box.
Here is my code but it throws an error that the textbox1 is being accessed from a different thread that it was created.
private void textBox19_TextChanged(object sender, EventArgs e)
{
Thread t = new Thread(() => {
Thread.Sleep(2000);
textBox1.Focus();`
}
);
t.Start();
}
Ok, first up, you need to grasp and understand the concept of a round trip.
next up, the text changed event does NOT fire until the user is finished typing in that text box and hits TAB. So you can't really do key press processing with code behind.
When you hit tab, then a post back occures. This is is the ALL IMPORTANT start of the round trip. If you do not with absolute certaintity grasp this concpet, then all your fortay into asp.net pages will be lost, and you will forevermore be 100% lost. you must, absolute must grasp this concpet.
So Our round trip:
A button is clicked, or a event is triggered for htat control (keypress processing will not work - it is WHEN the user hits tab).
So, button click or tab on that control.
Post back occures
The WHOLE web page travels up to the server.
When we say whole page, we mean ALL of the browser HTML, all of the whole page
This includes all controls, all graphics, all HTML - the whole deal
Now the page is at the server.
The asp.net processes the market.
THEN your code behind runs. At this point your event code runs
In your event code, you can say modify a value of a control.
Now:
Then the WHOLE PAGE travels back to the browser and is refresed and displald.
The page is now sitting back on the client side browser.
So as the user types. Clicks into a text box etc.? The browser is allowing this.
The server is not being talked to (unless you trigger another post-back (round trip).
So, as the user is typing in that text box?
As the user is editing that text box?
This is ALL occurring browser side. You are NOT talking to the server and those round trips are NOT occuring.
So you can't say put some timer on the text box and look/check/see/hope for a change in what your code sees. None of that code is going to run untill that page post back occures and the round trip starts.
A round trip is expensive, and in general is NOT appropiate for keypress processing. If you were to setup a full page post back for EACH keypress, then each key press would be JUST like a submit button - the whole page has to travel back up to the server.
So, now that you grasp the above?
Well, then you can't loop/pool/test the value of a text box with code behind on the server You can ONLY see/use/check/modify/play with controls on the form AFTER the WHOLE WEB PAGE has been sent up to the server. Thus single key press processing is not practial.
Ok, so what can we do here?
Most simple is to use client side code. Simply check the length of the text box, and if it 2 characters, then set the focus to another control.
So, lets drop a text box on a form, and we can use this markup for this to work:
<asp:TextBox ID="TextBox3" runat="server"
onkeyup="mykeycheck()" >
</asp:TextBox>
<script>
function mykeycheck() {
vTextBox = document.getElementById('<%= TextBox3.ClientID %>');
if (vTextBox.value.length == 2) {
document.getElementById('<%= TextBox1.ClientID %>').focus();
}
}
</script>
So, now, our focus will jump to Textbox1, and we don't have ANY server side code.
Can we "some how" do single key press checking and run server side code?
Well, yes, you can. But then again, that huge large round trip process will occur.
We can however, I suppose introduce a update-panel. This would suggest that the text box is OUTSIDE of the up-date panel, and we could say for example display the results of the text box, and run code behind for each keypress. I can post the code and how to do this, but in general, having a full round trip for each keypress is quite much the same idea as having a submit button for every key you press - quite heavy.
So, I can't stress how absolute important it is to keep in mind that to run/use/have code behind interact with the web page, it can only do so during that "small" time when the page is been posted up to the server, and your code runs, and then the WHOLE page is now re-send back to the browser side. And you code behind can only see/touch/modify/use the controls on that page WHILE the page is up on the server during that round trip. But it not going to stay up there very long - and after all your code runs, the WHOLE page is now send back down client side. And this would also mean that even simple things like your cursor position in the text box would be lost. You can VERY much think of the round trip process VERY much like as if you just had hit the refresh key.
So, you not use nor need any code behind in the text changed event. However, DO keep in mind that when we use the above client side JavaScript, that when we change the focus, if you do still have a server side text changed event wired up, (and postback = true for that text box), then the server side code WILL run, and a post back will occur. Since we really don't need nor want a postback to occur, then of course we will remove that text changed code stub, and turn off the post-back setting for that text box.

Why do I have to force an AutoPostBack="true"?

ASP.net 2.0, Visual Studio 2005, and standard controls such as <asp:DropDownList>, etc require that I put in AutoPostBack="true" for there to be a call to the code behind. But why? Shouldn't that be happening anyway?
Thanks
Code behind runs on the server. HTML code and Javascript run on the browser.
A dropdownlist is an HTML element that runs on the browser. It can't do anything on the server without sending data back to the server. The means by which ASPX web forms send data to the server is via postback.
Sometime you don't want a dropdownlist to send data to the server. It really slows down the user experience to have to wait for something to cross the wire. To speed things up, you can disable the postback on the list control; the server will only get contacted when the user posts the whole form. At that point, the server can inspect the list control to see if its value has changed and take action.
No, this should not be happening anyway.
An asp:DropDownList is a control that generates a single drop-down list. This is rendered as a select tag to the client. A select tag is typically there to collect input from a user, not to submit a form.
Forcing AutoPostBack="true" is necessary because then you are causing a post-back whenever the selected index changes. While this can be useful, this is not the expected behavior of a select tag, and most developers are not going to want this action... for performance reasons... or if it is part of a larger form, it will interrupt user flow... etc.
The alternative would be they only call javascript (on the client) as opposed to making a round trip to the server (postback).
Javascript is faster since it is on the client and doesn't require a round trip to the server, but it can be disabled or changed by the user.

ASP.NET HttpHandler and frequency of hits

I was able to setup some ASP.NET Image controls to render images from a database by using an HttpHandler.
// Notice the ImageHandler.ashx
<asp:Image ID="imgSrvcGrp" runat="server" ImageUrl='<%# DataBinder.Eval(Container.DataItem, "ServiceGroupID", "~/ImageHandler.ashx?id={0}") %>' />
It works great and was surprisingly easy to setup. My question follows...
I noticed that the HttpHandler (ImageHandler.ashx) gets hit at certain times when I don't expect it to. For example, I have a break point at the Page_Load event of the page that contains the Image tags consuming the HttpHandler and another break point in the handler itself, and I found that even though there is no postback (ie - the Page_Load break point is not hit) the handler sometimes gets hit (ie - the break point in the handler is hit).
Oddly, I found this occurs when I close a jQuery dialog on the page. I have a jQuery dialog popup on the page, and I found that when I close the jQuery popup (by clicking on the X) the image handler is hit for every image on the page that consumes it and yet no postback occurs.
The only other detail that I can think to add is my webpage is using Telerik's RadTabStrip, and it is possible that it is somehow having an effect upon this matter.
I realize that my explanation was rather long-winded, so to be more succinct with my question: Why does my image handler get hit so often even though there are no postbacks occurring?
Because loading a page resource and posting a form are different actions.
Don't think of it from an ASP.NET perspective with postbacks and Page_Load handlers and whatnot. Think of it from the perspective of the actual HTML in the browser. A "postback" is nothing more than a form being posted to a page. If you're not doing anything to trigger a form post, the page won't post back.
However, the page is hitting the server when it requests other resources. CSS files, JavaScript files, images, and so on. The resources referenced within the HTML which the page needs to load. So when a page is loaded, it doesn't just hit the server once. It hits the server to get the HTML document (this is where Page_Load for the page gets triggered), and while it renders that HTML it hits the server again and again for every resource referenced in the HTML document.
If the page is hiding/showing resources with dynamic style tweaks, then it shouldn't need to re-load those resources each time it shows them. However, if the page is doing something which causes it to have to re-render the loaded content (and that content isn't cached in the browser), then it will hit the server. This would be what causes that ASHX handler to get hit.
One suggestion for you would be to load up the page with some debugging tools (FireBug in Firefox continues to be my personal choice), and watch the actual traffic coming and going on the page (the "Net" tab in FireBug, possibly something similar in other tools.) This can help you determine exactly what is being requested and possibly what is requesting it. For example, if that RadTabStrip is for whatever reason removing img elements from the page and re-adding them, it'll request the image from the server each time.

Asp.net server control same event handling order on server-side/client-side

I have an asp.net server control (with the asp: in its definition). The button has been set to do post back.
On the server side, I have the on click event handler
e.g btnSave_click()
On the client side, I have a javascript function to be invoked on the click event
e.g btnSave.Attributes.Add("onclick","javascript: return CheckIsDirty();")
Am not sure which order these two will be executed. Because I want first on the client side to warn of any data entry fields that are not yet filled-out before actually saving any data.
Any help?
First client side, second server-side.
So you can use it.
I also use it in some cases, like:
close.Attributes["OnClick"] = "return confirm('Are you sure?')";
In this case if the user presses 'No' then the server-side event handler does not even play a role.
The trick here is to set this global variable "Page_IsValid" false if your test fails and this will stop the post back.
Read this page http://msdn.microsoft.com/en-us/library/aa479045.aspx which explains both server side and client Validation. There is sone good code example you can use.
The way you are setting your onClick JavaScript event will actually prevent it from posting back as you are overwritten the ASP.NET event handler. The correct way to accomplish the validation you are intending is to:
btnSave.Attributes.Add("onclick", "CheckIsDirty();" + GetPostBackEventReference(btnSave).ToString());
Notice that you append the result of GetPostBackEventReference, so that in JavaScript you first call your CheckIsDirty() method and then call the ASP.NET postback method. Assuming your method returns true, then the button will post. If it returns false then it will not cause a post back.
Does that sound like what you are trying to accomplish?
I think you need a much better understanding of what it means client side and what it means server side and how they all relate together. I've seen more and more developers make a mess of it.
Of course the client side will execute first in your case. Actually there's no way to execute it after the server code is executed (except if you do something manually). I'll try to give a brief explanation:
Whatever you have in your server, will generate some HTML on the client and the user is always interacting on the client. So you have a html button that the user is clicking. What the browser will do is execute the javascript associated with it or if no javascript is specified and the button is a submit button it will submit the form. if you check the generated html you will see that for the onclick event you will have the script you have added followed by some autogenerated script that actually will submit the form to the server. Your server side code will execute only if the page will be submitted.

Resources