Post Back не работает после записи файлов в ответ в ASP.NET
Что у меня есть?
У меня есть страница ASP.NET, которая позволяет пользователю загружать файл a
нажатием кнопки. Пользователь может выбрать желаемый файл из списка доступных файлов (RadioButtonList) и щелкнуть по кнопке загрузки, чтобы загрузить его. (Я не должен предоставлять ссылку для каждого файла, который можно загрузить - это требование).
Что мне нужно?
Я хочу, чтобы пользователь загружал несколько файлов один за другим, выбирая нужный переключатель и нажав кнопку.
С какой проблемой сталкиваюсь?
Я могу загрузить файл в первый раз правильно. Но после загрузки, если я выберу какой-то другой файл и нажму кнопку, чтобы загрузить его, нажмите кнопку, когда кнопка не отправит сообщение, а второй файл не будет загружен.
Я использую следующий код для события нажатия кнопки:
protected void btnDownload_Click(object sender, EventArgs e)
{
string viewXml = exporter.Export();
Response.Clear();
Response.AddHeader("Content-Disposition", "attachment; filename=views.cov");
Response.AddHeader("Content-Length", viewXml.Length.ToString());
Response.ContentType = "text/plain";
Response.Write(viewXml);
Response.End();
}
Я делаю что-то не так здесь?
Одну и ту же проблему можно реплицировать в IE6, IE7 и Chrome. Я думаю, что эта проблема не зависит от браузера.
Ответы
Ответ 1
У меня была такая же проблема с sharepoint. У меня есть кнопка на странице, которая отправляет файл, и после нажатия кнопки остальная часть формы не отвечает. Оказывается, это вещь sharepoint, которая устанавливает переменную _spFormOnSubmitCalled в true, чтобы предотвратить дальнейшие отправки. Когда мы отправляем файл, это не обновляет страницу, поэтому нам нужно вручную вернуть эту переменную в значение false.
На вашей кнопке в веб-части установите OnClientClick на функцию в вашем javascript для этой страницы.
<asp:Button ID="generateExcel" runat="server" Text="Export Excel"
OnClick="generateExcel_Click" CssClass="rptSubmitButton"
OnClientClick="javascript:setFormSubmitToFalse()" />
Тогда в javascript у меня есть эта функция.
function setFormSubmitToFalse() {
setTimeout(function () { _spFormOnSubmitCalled = false; }, 3000);
return true;
}
3-секундная пауза, которую я нашел, была необходима, потому что в противном случае я устанавливал переменную до того, как установил ее sharepoint. Таким образом, я разрешаю sharepoint устанавливать его нормально, после чего я вернул его false.
Ответ 2
Небрежно, то, что вы делаете, должно работать. Я успешно сделал подобное в прошлом, хотя использовал ретранслятор и LinkButtons.
Единственное, что я вижу, это то, что вы используете Response.Write()
, а не Response.OutputStream.Write()
, и что вы пишете текст, а не двоичный, но учитывая указанный ContentType
, он не должен быть проблемой. Кроме того, я вызываю Response.ClearHeaders()
перед отправкой информации и Response.Flush()
после (до моего вызова Response.End()
).
Если это поможет, вот санированная версия того, что хорошо работает для меня:
// called by click handler after obtaining the correct MyFileInfo class.
private void DownloadFile(MyFileInfo file)
{
Response.Clear();
Response.ClearHeaders();
Response.ContentType = "application/file";
Response.AddHeader("Content-Disposition", "attachment; filename=\"" + file.FileName + "\"");
Response.AddHeader("Content-Length", file.FileSize.ToString());
Response.OutputStream.Write(file.Bytes, 0, file.Bytes.Length);
Response.Flush();
Response.End();
}
Возможно, вам стоит рассмотреть возможность переноса файла двоичным способом, возможно, вызывая System.Text.Encoding.ASCII.GetBytes(viewXml);
и передавая его результат в Response.OutputStream.Write()
.
Немного измените свой код:
protected void btnDownload_Click(object sender, EventArgs e)
{
string viewXml = exporter.Export();
byte [] bytes = System.Text.Encoding.ASCII.GetBytes(viewXml);
// NOTE: you should use whatever encoding your XML file is set for.
// Alternatives:
// byte [] bytes = System.Text.Encoding.UTF7.GetBytes(viewXml);
// byte [] bytes = System.Text.Encoding.UTF8.GetBytes(viewXml);
Response.Clear();
Response.ClearHeaders();
Response.AddHeader("Content-Disposition", "attachment; filename=views.cov");
Response.AddHeader("Content-Length", bytes.Length.ToString());
Response.ContentType = "application/file";
Response.OutputStream.Write(bytes, 0, bytes.Length);
Response.Flush();
Response.End();
}
Ответ 3
Простым способом сделать это без удаления Response.End
является добавление js на стороне клиента для обновления страницы. Добавьте js к свойству onclientclick.
например.
onclientclick="timedRefresh(2000)"
then in your html..
<script type="text/JavaScript">
<!--
function timedRefresh(timeoutPeriod) {
setTimeout("location.reload(true);",timeoutPeriod);
}
// -->
Ответ 4
Удалите Response.End()
и дайте ответ конечно в рамках экосистемы ASP.NET.
Если это не сработает, я бы рекомендовал поместить кнопку в отдельный <form>
и отправить необходимые данные отдельному обработчику HTTP. Установите обработчик HTTP для экспорта XML вместо веб-страницы.
Ответ 5
У меня была такая же проблема. Функция для выполнения простого Response.Writer("") при нажатии кнопки Click на странице aspx никогда не срабатывала.
Метод в классе:
public test_class()
{
public test_class() { }
public static void test_response_write(string test_string)
{
HttpContext context = HttpContext.Current;
context.Response.Clear();
context.Response.Write(test_string);
context.Response.End();
}
}
Страница ASPX:
protected void btn_test_Click(object sender, EventArgs e)
{
test_class.test_response_write("testing....");
}
Пока я пытался найти причину, я только что вызвал ту же функцию в событии Page_Load
, в котором он работал.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
test_class.test_response_write("testing....");
}
}
Исследуя проблему, я узнал, что главная страница этого тела страницы aspx находится под <asp:UpdatePanel>
.
Я удалил его, и он работал над Button_Click
Event. Я бы порекомендовал вам также проверить это.