Проблема с заголовком ответа в веб-приложении Azure

Я не уверен, что здесь происходит.

Когда я запускаю свое веб-приложение локально и нажимаю кнопку, чтобы загрузить файл, файл загружается нормально и заголовок ответа, как вы можете видеть на прилагаемом скриншоте, где написано "локально".

Но когда я публикую приложение в лазурное веб-приложение. Почему-то перестает работать кнопка загрузки. Я проверил заголовок ответа, и вы можете увидеть разницу.

Что может вызвать эту проблему? Код такой же? Есть ли какие-либо настройки, которые я должен установить в веб-приложении Azure на портале Azure?

Обновлено, чтобы добавить код

Я отлаживал удаленно, чтобы выяснить, что происходит, как предложил @Amor.

Это так странно, что когда я отлаживаю на своей локальной машине, срабатывает первое действие ExportTo, которое подготавливает TempData, затем вызывается действие Download, как только первое действие завершается вызовом ajax.

Однако это не тот случай, когда я отлаживаю удаленно. Каким-то образом действие ExportTo никогда не вызывается. Он напрямую вызывает действие Download. В результате проверка нуля TempData всегда равна нулю.

Но почему? С какой стати и как это возможно? Где-то что-то кешируется?

Я удалил содержимое веб-приложения на удаленном компьютере и заново опубликовал все, чтобы все обновлялось. Но все равно безуспешно.

вот код:

[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);

Как я уже говорил, этот код отлично работает на локальной машине. В лазурном веб-приложении происходит нечто странное, что точка останова действия ExportTo никогда не попадает в цель.

Я не уверен, что еще я мог бы изменить, чтобы получить действие ExportTo?

1 ответ

Решение

Основываясь на заголовке ответа веб-приложения Azure, мы обнаруживаем, что значение Content-Length равно 0. Это означает, что данные не были отправлены со стороны сервера веб-приложения.

В 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) и отправить содержимое файла на клиентскую сторону. Для этого, пожалуйста, проверьте, был ли файл успешно прочитан. Вы можете выполнить удаленную отладку веб-приложения Azure, чтобы проверить, правильно ли прочитано содержимое файла.

byte[] fileContent = GetFileContent();
string contentType = System.Net.Mime.MediaTypeNames.Application.Octet;
string fileName = "file.xlsx";
return File(fileContent, contentType, fileName);

27.05.2017 Обновление

Каким-то образом действие ExportTo никогда не вызывается. Он напрямую вызывает действие Download. В результате проверка нуля TempData всегда равна нулю.

Сколько экземпляров назначено вашему веб-приложению? Если в вашем веб-приложении есть несколько экземпляров, запрос ExportTo обрабатывается одним экземпляром, а запрос на загрузку обрабатывается другим экземпляром. Поскольку TempData хранится в памяти выделенного экземпляра, его нельзя получить из другого экземпляра. По данным удаленного отладочного документа. Я выясняю причину, по которой действие ExportTo никогда не вызывается.

Если у вас есть несколько экземпляров веб-сервера, когда вы подключаетесь к отладчику, вы получаете случайный экземпляр, и у вас нет никакого способа гарантировать, что последующие запросы браузера будут идти к этому экземпляру.

Чтобы решить эту проблему, я предлагаю вам ответить на данные непосредственно из действия ExportTo или сохранить временные данные в хранилище BLOB-объектов Azure, к которым нельзя получить доступ из нескольких экземпляров.

Другие вопросы по тегам