#c# #asp.net #server-side-rendering
Вопрос:
Команда!!
У меня есть веб-сайт, который позволяет людям загружать данные в файл excel или pdf. Загрузка занимает достаточно много времени, поэтому я хочу, чтобы во время обработки отображался режим «Пожалуйста, подождите». Я нашел какой-то код, который делает это, но проблема в том, что он просто считает от 1 до 100, а затем бросает. Я хотел бы изменить это, чтобы оно отображалось до завершения загрузки.
Когда пользователь нажимает кнопку, чтобы начать экспорт, вызывается функция expot_click. Функция WorkerMethod, расположенная ниже, передается в класс и содержит количество от 1 до 100. Я не знаю, что изменить или где это изменить.
protected void export_click(object sender, EventArgs e)
{
string exportType = hidExportType.Value;
string exportSections = hidSections.Value;
string exportStudents = hidStudents.Value;
//Display a "Please Wait" message while the download is happening
object result = WaitWindow.Show(this.WorkerMethod);
switch (exportType)
{
case "csv":
export_csv(exportSections, exportStudents);
break;
case "excel":
export_excel(exportSections, exportStudents);
break;
case "pdf":
export_pdf(exportSections, exportStudents);
break;
default:
break;
}
//I'm guessing here is where I'd want to do something to make the wait display quit?
}
private void WorkerMethod(object sender, Jacksonsoft.WaitWindowEventArgs e)
{
// Do something
for (int progress = 1; progress <= 100; progress )
{
System.Threading.Thread.Sleep(20);
// Update the wait window message
e.Window.Message = string.Format
("Please wait ... {0}%", progress.ToString().PadLeft(3));
}
// Use the arguments sent in
if (e.Arguments.Count > 0)
{
// Set the result to return
e.Result = e.Arguments[0].ToString();
}
else
{
// Set the result to return
e.Result = "Hello World";
}
}
Ниже приведен класс, который вызывается:
/*
* Created by SharpDevelop.
* User: mjackson
* Date: 05/03/2010
* Time: 09:36
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace Jacksonsoft
{
/// <summary>
/// Displays a window telling the user to wait while a process is executing.
/// </summary>
public class WaitWindow
{
/// <summary>
/// Shows a wait window with the text 'Please wait...' while executing the passed method.
/// </summary>
/// <param name="workerMethod">Pointer to the method to execute while displaying the wait window.</param>
/// <returns>The result argument from the worker method.</returns>
public static object Show(EventHandler<WaitWindowEventArgs> workerMethod){
return WaitWindow.Show(workerMethod, null);
}
/// <summary>
/// Shows a wait window with the specified text while executing the passed method.
/// </summary>
/// <param name="workerMethod">Pointer to the method to execute while displaying the wait window.</param>
/// <param name="message">The text to display.</param>
/// <returns>The result argument from the worker method.</returns>
public static object Show(EventHandler<WaitWindowEventArgs> workerMethod, string message){
WaitWindow instance = new WaitWindow();
return instance.Show(workerMethod, message, new List<object>());
}
/// <summary>
/// Shows a wait window with the specified text while executing the passed method.
/// </summary>
/// <param name="workerMethod">Pointer to the method to execute while displaying the wait window.</param>
/// <param name="message">The text to display.</param>
/// <param name="args">Arguments to pass to the worker method.</param>
/// <returns>The result argument from the worker method.</returns>
public static object Show(EventHandler<WaitWindowEventArgs> workerMethod, string message, params object[] args){
List<object> arguments = new List<object>();
arguments.AddRange(args);
WaitWindow instance = new WaitWindow();
return instance.Show(workerMethod, message, arguments);
}
#region Instance implementation
private WaitWindow(){}
private WaitWindowGUI _GUI;
internal delegate void MethodInvoker<T>(T parameter1);
internal EventHandler<WaitWindowEventArgs> _WorkerMethod;
internal List<object> _Args;
/// <summary>
/// Updates the message displayed in the wait window.
/// </summary>
public string Message{
set{
this._GUI.Invoke(new MethodInvoker<string>(this._GUI.SetMessage), value);
}
}
/// <summary>
/// Cancels the work and exits the wait windows immediately
/// </summary>
public void Cancel(){
this._GUI.Invoke(new MethodInvoker(this._GUI.Cancel), null);
}
private object Show(EventHandler<WaitWindowEventArgs> workerMethod, string message, List<object> args){
// Validate Parameters
if (workerMethod == null){
throw new ArgumentException("No worker method has been specified.", "workerMethod");
} else {
this._WorkerMethod = workerMethod;
}
this._Args = args;
if (string.IsNullOrEmpty(message)){
message = "Please wait...";
}
// Set up the window
this._GUI = new WaitWindowGUI(this);
this._GUI.MessageLabel.Text = message;
// Call it
this._GUI.ShowDialog();
object result = this._GUI._Resu<
// clean up
Exception _Error = this._GUI._Error;
this._GUI.Dispose();
// Return result or throw and exception
if (_Error != null){
throw _Error;
} else {
return resu<
}
}
#endregion Instance implementation
}
}
Любые предложения о том, что нужно сделать, чтобы это сработало, будут высоко оценены!!
Комментарии:
1. Некоторое разъяснение, почему вы хотите показать некоторый пользовательский интерфейс на (безголовом) сервере, было бы полезно. Обычно никто не смотрит на серверы, чтобы увидеть такой пользовательский интерфейс…
2. Вы не можете отображать информацию об окнах на стороне браузера. Ваш код отобразит окно на веб-сервере, расположенном в здании, где работает веб-сервер. Таким образом, вы не можете использовать ЧТО — либо связанное с рабочим столом Windows для веб-браузера-они вообще не связаны. Способ, которым это будет работать, заключается в том, что нажатие кнопки для запуска процесса загрузки должно отображать всплывающее окно с клиентской стороной JavaScript, а ЗАТЕМ запускать код нажатия кнопки на стороне сервера.
Ответ №1:
Вы не можете использовать окно на стороне сервера.
но что вы можете сделать, так это открыть или отобразить диалоговое окно, КОГДА пользователь нажимает на кнопку. Это всплывающее диалоговое окно будет оставаться открытым, пока веб-страница находится на обрабатываемом сервере. Когда страница сервера будет завершена, эта новая свежая страница сервера будет отправлена обратно в браузер на стороне клиента, и, таким образом, отображаемое сообщение исчезнет само по себе.
Итак, скажите, что ваша кнопка для запуска процесса-это простая кнопка. При нажатии на этот «более длинный» код на стороне сервера запускается.
Таким образом, вы сохраняете вставку, но добавляете сценарий на стороне клиента, чтобы вывести диалоговое сообщение. В этом случае мы будем использовать jQuery.Диалоговое окно пользовательского интерфейса. Итак, вам понадобится на веб-странице jQquery и jQuery.UI.
Итак, теперь простой код кнопки становится таким:
<asp:Button ID="cmdBigProcess" runat="server" Text="Start the reactor!"
OnClientClick="showait();return true;"
OnClick="cmdBigProcess_Click" />
<div id="mywait" style="display:none;border:solid">
<h2>Big process running - please wait</h2>
</div>
<script>
function showait() {
// lets pop jquery.UI dialog
var mydiv = $("#mywait")
mydiv.dialog({
modal: true, appendTo: "form",
title: "Please wait", closeText: "",
width: "400px"
});
}
</script>
Итак, мы добавили простой «div», который будет содержать сообщение.
Теперь, когда вы нажимаете на кнопку, сначала запускается код «при нажатии на клиента» и отображается диалоговое окно, затем запускается код на стороне сервера. Как уже отмечалось, нам не нужно закрывать или что-либо делать с диалогом, так как при публикации веб-страницы она перемещается на сервер. Код, лежащий в основе, запускается (может изменить или не изменить что-либо на веб-странице), а затем, когда страница завершена, вся веб-страница теперь перемещается обратно на веб-сторону, браузер перерисовывает и повторно загружает веб-страницу (это так называемый цикл туда и обратно или часто называемый жизненным циклом страницы. крайне важно, чтобы вы поняли и поняли эту концепцию кругосветного путешествия. Ваш код, лежащий в основе, НИКОГДА напрямую не взаимодействует с пользователем. Но при нажатии кнопки ВСЯ веб-страница перемещается на сервер, код запускается. И ДАЖЕ когда код изменяет элементы управления и прочее на веб-странице? Они НЕ будут отображаться, НЕ обновляться, и пользователь не увидит никаких изменений на этой веб-странице до тех пор, пока ВЕСЬ ВАШ код не будет выполнен. Как только код будет выполнен, ВСЯ страница вернется в браузер и будет загружена повторно.
Таким образом, повторная загрузка страницы-это то, что на самом деле приведет к тому, что всплывающее диалоговое окно будет закрыто. Обратите внимание, что jQuery.Диалоги пользовательского интерфейса (и большинство веб — диалогов) НЕ останавливают код при вызове- код продолжается.
Результат выглядит так:
Комментарии:
1. Спасибо! Я не знаю, почему мне никогда не приходило в голову, что у вас могут быть одновременные события onclick как для клиентской, так и для серверной сторон на одной и той же кнопке 🙁