2017-05-25 124 views
0

我不確定這裏發生了什麼。Azure Web應用程序上的響應頭問題

當我在本地運行我的web應用程序並單擊一個按鈕下載文件時,該文件被正確下載並返回頭文件,如您在本地所示的附加屏幕截圖中所見。

但是,當我將應用程序發佈到天藍色的web應用程序。不知何故,下載按鈕停止工作。我檢查了響應頭,你可以看到差異。

什麼會導致此問題?代碼是一樣的嗎?是否有任何設置應該在Azure門戶中的Azure Web應用程序中設置?

enter image description here

更新添加代碼

我有遠程調試弄清楚是怎麼回事作爲@Amor建議。

這很奇怪,當我在本地機器上調試時,首先導出ExportTo動作,準備TempData,然後在第一個動作完成後使用ajax調用下載動作。

但是,當我遠程調試時情況並非如此。不知何故,ExportTo動作永遠不會被調用。它直接調用下載操作。因此,TempData空檢查始終爲空。

但是爲什麼?爲什麼在地球上以及這可能如何?有什麼地方緩存嗎?

我已經擦除了遠程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 Web應用程序上發生的一件奇怪事情是,ExportTo操作斷點永遠不會被擊中。

我不知道還有什麼我可以改變,以獲得導出到行動命中?

回答

2

根據Azure Web App的Response Header,我們發現Content-Length的值爲0.它表示沒有數據從Web應用服務器端發送。

在ASP.NET MVC中,我們可以使用以下方式響應文件。

第一種方式,發送託管在服務器上的文件。爲此,請檢查excel文件是否已上傳到Azure Web App。您可以使用Kudu或FTP來查看文件夾是否存在。第二種方式,我們可以從任何位置(數據庫,服務器或天藍色存儲)讀取文件並將文件內容發送到客戶端。這樣,請檢查文件是否已成功讀取。您可以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); 

2017年5月27日更新

不知何故,ExportTo動作不會被調用。它直接調用下載操作。因此,TempData空檢查始終爲空。

您的Web App分配了多少個實例?如果Web應用程序具有多個實例,則ExportTo請求由一個實例處理,而「下載」請求由另一個實例處理。由於TempData存儲在專用實例的內存中,因此無法從另一個實例獲取。根據遠程調試文檔。我找出了爲什麼ExportTo操作永遠不會被調用的原因。

如果您確實有多個Web服務器實例,那麼當您連接到調試器時,您將得到一個隨機實例,並且無法確保後續的瀏覽器請求將轉到該實例。

要解決此問題,我建議您直接從ExportTo操作響應數據或將臨時數據保存在無法從多個實例訪問的Azure blob存儲中。

+0

謝謝@Amor提供您的答案。我更新了我的問題以添加代碼。我在遠程調試了天藍色的web應用程序,我可以看到一個問題,正如我在問題中詳述的。任何想法爲什麼發生這種情況? – akd

+0

我根據你的評論更新了我的答案。 – Amor

+0

我沒有意識到任何由Azure爲Web應用程序創建的實例。我想你已經救了我。我禁用了Web應用程序的ARR Affinity。現在這一切都變得更有意義。因此,如果您禁用ARR親和力,如您所述,如果您的應用程序不是完全無狀態的應用程序,比如tempdata等,那麼調試幾乎沒用。但是有人應該寫一個關於這個好主意的博客來警告人們。回到這個問題,無法響應來自ExportTo操作的數據,因爲它被ajax調用來傳遞過濾器數據。 – akd