Azure Web应用程序

时间:2017-05-25 16:28:30

标签: asp.net-mvc azure-web-sites response-headers

我不确定这里发生了什么。

当我在本地运行我的Web应用程序并单击按钮下载文件时,该文件已正确下载并且可以在附加的屏幕截图中看到响应标题,其中它表示本地。

但是当我将应用程序发布到azure web app时。不知何故,下载按钮停止工作。我检查了响应标题,你可以看到差异。

什么会导致这个问题?代码是一样的吗?我是否应该在azure门户网站的azure web app中设置任何设置?

enter image description here

  

已更新以添加代码

我已经远程调试,以确定@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操作命中?

1 个答案:

答案 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存储中,这些数据无法从多个实例访问。