导出使用HttpContext.Current.Response是造成问题

我正在开发一个使用asp.net/C#/HTML5/bootstrap的网站。 其中一个要求是将文档导出为Excel和/或PDF。 我能够导出(成功)使用以下代码片段(这是Excel代码段):

HttpContext.Current.Response.ContentType = "application/octet-stream"; HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF8; HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=" + filename); HttpContext.Current.Response.BinaryWrite(xlsBytes); HttpContext.Current.Response.Flush(); HttpContext.Current.Response.End(); 

我遇到的问题是,在运行之后,似乎是停止页面生命周期中的轨道。 作为一个例子,用户点击导出button,调用JavaScript抛出一个“请稍候”模式对话框,并提交表单:

 <script src="../Scripts/waitingFor.js"></script> <script type="text/javascript"> function pleaseWait() { waitingDialog.show("Building File<br/>...this could take a minute", { dialogSize: "sm", progressType: "warning" }); form = document.getElementById("frm_contentMaster"); form.submit(); } </script> 

javascript包含文件:

 /** * Module for displaying "Waiting for..." dialog using Bootstrap * * @author Eugene Maslovich <ehpc@em42.ru> */ (function (root, factory) { 'use strict'; if (typeof define === 'function' && define.amd) { define(['jquery'], function ($) { return (root.waitingDialog = factory($)); }); } else { root.waitingDialog = root.waitingDialog || factory(root.jQuery); } }(this, function ($) { 'use strict'; /** * Dialog DOM constructor */ function constructDialog($dialog) { // Deleting previous incarnation of the dialog if ($dialog) { $dialog.remove(); } return $( '<div id="waitingFor" class="modal fade" data-backdrop="static" data-keyboard="false" tabindex="-1" role="dialog" aria-hidden="true" style="padding-top:15%; overflow-y:visible;">' + '<div class="modal-dialog modal-m">' + '<div class="modal-content">' + '<div class="modal-header" style="display: none;"></div>' + '<div class="modal-body">' + '<div class="progress progress-striped active" style="margin-bottom:0;">' + '<div class="progress-bar" style="width: 100%"></div>' + '</div>' + '</div>' + '</div>' + '</div>' + '</div>' ); } // Dialog object var $dialog; return { /** * Opens our dialog * @param message Custom message * @param options Custom options: * options.headerText - if the option is set to boolean false, * it will hide the header and "message" will be set in a paragraph above the progress bar. * When headerText is a not-empty string, "message" becomes a content * above the progress bar and headerText string will be set as a text inside the H3; * options.headerSize - this will generate a heading corresponding to the size number. Like <h1>, <h2>, <h3> etc; * options.headerClass - extra class(es) for the header tag; * options.dialogSize - bootstrap postfix for dialog size, eg "sm", "m"; * options.progressType - bootstrap postfix for progress bar type, eg "success", "warning"; * options.contentElement - determines the tag of the content element. * Defaults to "p", which will generate a <p> tag; * options.contentClass - extra class(es) for the content tag. */ show: function (message, options) { // Assigning defaults if (typeof options === 'undefined') { options = {}; } if (typeof message === 'undefined') { message = 'Loading'; } var settings = $.extend({ headerText: '', headerSize: 3, headerClass: '', dialogSize: 'm', progressType: '', contentElement: 'p', contentClass: 'content', onHide: null // This callback runs after the dialog was hidden }, options), $headerTag, $contentTag; $dialog = constructDialog($dialog); // Configuring dialog $dialog.find('.modal-dialog').attr('class', 'modal-dialog').addClass('modal-' + settings.dialogSize); $dialog.find('.progress-bar').attr('class', 'progress-bar'); if (settings.progressType) { $dialog.find('.progress-bar').addClass('progress-bar-' + settings.progressType); } // Generate header tag $headerTag = $('<h' + settings.headerSize + ' />'); $headerTag.css({ 'margin': 0 }); if (settings.headerClass) { $headerTag.addClass(settings.headerClass); } // Generate content tag $contentTag = $('<' + settings.contentElement + ' />'); if (settings.contentClass) { $contentTag.addClass(settings.contentClass); } if (settings.headerText === false) { $contentTag.html(message); $dialog.find('.modal-body').prepend($contentTag); } else if (settings.headerText) { $headerTag.html(settings.headerText); $dialog.find('.modal-header').html($headerTag).show(); $contentTag.html(message); $dialog.find('.modal-body').prepend($contentTag); } else { $headerTag.html(message); $dialog.find('.modal-header').html($headerTag).show(); } // Adding callbacks if (typeof settings.onHide === 'function') { $dialog.off('hidden.bs.modal').on('hidden.bs.modal', function () { settings.onHide.call($dialog); }); } // Opening dialog $dialog.modal(); }, /** * Closes dialog */ hide: function () { if (typeof $dialog !== 'undefined') { $dialog.modal('hide'); } } }; })); 

我正在使用NPOI在后面的代码(简化函数)中创buildExcel文件:

 using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; protected void exportExcel() { XSSFWorkbook wb = new XSSFWorkbook(); XSSFSheet sh = (XSSFSheet)wb.CreateSheet("Legend"); //***************************************** //* Workbook Download & Cleanup //***************************************** MemoryStream stream = new MemoryStream(); wb.Write(stream); stream.Dispose(); var xlsBytes = stream.ToArray(); string filename = "Behavior Stats YTD.xlsx"; MemoryStream newStream = new MemoryStream(xlsBytes); HttpContext.Current.Response.ContentType = "application/octet-stream"; HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF8; HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=" + filename); HttpContext.Current.Response.BinaryWrite(xlsBytes); HttpContext.Current.Response.Flush(); HttpContext.Current.Response.End(); } 

这将创buildExcel文件并将其推送给用户,但后面的代码的生命周期不会继续 – 在End命令后立即停止。 如果我注释掉HttpContext行,显然Excel表格不会被创build,但是页面的生命周期仍在继续 – 其余的代码运行,页面刷新,模式Please Wait对话框消失。

所以我用这个错误? 我见过的大多数例子都是用这个方法导出的。 我还有另一种更清洁和/或更安全的出口方式吗? 我需要做一个简单的调整,这将使生命周期继续下去吗? 谁创造了液体肥皂,为什么?

任何帮助,您可以提供将大大,非常感谢。

它的工作完全按照它应该的。 您正在告诉浏览器该响应是一个文件。 回应一次只能是一件事。 你不能有相同的回应页面内容和文件。

您可以通过在IFrame中下载文件来分开这两个文件。 首先把你的文件下载C#代码在自己的页面。 然后使用JavaScript函数从IFrame调用该页面。

 function DownloadExcel() { var downloadFrame = document.createElement("IFRAME"); if (downloadFrame != null) { downloadFrame.setAttribute("src", '/DownloadExcel.aspx'); downloadFrame.style.width = "0px"; downloadFrame.style.height = "0px"; document.body.appendChild(downloadFrame); } }