我不确定这里发生了什么。
当我在本地运行我的Web应用程序并单击按钮下载文件时,该文件已正确下载并且可以在附加的屏幕截图中看到响应标题,其中它表示本地。
但是当我将应用程序发布到azure web app时。不知何故,下载按钮停止工作。我检查了响应标题,你可以看到差异。
什么会导致这个问题?代码是一样的吗?我是否应该在azure门户网站的azure web app中设置任何设置?
已更新以添加代码
我已经远程调试,以确定@Amor建议发生了什么。
很奇怪,当我在我的本地机器上进行调试时,首先执行ExportTo操作,准备TempData,然后在第一个操作完成ajax调用后调用Download动作。
然而,当我远程调试时,情况并非如此。不知怎的,ExportTo动作永远不会被调用。它直接调用下载操作。因此,TempData null检查始终为null。
但为什么呢?为什么在地球上以及如何可能?有什么东西缓存在某个地方吗?
我已经删除了远程Web应用程序的内容并重新发布了evertyhing以确保所有内容都已更新。但仍然没有成功。
这是代码:
[HttpPost]
public virtual ActionResult ExportTo(SearchVm searchVm)
{
var data = _companyService.GetCompanieBySearchTerm(searchVm).Take(150).ToList();
string handle = Guid.NewGuid().ToString();
TempData[handle] = data;
var fileName = $"C-{handle}.xlsx";
var locationUrl = Url.Action("Download", new { fileGuid = handle, fileName });
var downloadUrl = Url.Action("Download");
return Json(new { success = true, locationUrl, guid = handle, downloadUrl }, JsonRequestBehavior.AllowGet);
}
[HttpGet]
public ActionResult Download(string fileGuid, string fileName)
{
if (TempData[fileGuid] != null)
{
var fileNameSafe = $"C-{fileGuid}.xlsx";
var data = TempData[fileGuid] as List<Company>;
using (MemoryStream ms = new MemoryStream())
{
GridViewExtension.WriteXlsx(GetGridSettings(fileNameSafe), data, ms);
MVCxSpreadsheet mySpreadsheet = new MVCxSpreadsheet();
ms.Position = 0;
mySpreadsheet.Open("myDoc", DocumentFormat.Xlsx, () =>
{
return ms;
});
mySpreadsheet.Document.Worksheets.Insert(0);
var image = Server.MapPath("~/images/logo.png");
var worksheet = mySpreadsheet.Document.Worksheets[0];
worksheet.Name = "Logo";
worksheet.Pictures.AddPicture(image, worksheet.Cells[0, 0]);
byte[] result = mySpreadsheet.SaveCopy(DocumentFormat.Xlsx);
DocumentManager.CloseDocument("myDoc");
Response.Clear();
//Response.AppendHeader("Set-Cookie", "fileDownload=true; path=/");
Response.ContentType = "application/force-download";
Response.AddHeader("content-disposition", $"attachment; filename={fileNameSafe}");
Response.BinaryWrite(result);
Response.End();
}
}
return new EmptyResult();
}
这是javascript:
var exportData = function (urlExport) {
console.log('Export to link in searchController: ' + urlExport);
ExportButton.SetEnabled(false);
var objData = new Object();
var filterData = companyFilterData(objData);
console.log(filterData);
$.post(urlExport, filterData)
.done(function (data) {
console.log(data.locationUrl);
window.location.href = data.locationUrl;
});
};
单击“导出”按钮时,将调用exportData函数:
var exportToLink = '@Url.Action("ExportTo")';
console.log('Export to link in index: '+exportToLink);
SearchController.exportData(exportToLink);
正如我所提到的,此代码在本地计算机上运行良好。在azure webapp上发生了一些奇怪的事情,即ExportTo动作断点永远不会被击中。
我不确定我还能改变什么以使ExportTo操作命中?
答案 0 :(得分:2)
基于Azure Web App的响应标头,我们发现Content-Length的值为0.这意味着没有数据从Web应用服务器端发送。
在ASP.NET MVC中,我们可以使用以下方式响应文件。
第一种方式,发送托管在服务器上的文件。为此,请检查excel文件是否已上载到Azure Web App。您可以使用Kudu或FTP到文件夹来检查文件是否存在。
string fileLocation = Server.MapPath("~/Content/myfile.xlsx");
string contentType = System.Net.Mime.MediaTypeNames.Application.Octet;
string fileName = "file.xlsx";
return File(fileLocation, contentType, fileName);
第二种方式,我们可以从任何位置(数据库,服务器或azure存储)读取文件,并将文件内容发送到客户端。为此,请检查文件是否已成功读取。您可以remote debug your azure web app检查文件内容是否未以正确方式读取。
byte[] fileContent = GetFileContent();
string contentType = System.Net.Mime.MediaTypeNames.Application.Octet;
string fileName = "file.xlsx";
return File(fileContent, contentType, fileName);
5/27/2017更新
某种程度上,ExportTo操作永远不会被调用。它直接调用下载操作。因此,TempData null检查始终为null。
您的Web App分配了多少个实例?如果您的Web应用程序具有多个实例,则ExportTo请求由一个实例处理,而下载请求由另一个实例处理。由于TempData存储在专用实例的内存中,因此无法从另一个实例获取。根据远程调试文档。我找出了为什么ExportTo动作永远不会被调用的原因。
如果您有多个Web服务器实例,当您附加到调试器时,您将获得一个随机实例,并且您无法确保后续浏览器请求将转到该实例。
要解决此问题,我建议您直接从ExportTo操作响应数据,或者将临时数据保存在Azure blob存储中,这些数据无法从多个实例访问。