Подтвердить что ты не робот

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

4b9b3361

Ответ 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. Я бы порекомендовал вам также проверить это.