In my application I have a button to save some information. However, I would like to have a delay in the code before the last line is executed, so that the user could read the message that shows up before he gets redirected to the new page.
I know that doing this isn't at all an optimal way, but by some reasons (time, for example) I want to do it anyway.
So is it possible and if so, how could I do it?
Thanks in advance!
protected void SaveButton_Click(object sender, EventArgs e) {
// Lots of code not relevant for the problem here
Service service = new Service();
service.SaveMovie(movie);
successMessage.Visible = true;
happyMessage.Text = "The movie was successfully added, now add some genres!";
// Here I want a delay of 2 seconds before the next line is executed...
Response.Redirect(String.Format("~/Edit.aspx?id={0}", movie.MovieID), false);
}
You need to do this on the client side. One alternative is this:
Define a Javascript function in the page called redirect as so:
function redirect(url)
{
setTimeout(function(){window.location.href=url;} ,2000);
}
protected void SaveButton_Click(object sender, EventArgs e)
{
// Lots of code not relevant for the problem here
Service service = new Service();
service.SaveMovie(movie);
successMessage.Visible = true;
happyMessage.Text = "The movie was successfully added, now add some genres!";
// Here I want a delay of 2 seconds before the next line is executed...
ClientScript.RegisterStartupScript(this.GetType(),"somekey","redirect('"+String.Format("~/Edit.aspx?id={0}", movie.MovieID)+"');");
}
This will be easy if you are using Javascript. Use javascript will boost performance
Button_Click
{
string js ="<script type='text/javascript'>setTimeout(function()window.location.href="+String.Format("~/Edit.aspx?id={0}", movie.MovieID)+";} ,2000);</script>"
ScriptManager.RegisterStartupScript(Me.Page, GetType(Page), "js", js, False)
}
possible duplicate of
asp.net delay before response redirect
Related
Working with Xamarin Android and C# -
I want to have a download function, that just download the next item (url) from the list if the first with index 0 is finished. While Downloading, the user should be able to extend the list (add new urls for download).
My idea was to have one void OnButtonClick() (for user input) and one custom aysnc void Download() function, as well the possibility to use the "share function" (intent) to send the link directly. It is working BUT only if the user does not uses the "share function" in another app (see here: Intent.GetStringExtra). If the App gets open via this intent, the download loop gets overwritten completely. Is there a way to avoid this "bug" or another solution for a download que?
protected override void OnCreate() //gets called if activity starts
{
string catchedLink = Intent.GetStringExtra(Intent.ExtraText);
if (!String.IsNullOrEmpty(catchedLink))
{
button.Text = catchedLink;
}
}
public OnButtonClick()
{
urlList.Add(Button.Text);
}
private aysnc void Download()
{
if(IsDownloading) return;
IsDownloading = true;
do
{
await DownloadSomethingFromTheInternet(); //Let's say these two function need 2 mins to complete -
await SafeItToStorage(); //But after one minute the user adds a secound url for download
//so this loop needs to run again (see below)
urlList.Remove(urlList[0]);
} while (urlList.Count >= 1) //see here
IsDownloading = false;
}
Please leave a comment if more details are needed.
Okay it's working now:
What I did:
Save the links on the device with Preferences.Set(); not only just with a List
Added LaunchMode = Android.Content.PM.LaunchMode.SingleTask to AndroidMainfest.xml (in <activity [...] />)
Used for intent-input following code:
protected override void OnNewIntent(Intent myIntent)
{
base.OnNewIntent(myIntent);
string catchedLink = myIntent.GetStringExtra(Intent.ExtraText);
if (!String.IsNullOrEmpty(catchedLink))
{
AddVideoToQue(catchedLink);
}
}```
Thanks #Leo Zhu - MSFT for his comments and help!
The service is working fine and return the correct response. the problem is if I use sessions after calling the service, it converts to be null out of the scope which I called the service inside.
Edit 1: after tracing, I found that there is a line in MyOperation method in the service which write a text into file [ File.WriteAllText(Path, txt);], and if I comment this line, sessions works fine. any explanation ?
protected void Button1_Click(object sender, EventArgs e)
{
client = new MySvc.MyServiceClient();
var res = client.MyOperation(); // If I comment this line, sessions works fine.
Session["val"] = 2000;
}
protected void Button2_Click(object sender, EventArgs e)
{
var foo = Session["val"]; // always null
}
Please help me with that.
Wrap the three lines of code in Button1_Click in a try-catch block or just the first two lines in the try block and the last line in the finally block.
There may be an exception which is not being caught which would prevent the next line (Session["val"] = 2000;) from being performed correctly.
When the user touch the app icon,
I want do these steps before user go to the main view
Fetch json string from URI
Use JArray.Parse to get the value
After all finish, go to the main view.
The problem is how can I prevent user to go to the main view
and put all the code
I tried to put it in Application_Launching method in the App.xaml.cs file
// Code to execute when the application is launching (eg, from Start)
// This code will not execute when the application is reactivated
private void Application_Launching(object sender, LaunchingEventArgs e)
{
// code here
}
But it doesn't prevent the program to go to the main view before the fetching finished.
And I found that actually in the MainPage.xaml, if I put this code like this
protected override void OnNavigatedTo(NavigationEventArgs e)
{
while(true) {}
// it will prevent the program to go to the main view,
// and will stick with the loading screen until this function reach its end
}
So I think, I can put the all the code here, when I finish the fetch, I will just break the while and it will go to the main view automatically.
And I try, this is the code
protected override void OnNavigatedTo(NavigationEventArgs e)
{
bool isFetchFinished = false;
ObservableCollection<PromoViewModel> Promos = new ObservableCollection<PromoViewModel>();
WebClient client = new WebClient();
client.DownloadStringCompleted += (s, evt) =>
{
if (evt.Error == null)
{
// Retrieve the JSON
string jsonString = evt.Result;
JArray promos = JArray.Parse(jsonString);
foreach (JObject promo in promos)
{
string name = promo["name"].Value<string>();
string description = promo["description"].Value<string>();
string img = promo["image"].Value<string>();
Promos.Add(new PromoViewModel() { Name = name, Description = description, Img = img });
}
isFetchFinished = true;
System.Diagnostics.Debug.WriteLine("finish fetch");
}
};
// run
client.DownloadStringAsync(new Uri("the json url"));
while(true) {
if(isFetchFinished) {
App.ViewModel.LoadData(Promos); // pass value to main view model
break; // after complete, break
}
}
}
I thought it would work, but it was not.
This is what I found,
The WebClient DownloadStringAsync won't run until the OnNavigatedTo function finished.
Because it's still waiting for the while loop to break and reach the end function.
And this
isFetchFinished = true; // will never executed
Resulting infinite loop.
I think I put the fetch code in the wrong method. Where is the right place to put all of this?
Ouch, you are doing it all wrong. First of all, you have to specify the starting page. If you want to download some data before navigating to it, you can create a special "download" page that is actually the first page navigated to when starting the application. And then, once the download is completed, you navigate to your main page. This is actually a replacement for the extended splash screen.
Also, never put while (true) in any UI code, that will simply freeze the application. Besides, if the application is frozen, you never get the chance to "unfreeze" it.
I have a program that people can leave comments on a video. The comments come is as in queue status. The admin can go into the admin section and mark the comments as either approved or removed. They want to be able to automatically go to the next item marked in queue when they press either the previous or next buttons, as well as if they approve or remove a comment. I do not know jQuery or JavaScript well enough to know if it is possible to do it using those, or how to do it through the code behind (this is in C# .NET). Any help would be appreciated:
Status and value:
In queue = 0
Approved = 1
Removed = 2
Here is the code-behind. The status changes work, the only thing I cannot do is have it go to the next record marked in queue. The first two events are blank because I do not know how to fill them, but simply put, all the need to do too is go to the next record marked in queue.
If you need any more code, please let me know...
protected void previous_clicked(object sender, EventArgs e)
{
}
protected void next_clicked(object sender, EventArgs e)
{
}
protected void approve_clicked(object sender, EventArgs e)
{
currentMessage = new videomessage(Request["id"].ToString());
status.SelectedValue = "1";
currentMessage.status = "1";
currentMessage.Save();
}
protected void remove_clicked(object sender, EventArgs e)
{
currentMessage = new videomessage(Request["id"].ToString());
status.SelectedValue = "2";
currentMessage.status = "2";
currentMessage.Save();
}
Sounds more like an architectural challenge to me.
I recommend using a Queue. This is a collection type following a first-in, first-out (FIFO) approach. You put objects into the queue and get them back out in the same order. An object that was received out of this queue is automatically is removed from the queue, so you can be sure that you do not handle the same element twice.
Your described workflow then would work as these simple steps:
Whenever a message arrives, you put the object into your queue.
When the admin clicks on the next button, you request the first object out of the queue.
Your admin does his administrative tasks and approves the message.
Clicking on Next start with above item 1 again.
[EDIT]
Oops, I realized that my Queue approach would not allow for navigating back to previous items.
In this case I suggest using a simple List collection. This list can be accessed via the 0-based position in the list. This makes it easy to implement a forward/ backward navigation.
For my sample code, please bear in mind that there is a lot that I cannot know about your environment, so my code make a lot assumptions here.
You need to somwhere store a collection that contains your messages to be approved:
private IList<videomessage> _messagesToApprove = new List<videomessage>();
You will also need some variable that keeps track of the current position in your collection:
// Store the index of the current message
// Initial value depends on your environment. :-)
private int _currentIndex = 0;
To begin with, you will need a starting point where new messages are added to that collection, like subscribing to some event or so. Whenever a message arrives, add it to the collection by calling a method like:
// I made this method up because I do not know where your messages really come from.
// => ADJUST TO YOUR NEEDS.
private void onNewMessageArriving(string messageId)
{
videomessage arrivingMessage = new videomessage(messageId);
_messagesToApprove.Add(arrivingMessage);
}
The you can easily implement the navigation by incrementing/ decrementing the position index:
private void previous_Click(object sender, EventArgs e)
{
// Check that we do not go back further than the beginning of the list
if ((_currentIndex - 1) >= 0)
{
_currentIndex--;
this.currentMessage = this._messagesToApprove[_currentIndex];
}
else
{
// Do nothing if the position would be invalid
return;
}
}
private void next_Click(object sender, EventArgs e)
{
// Check if we have new messages to approve in our list.
if ((_currentIndex + 1) < _messagesToApprove.Count)
{
_currentIndex++;
currentMessage = _messagesToApprove[_currentIndex];
}
else
{
// Do nothing if the position would be invalid
return;
}
}
private void approve_Click(object sender, EventArgs e)
{
// Sorry, I don't know where exactly this comes from, needs to be adjusted to your environment
status.SelectedValue = "1";
this.currentMessage.status = "1";
this.currentMessage.Save();
// If you want to remove items that have been checked by the admin, delete it from the approval list.
// Otherwise remove this line :-)
this._messagesToApprove.RemoveAt(_currentIndex);
}
private void remove_Click(object sender, EventArgs e)
{
// Sorry, I don't know where exactly this comes from, needs to be adjusted to your environment
status.SelectedValue = "2";
this.currentMessage.status = "2";
this.currentMessage.Save();
// If you want to remove items that have been checked by the admin, delete it from the approval list.
// Otherwise remove this line :-)
this._messagesToApprove.RemoveAt(_currentIndex);
}
Save the id of current comment in session or viewstate get it back on next or previous button click and display the accordingly:
Session["id"] = 2;
int id = (int) Session["id"];
I have a Button_click event. While refreshing the page the previous Postback event is triggering again. How do I identify the page refresh event to prevent the Postback action?
I tried the below code to solve it. Actually, I am adding a visual webpart in a SharePoint page. Adding webpart is a post back event so !postback is always false each time I'm adding the webpart to page, and I'm getting an error at the else loop because the object reference is null.
if (!IsPostBack){
ViewState["postids"] = System.Guid.NewGuid().ToString();
Cache["postid"] = ViewState["postids"].ToString();
}
else{
if (ViewState["postids"].ToString() != Cache["postid"].ToString()){
IsPageRefresh = true;
}
Cache["postid"] = System.Guid.NewGuid().ToString();
ViewState["postids"] = Cache["postid"].ToString();
}
How do I solve this problem?
using the viewstate worked a lot better for me as detailed here. Basically:
bool IsPageRefresh = false;
//this section of code checks if the page postback is due to genuine submit by user or by pressing "refresh"
if (!IsPostBack)
{
ViewState["ViewStateId"] = System.Guid.NewGuid().ToString();
Session["SessionId"] = ViewState["ViewStateId"].ToString();
}
else
{
if (ViewState["ViewStateId"].ToString() != Session["SessionId"].ToString())
{
IsPageRefresh = true;
}
Session["SessionId"] = System.Guid.NewGuid().ToString();
ViewState["ViewStateId"] = Session["SessionId"].ToString();
}
This article could be of help to you
http://www.codeproject.com/Articles/68371/Detecting-Refresh-or-Postback-in-ASP-NET
you are adding a Guid to your view state to uniquely identify each page. This mechanism works fine when you are in the Page class itself. If you need to identify requests before you reach the page handler, you need to use a different mechanism (since view state is not yet restored).
The Page.LoadComplete event is a reasonable place to check if a Guid is associated with the page, and if not, create one.
check this
http://shawpnendu.blogspot.in/2009/12/how-to-detect-page-refresh-using-aspnet.html
This worked fine for me..
bool isPageRefreshed = false;
protected void Page_Load(object sender, EventArgs args)
{
if (!IsPostBack)
{
ViewState["ViewStateId"] = System.Guid.NewGuid().ToString();
Session["SessionId"] = ViewState["ViewStateId"].ToString();
}
else
{
if (ViewState["ViewStateId"].ToString() != Session["SessionId"].ToString())
{
isPageRefreshed = true;
}
Session["SessionId"] = System.Guid.NewGuid().ToString();
ViewState["ViewStateId"] = Session["SessionId"].ToString();
}
}
Simple Solution
Thought I'd post this simple 3 line solution in case it helps someone. On post the session and viewstate IsPageRefresh values will be equal, but they become out of sync on a page refresh. And that triggers a redirect which resets the page. You'll need to modify the redirect slightly if you want to keep query string parameters.
protected void Page_Load(object sender, EventArgs e)
{
var id = "IsPageRefresh";
if (IsPostBack && (Guid)ViewState[id] != (Guid)Session[id]) Response.Redirect(HttpContext.Current.Request.Url.AbsolutePath);
Session[id] = ViewState[id] = Guid.NewGuid();
// do something
}
If you want to detect a refresh on an HTTP GET rather than only POSTs, here's a hacky work-around that, in modern browsers, mostly works.
Javascript:
window.onload = function () {
// regex for finding "loaded" query string parameter
var qsRegex = /^(\?|.+&)loaded=\d/ig;
if (!qsRegex.test(location.search)) {
var loc = window.location.href + (window.location.search.length ? '&' : '?') + 'loaded=1';
window.history.replaceState(null, document.title, loc);
}
};
C#:
public bool IsPageRefresh
{
get
{
return !string.IsNullOrEmpty(Request.QueryString["loaded"]);
}
}
When the page loads, it will change add a QueryString parameter of loaded=1 without reloading the page (again, this--window.history.replaceState--only works in post-archaic browsers). Then, when the user refreshes the page, the server can check for the presence of the loaded parameter of the query string.
Caveat: mostly works
The case where this doesn't work is when the user clicks the Address Bar and presses enter. That is, the server will produce a false-positive, detecting a refresh, when odds are, the user actually meant to reload the page fresh.
Depending on your purposes, maybe this is desirable, but as a user, it would drive me crazy if I expected it to reset the page.
I haven't put too much thought into it, but it might be possible to write some magic in order to distinguish a refresh from a reset via the address bar using any/all of:
SessionState (assuming SessionState is enabled) and the value of the loaded QueryString parameter
the window.onbeforeunload event listener
keyboard events (detecting F5 and Ctrl + R to quickly change the URL back to removing the loaded QueryString parameter--though this would have a false-negative for clicking the browser's refresh button)
cookies
If someone does come up with a solution, I'd love to hear it.
Another way to check page refresh. I have written custom code without java script or any client side.
Not sure, it's the best way but I feel good work around.
protected void Page_Load(object sender, EventArgs e)
{
if ((Boolean)Session["CheckRefresh"] is true)
{
Session["CheckRefresh"] = null;
Response.Write("Page was refreshed");
}
else
{ }
}
protected void Page_PreInit(object sender, EventArgs e)
{
Session["CheckRefresh"] = Session["CheckRefresh"] is null ? false : true;
}