Post Back не работает после записи файлов для ответа в ASP.NET - PullRequest
44 голосов
/ 25 февраля 2010

Что у меня есть?

У меня есть страница 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. Я думаю, что эта проблема не зависит от браузера.

Ответы [ 6 ]

58 голосов
/ 19 июня 2013

У меня была такая же проблема с 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.

4 голосов
/ 19 сентября 2010

Простой способ сделать это без удаления 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 голосов
/ 25 февраля 2010

От руки, то, что вы делаете, должно работать. Я успешно делал подобное в прошлом, хотя я использовал повторитель и кнопки 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 голосов
/ 04 ноября 2013

У меня была такая же проблема. Функция для выполнения простого Response.Writer ("") для события нажатия кнопки на странице 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 Событии. Я бы порекомендовал вам это тоже проверить.

3 голосов
/ 25 февраля 2010

Удалите Response.End() и дайте естественному завершению ответа в экосистеме ASP.NET.

Если это не сработает, я бы порекомендовал поместить кнопку в отдельный <form> и отправить необходимые данные в отдельный обработчик HTTP. Настройте обработчик HTTP для экспорта XML вместо веб-страницы.

0 голосов
/ 28 июля 2018

Чек на https://multilingualdev.wordpress.com/2014/08/19/asp-net-postback-after-response-write-work-around-solution/

При отправке файла клиенту и использовании response.write в ASP.Net разработчик не может сделать что-либо еще после отправки файла. Существуют и другие обходные пути, такие как добавление функции javascript onclick, которая будет вызывать функцию после того, как клиент получит файл, что аналогично добавлению мета-обновления в функцию, когда вызывается функция отправки файла (например, Response.AppendHeader ( Обновить »,« 5; URL = »& HttpContext.Current.Request.Url.AbsoluteUri))

Но те не смотрели на меня так, как я хотел. Поэтому я использовал комбинацию из этих обходных путей, чтобы придумать это решение:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

checkSendFile() ‘each time page loads it will check to see if it needs to send the file

If (Not IsPostBack) Then

‘this spot is not be executed after a form submit (postback); which means you can put 

‘ the checkSendFile() in here if you want

end If

End Sub

Private Sub checkSendFile()

Dim sendFile As String = Session(“SENDFILE”) ‘ first we get the session file to see if its time 

‘ to send a file

If Not sendFile Is Nothing Then

If sendFile = “YES” Then

Session(“SENDFILE”) = “” ‘here we clear the session file so it doesn’t send again if

‘ refreshed

sendClientFile() ‘ function to send the file to client

End If

End If

End Sub

Protected Sub btnGetFile_Click(sender As Object, e As EventArgs) Handles btnGetFile.Click

‘this is where the client clicks on a button or link or something that submits the form and 

‘ request a file to be sent to them

Session(“SENDFILE”) = “YES” ‘ we set a session variable flag 

‘then we update the GUI, or run any other method that we wanted to do after client gets file

me.lblMsgToClient.text = “Thank you for downloading file.”

RefreshPage() ‘ then we refresh the page instantly (this is where post back will update values

‘ and interface, then send file)

End Sub

Private Sub RefreshPage()

‘ here we instantly add a refresh meta tag to the header with zero seconds to refresh to the

‘ same url we are currently at

Response.AppendHeader(“Refresh”, “0;URL=” & HttpContext.Current.Request.Url.AbsoluteUri)

End Sub

Private Sub sendClientFile()

‘here you will have your file and bytes to send to browser from either file system or database

‘then you can call sendToBrowser(…)

End Sub

Private Sub sendToBrowser(ByVal fileName As String, ByVal contentType As String, ByRef fileBytes As Byte())

‘this function is just the normal send file to client

Response.AddHeader(“Content-type”, contentType)
Response.AddHeader(“Content-Disposition”, “attachment; filename=” & fileName)
Response.BinaryWrite(fileBytes)
Response.Flush()
Response.End()

End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...