Methods for asp:FileUpload object? - asp.net

. .
I'm trying to set up an <asp:FileUpload> object to fire on the client side after I click "Browse" and select a file. (Specifically, I want it to return the name of the file that was selected.)
However, I'm having a hard time trying to find the correct method. None of the server-side methods do what I want (and I'd prefer it to fire on the client-side, anyway), and none of the various combinations of client-side methods (onclick, onchange, etc.) seem to work.
Ideas, anyone?
Thanks!
Edit: I think I may have answered my own question. I ended up abandoning the ASP.NET <asp:FileUpload> tool, and simply used the lower-tech <input type="file"> instead. Methods seem to work just fine with that.
Edit #2: Nothing doing. That works fine on the client side, but then I have the problem of trying to save the file on the server side. I guess it's back to Square 1.
Edit #3: I think this is the final answer. I changed it back to <asp:FileUpload ID="FileUploader"> and added a FileUploader.Attributes.Add to the Page_Load. It sees that and fires with no problem. Of course, now I'm getting an "Object expected" error (because the script it's calling comes after the code -- ah, the joys of dealing with JavaScript order).

As I mentioned in my edit yesterday -- the answer ended up being to add the attributes in the Page_Load. Let's say my FileUpload ID is "FileUploader". I added FileUploader.Attributes.Add("onchange","CallThisCode();"). That did the trick!
Now I just need to figure out how to make it call the JavaScript correctly -- a different issue altogether! :-)

Related

Is it OK to use __doPostBack()?

Is it OK to use __doPostBack() or it is not recommended because it is generated from ASP.Net and we are not sure if they changed it in a next version of ASP.Net.
I would advice against it, since it's internal stuff of ASP.NET and was never meant to be used directly.
Instead, what I'm doing when I need to "manually" trigger PostBack is adding hidden "server side" button with the proper OnClick:
<asp:Button id="btnDummy" runat="server" OnClick="Foo" style="display: none;" />
Then the JS is:
document.getElementById("<%=btnDummy.ClientID%>").click();
This way I don't care how post back happens, I just trigger the natural flow of events.
You should not call it directly. You should generate the javascript call by using functions in Page.ClientScript such as:
GetPostBackEventReference
GetPostBackClientHyperlink
This will ensure that it's always compatible.
I think its perfectly fine to use directly, and have used it without fail, its just a javascript function after all.
They probably won't change it, but why call it directly?
I think it's a better strategy to trigger the event (a button click for example) and let the control trigger the postback.
I you do need to trigger the postback directly it's recommended to use the Page.ClientScript functions tenfour described.
We use it all over the place and I can't imagine it would ever be stripped out of ASP.NET. I think the fake/hidden button method is just as hokie if not worse. If you use the fake button approach, then you get no option to pass in the __EVENTARGUMENT. I like using __EVENTARGUMENT to pass my data to the server better than creating hidden fields, because it would be more difficult for a hacker to compromise than simply posting back some hidden field to my page. I also don't like the idea of creating fields and controls on the page if they are not even going to be displayed. I am sure that the fake button approach is probably easier for a newbie coder to understand. That being said I am searching for a more elegant way to approach this, but still find myself calling
__doPostBack('%=UpdatePanel.ClientID%>','MyData')
in some cases.

On Creating Controls Dynamically or Not

I'm currently working on an ASP.NET 3.5 project, and I wanted to know your opinion regarding the following situation, which I happen to run into sometimes:
Let's say I've defined the following control of an imaginary component framework somewhere in my code:
<Window runat="server" ID="windowTest" />
Let's assume that with the above mentioned imaginary component framework it's possible to get a reference to my Window control from the client-side using its ID (for example to change its appearance):
function MyFunc(){
var win = GetWindow("windowTest");
}
Let's also assume that both code snippets are placed in different files, e.g. the JavaScript code in MasterPage.Master and the control in AnotherPage.aspx.
As you might already have noticed, the passing of the control's ID as a hard-coded string to the GetWindow function is a bit problematic here, since changing the control's ID is going to break the JavaScript function.
This situation surely smells like it needs a good ol' Replace Magic Number with Symbolic Constant refactoring. I can achieve this by dynamically creating the Window control and using a constant for the value of the control's ID:
AnotherPage.aspx:
Window windowTest = new Window();
windowTest.ID = Consts.ID_WINDOW_TEST;
form1.Controls.Add(windowTest);
MasterPage.Master:
function MyFunc(){
var win = GetWindow("<%= My.Namespace.Consts.ID_WINDOW_TEST %>")
}
My question now is: How do you handle such situations? Do you create all your controls dynamically (like shown in the example above) when running into this situation, and are there any drawbacks using this approach, e.g. Designer doesn't display the control anymore? Or do you say "Screw it, nobody's going to change that control's ID" and leave it hard-coded in your code? Or do you have other approaches to this situation?
I personally am a fan of the of the first option (refactoring), since a) it makes sure that a change to the ID is not going to break my code and b) I almost never work with the Designer, but I thought I'd ask this question on SO to get some valuable opinions on this.
Thanks in advance for all the responses.
Greetings,
Giu
Update / Clarification:
I made a small error in the first version of this question by stating that the code snippets are placed in the same file. Since both the control and the JavaScript method are located in the same file, there is no need to create the control dynamically and defining the control's ID using a constant; by defining the control directly in the .aspx file I could use its ID in the JavaScript method as follows: GetWindow("<%= windowTest.ID %>");
But, my problem is another one; the control and the JavaScript method are each placed in different files, in which case the mentioned approach of using the control's ID doesn't work anymore. Therefore I introduced the solution mentioned in my question with the constant and the dynamic creation of the control. I now corrected both the filenames in my question so that the correct scenario is described to which my question is related.
In 4.0 you can control the client ID that's generated in master/content page situations quite well. but i believe if someone changes the ID manually in the page at one place and not in the javascript code it will still be a problem. If you are the only one who'll be working on this code then you can always be mindful and refactor properly. Otherwise you can go in for the constants option or store the IDs in a separate resource file.
In my opionion there a two suitable solutions:
1) Use the JQuery framework to get ahold of the html element you want to adress via JavaScript. JQuery is designed to be able to work with autogenerated hierarchically created control IDs
2) Use .net Framework 4.0 and don't use autogeneration of the Control ID. (I've heard that this is a new feature in 4.0. I think in your situation it might be worth trying out)
Check out Rick Strahl's blog post entitled "A generic way to find ASP.NET ClientIDs with jQuery"... it seems to have some good ideas that could be of some help to you.
He uses jQuery, as the first responder suggested, but does it in a way that you are using ASP.NET's built-in ClientID property to get the actual id ASP.NET generates and uses a client-side friendly mechanism that enables you to write script code referencing controls that won't break with ID changes.

Updatepanels: Prevent multiple concurrent requests by same user?

On a rather complicated screen with a big updatepanel, I'm running into the following problem:
If a user clicks on a certain button 6 or 7 times really fast, it seems to eventually process the last request out of turn and problems occur. Specifically, there's an xml document in session state, and it gets out of sync.
What I really want to do is block clicks to this button until the postback completes. I know I could probably find an easy way to do this with Javascript, but it seems like it might be built-in.
Any thoughts?
Note: The answers below are helpful, but they haven't solved the problem. After disabling the linkbutton with onClientClick and then allowing it to come back after the postback enabled again, the problem persists. It's almost as if the updatepanel isn't quite done with everything even though it has drawn the fresh, enabled linkbutton on the screen.
More notes (solved!): I solved this one by using BlockUI (jQuery plugin). See my answer below.
ASP.NET UpdatePanel always honors the last request. If you make a request while one is processing, the first requests gets terminated and the current one is processed. It was designed and built to work this way.
I would disable the button with JavaScript once it has been clicked.
UpdatePanel? I will assume you are using MS AJAX, if so I will recommend you download the AJAX toolkit if you have not done so. This toolkit comes with many ready to use controls, and extensions to help you in your AJAX enabled app. For example, there is one extension called "ConfirmButton" that will help you prevent the user from clicking in a button more than once, and it also does it in a very cool and elegant manner.
Another option will be to use JavaScript or better yet, create a custom button control that has a property to be disabled after it is clicked, if you do that, it will be really easy to reuse it in your other applications.
Hope this helps.
In a home-rolled AJAX framework I worked on awhile back, we simply logged the last call in javascript (javascript function call with many parameters) and prevented subsequent calls with identical parameters. It wasn't ideal, but it did the trick in a pinch.
I was having some "Asyc" problems with infragistics control, but after adding ScriptMode="Release" in Scripmanager the problem was resolve.
The link below solved my problem in about half an hour. Just going with a javascript disable (and I tried several different ways...) did not do the trick due to the timing of the updatepanel.
Disabling UpdatePanels While an Asynchronous Postback is in Progress

Registering a dynamic javascript after an UpdatePanel's update

I have a page with a dynamicly created javascript (the script is pretty static really, but the value of its variables are filled based on user input).
The result and the controls to take user input is inside an UpdatePanel which updates itself on certain user intputs. Some of these userinputs cause changes in the variables i spoke of earlier so i need to register a new javascript.
The problem ofcourse is that only the updatepanel gets updated and the scripts are registred outside the update panel so no new scripts are added.
What do you think would be best practice now? I could solve this by letting this script (and variables) live inside the updatepanel or i could make sure the page is fully reloaded when the need for posting a new javascript arises? The ScriptManager that i already have on the page might be able to help me with this...
So i'm looking for someone who either had similar problems and solved them in a nice way, or just someone with some bright ideas :)
Have a look at ScriptManager.RegisterClientScriptBlock.
I've had better luck with ScriptManager.RegisterStartupScript than I did with ScriptManager.RegisterClientScriptBlock. You might give that a shot.
Why not just put the variables inside the update panel, or have the JavaScript get the values through the DOM?

What is the best way the _DoPostBack javascript method in Asp.net

I want to set a breakpoint on the __DoPostBack method, but it's a pain to find the correct file to set the breakpoint in.
The method __DoPostBack is contained in an auto-generated js file called something like:
ScriptResource.axd?d=P_lo2...
After a few post-backs visual studio gets littered with many of these files, and it's a bit of a bear to check which one the current page is referencing. Any thoughts?
If you using IE7 for testing you can use View -> Script Debugger -> Break on next statement and then just click the button that generates the event(__DoPostBack)
TBH, I dont think there is much value in setting a breakpoint within the Javascript since it pretty much comes straight back to the server anyways.
It would be best to set breakpoints in your server code.. Depending on what you are trying to debug this will be in different places.. Either in the page event cycle or a controls IPostBackEventHandler.RaisePostBackEvent handler.

Resources