I'm new to web development, and I'm currently using ASP.net. I wonder what would I need to do to let the browser wait for 3 seconds so my users can read the text "Customer Successfully Added" before turning to another page? I have attached my code as follows.
Protected Sub btnAdd_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnAdd.Click
Dim db As New DatabaseClass
db.addProfile(txtLN.Text, txtFN.Text, txtUsername.Text, txtPassword.Text, txtAddress.Text, txtZip.Text, txtPhone.Text, txtEmail.Text)
lblMessage.Text = "Customer Successfully Added"
End Sub
In addition, I'm not sure how to utilize MSDN. For me, its information overload, I'm wondering how to go about finding the solution on MSDN so i would be able to solve my problems in the future. Thank you!
You can't do it in the code behind of the page because of how asp.net works - the label text would not update until after the timeout occurred if you did it in the code-behind.
The server-side processing spits all the html back to the browser only after it has completely processed any server-side code unless you're using Ajax. Since you're new, I won't even bother going into how to do it with Ajax as there is a MUCH simpler option for accomplishing what you want.
A simple method to accomplish what you're looking for would be to have a simple HTML page that just has a message that says "Customer successfully added" and use javascript (client-side code) to pause and then redirect using the Javascript "SetTimeout" function.
There's an example here: http://www.bloggingdeveloper.com/post/JavaScript-Url-Redirect-with-Delay.aspx
The logic flow wshould work like this:
The original page should add the record (in code-behind) then redirect to this simple html page (in code-behind). The html page should have the "Customer Added" message and use the SetTimeout and Redirect to go to whatever page you want the user to see after viewing the message.
For stuff like this you need the code to run client side rather than on the server. The easiest way to do this is to return some javascript with your page (in the .aspx part rather than the code behind)
Take a look here for an idea of what to do :)
The page is displayed for a few seconds and then the javascript triggers a redirect to a url of your choosing. Just add something like this into your html.
You can emit javascript to redirect to the other page, using the setTimeout function.
This is best accomplished using the ScriptManager to register any javascript on the page.
Related
I've looked around and didn't find anuthing similar, what I'm looking for is a way to disable or stop whatever action that make the page post back on the page_load method according to some validation
example:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Page.IsPostBack Then
'Validate here and stop the action
End If
End Sub
I've already tried to end the request but in this way I can't tell the user whats going on
If the page fails validation, then the whole idea that no post back WILL occur! So you as a general rule don't check in the post back for a validation that supposed to not allow the post back!!!
If validation and the validators are working correctly, then no post back can and should occur. Now if you want code behind to do some extra logic and processing and some extra testing?
The of course you allow the post back, and thus now in that button event code stub, or say dropdown list or whatever event code stub is being triggered? It is in THAT code that you can add additional validation.
So you might have a VERY nice regex validator that requires the user MUST enter a legal formatted email address. They then hit ok, and say you then run some code to check if the email is on-file, and at that point your code behind can:
Display a message on the screen, or even trigger a toast message (client side). Note that you CAN trigger nice toast message or client side script if that is the VERY last thing your code behind does, and this works rather well.
So yes, one can and will often have a mix between some validators on the page, and THEN some additional code "behind" that does and will run as a result of the post back having been allowed.
But, if validators (client side) are working, then you not have any post back to run, and thus you can't check anything at all anyway. If the validators are working correct, then no post back should occur at all.
However, as noted, if you need to write some additional logic for that button or control event? Then you let the post back occur, run that additonal logic, and display a message, or toast message or do whatever based on that input, and then the page will rendered again.
There are several discussions on this topic (the closest one might be at Redirecting new tab on button click.(Response.Redirect) in asp.net C#), but none fit my need. Here is my situation:
The code
<asp:ImageButton ID="SearchButton"
runat="server"
OnClick="SearchButton_Click" OnClientClick="target='_blank';"/>
allows me to handle the event in the "code behind" (to process the URL for this redirection) and if this markup is in a "regular" .aspx page and the event handler SearchButton_Click in the code behind all is fine.
My situation differs from this in that this code resides in an .ascx (User Control) element, which is dynamically loaded on the "top level" page. This same code results with the current page being replaced with this "search page" and cannot even use the browser's Back button to return to the original context.
Please note that I would prefer to handle this in C# as
protected void SearchButton_Click(object sender, EventArgs e)
{
string what = queryText.Text;
Response.Redirect(baseUrl + what);
}
Every advice appreciated.
Your question is a bit involved, I'll explain some backstory:
Tabs and Windows, and why you shouldn't make any assumptions or demands of the browser
Traditionally hyperlinks (e.g. <a href="foo">) opened links in the same window viewport as the originating document. This is convention and is what users expect when they click on a link. Unless you know exactly what the user expects you should never cause a link to open up in a new window, tab, or in-document iframe popup or Ajax dialog.
Prior to the advent of tabbed browsers, hyperlinks with target="_blank" would cause them to open in new windows. In recent years, tabbed browsers prevent taskbar spam by opening them in new tabs - but this is a user preference. Browser tabs are not exposed to the browser through any public API, so your application will never know if a target="_blank" opens in a new window, a new tab, or even the same window viewport (unless you monitor window events in client-script).
I'm of the opinion that applications should never surprise the user, and that the user will always expect a link to open something in the same window.
When XHTML1.x was released, they removed the target attribute entirely because it was originally intended for frames (which were also removed in XHTML), because the committee felt that the _blank feature was being abused, and because XHTML can be rendered on a variety of devices that might not support multiple windows (think: 2005-era featurephones with terrible web browsers).
...unfortunately they brought it back in HTML5, oh well. I guess it does have some legitimate uses, but anyway.
ASP.NET Web Forms Events (e.g. _Click)
(This is why I ditched Web Forms for MVC, I strongly suggest you do the same).
ASP.NET Web Forms emulates WinForms by wrapping the entire page in a <form> element, then adding client-script to all of the control elements, such as <asp:Hyperlink> and <asp:Button> which causes the entire <form> to submit a POST back to the server, which re-creates the form and, during processing, raises these events. This is a particularly ingenious, if misguided, design. Fortunately it has been made obsolete by MVC, but I digress.
...it means that when you have <asp:Hyperlink> with a _Click handler in the server code it means that you're getting <a onclick="__doPostback()"> instead of <a href="URL to redirect to" />, so it provides a very poor user-experience, makes things brittle (as data not within the <form> element is not saved), and means you can run into problems like these where it's unclear (from a client-side perspective) where logic is being carried out: logically a link should be executed by the client, not the server.
Response.Redirect
Response.Redirect is a shortcut of sending a HTTP 3xx redirect to the client and ending further processing of the page. It sends this redirection back instead of the complete page response. A HTTP redirection can only tell the browser to follow it to the new location, there are no other options it can specify.
Conclusion
Piece these things together and you see that there is no way <asp:Hyperlink onclick="delegate() { Response.Redirect("someUrl") }" /> can cause someUrl to be loaded in a new browser tab.
I suggest that instead you use straightforward <a href="someUrl" /> without using any server-side logic. I can't see why you even need to at all in this case.
If you think out of the box, there is always a way to solve this.
Look at this SO post. response-redirect-to-new-window. I went with the Extention Method way it it works. Yes, if they disable javascript, it does not, but who does that? Not your normal person and they are likely used to issues with not enabling javascript.
Or, you could do this:
Protected Sub Button2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim url As String = "Page2.aspx"
Dim sb As New StringBuilder()
sb.Append("<script type = 'text/javascript'>")
sb.Append("window.open('")
sb.Append(url)
sb.Append("');")
sb.Append("</script>")
ClientScript.RegisterStartupScript(Me.GetType(), _
"script", sb.ToString())
End Sub
In ASP.Net, I want to run some code (logging, other cleanup) after the page has already been sent to the user. I don't want this code to interfere with the amount of time it takes the client to receive a response. I tried placing this code in the OnUnload part of the page, but through testing (using breakpoints, or busy waiting loops) the client does not actually display the page until the code in the OnUnload is finished executing. Even though the response object is no longer available at this point, and therefore I would assume that the buffered response has been sent to the client, the client still does not display the page until the OnUnload is finished executing. The only way that seems to work at the moment is to start a new thread to do the work, and allow the OnUnload to finish immediately. However, I don't know if this is safe or not. Will the server kill the thread if it executes too long after the page is already sent out? Is there a more correct way to accomplish this?
Kibbee,
Try overriding the Page.Render method and flushing the response like so:
Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
MyBase.Render(writer)
Response.Flush() ' Sends all buffered output to the client
' Run some code after user gets their content
End Sub
I think at this point the response still isn't complete, but the user will get what the page has rendered before you finish running that final code.
HTH,
Mike
Unload is the last part of the ASP.NET page life cycle. See link below:
http://msdn.microsoft.com/en-us/library/ms178472.aspx
Is this something you could do with javascript or AJAX?
How about hooking into the page.Disposed event instead of the Unload event?
Depending on what you need to do an ISAPI filter can be created to do stuff at the end of the response.
You could try this solution - Best ASP.NET Background Service Implementation
Using a windows service and communicating with it through MSMQ might be a far more reliable solution and can scale up better. This will help you separate the concerns and let asp.net front end just focus on the user while the windows service focusses on the background tasks.
If you are moving to the cloud with azure, you can simply replace the asp.net front end with a web role and the windows service with a worker role and ur solution can scale seamlessly!
Here's a redneck way to do it. Have a second aspx page that does all your "clean up" post-rendering logic. Call that one 'cleanup.aspx' for example. Have your clean up code run in Page_Load of cleanup.aspx:
public partial class cleanup: System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// do logging blah blah here....
}
}
In your main aspx page, have a JavaScript function that makes an AJAX call to 'cleanup.aspx'. Make the AJAX function fire after page load. I recommend jquery, if so your code will look like this:
$(function(){
yourAJAXYFunctionName();
});
function yourAJAXYFunctionName()() {
// ajax code here
//
$.ajax({
url: "cleanup.aspx",
});
}
This way, your first page's code runs, then the page is sent to the browser. As the page renders to the client, the 2nd ASPX page is called via AJAX, which really doesn't matter to cleanup.aspx, it doesn't care how its called and its page load event is executed. Your cleanup/logging code is then ran.
Caveats: client side JavaScript is required. But really who the hell doesn't have JS running anyway? Also, your cleanup.aspx page is totally abstracted from your main page, so if you want to use any object in cleanup.aspx that originated in your first page, then you'll have to store them in session or cookies, or you can pass them as parameters in the AJAX call. That will require dynamic manipulation of the AJAX script itself, but that's not too hard.
Better i think try try{Response.End()}catch{} runcode();
In my global.asax file for my ASP.net project, I am checking for certain conditions. When those conditions are met, I want to automatically execute javascript code when the page runs.
This is my code:
if condition Then
Response.Write(" < script type=""text/javascript"" > ")
Response.Write(" // Javascript code to do stuff ")
Response.Write(" < /script > ")
End If
While this appears to work to execute the Javascript code, I don't think it's a best practice because this code will preceed all of the HTML of the page that gets loaded.
What is the best way of programmatically tacking on some extra Javascript code to be run when my page loads?
Update Thanks for the answer. Too bad this solution doesn't work from within global.asax. Is there no way to make this happen site-wide? It seems like global.asax would be the logical place to put code that runs with every page... Response.Write works fine in global.asax.
To correctly manage the placement of scripts from server controls or pages, you should use ClientScriptManager.RegisterStartupScript()
You can also use the equivalent method in the ScriptManager if you are using ajax controls in your site: ScriptManager.RegisterStartupScript
These methods take care of outputting your script in the appropriate locations to be run when the document is finished loading. The links posted have some good examples to work from.
Note that you won't be able to use these methods directly from global.asax, as it has no reference to the current page. Global.asax is for hooking events to the HttpApplication pipeline, and is decoupled from the actual HttpHandler such as your Page object. To keep the separation of UI, you'd be better off to do the check in your master page or in some base page class, and output the script from there.
back in the days of asp.net ajax 1.0 we had something called Sys.WebForms.PageRequestManager in the ajax client libraries. Haven't worked with asp.net 3.5 and asp.net ajax, but I am sure it is simply enough to add the asp.net ajax javascript file into your page and you'll be able to make use of it. Check out for an event called pageLoaded event.
ps: this event will fire every time there is a sync or async postback
If you want to do it on every page, put it on your masterpage if you have one.
If not, you can create a base Page class, that inherits from System.Web.UI.Page and extend it to check your conditions & render javascript.
Then in the codebehind of each page, inherit your base Page Class instead of System.Web.UI.Page
public partial class Orders : MyCode.BasePage
I'm using a custom control in ASP.NET that handles file uploading for me. The control has a handler in the code-behind using something like this:
Protected Sub UploadFileComplete(ByVal sender As Object, ByVal e As UploadControl.FileUploadCompleteEventArgs) Handles UploadControl.FileUploadComplete
Within that sub, I post back to the server and do some work on the database, but then when I come back, I want JavaScript to register at that point.
However, when I use Page.ClientScript.RegisterClientScriptBlock or ScriptManager.RegisterClientScriptBlock, the scripts don't load on the page. I need this JavaScript to run and update the page, and to close the upload dialog window. I assume it's because the page is already loaded.
Does anyone have any good ideas on how to do this?
Alright so turns out it's like this...
On the server side (code-behind), in the UploadFileComplete() sub, you can access that EventArgs variable by using the method e.CallbackData = [WHATEVER].
And then in your javascript, you use this built in client function:
function UploadComplete(args){
alert(args.callbackData);
}
And that args.callbackData variable has whatever you put in via server side. Pretty slick I think! But hard to figure out cause they didn't have it documented very well.
This way, you don't need to add your own RegisterClientScriptBlock method, because you can pass in anything you want to JavaScript using their built in method.