#c# #angularjs #asp.net-mvc #jsonresult
Вопрос:
У меня есть приложение AngularJS, использующее ASP.NET MVC и я хочу вернуть запрос JSON от контроллера MVC с одним из свойств, содержащих файл, который пользователь может загрузить, если он прошел успешно. У меня есть базовый DTO, который я использую для всех запросов, чтобы я мог указывать успех / неудачу и возвращать любые сообщения, которые должен видеть пользователь.
Я смог добиться успешной загрузки файла при использовании метода window.open(someURL) в javascript и выполнении действия MVC, которое возвращает результат FileResult. Я вызываю тот же метод для генерации файла, поэтому я уверен, что файл генерируется правильно. Однако это не совсем тот пользовательский интерфейс, который я хочу, поскольку я хочу также возвращать дополнительные данные для отображения пользователю вместе с файлом. Возможно ли вернуть файл в JsonResult с дополнительными данными и разрешить пользователю загружать файл? Моя текущая реализация загружает файл, но когда я пытаюсь его открыть, я получаю сообщение об ошибке «Excel не может открыть файл xxxxxx.xlsx потому что формат файла или расширение файла недопустимы. Убедитесь, что файл не поврежден и что расширение файла соответствует формату файла «.
ПРИМЕЧАНИЕ: файл создается правильно на стороне сервера. Я смог записать его в каталог и успешно открыть. Я также смог использовать window.open для вызова действия, которое возвращает результат FileResult и которое также работает без каких-либо проблем.
Вот моя функция angularjs, которая пытается загрузить файл:
$scope.createImportFile = function () {
ctrl.TestImportCreation.Messages = resetMessageDisplay();
ctrl.TestImportCreation.IsDownloading = true;
let data = {
id: ctrl.TestImportCreation.ID
};
let service = services.createImportFile(data);
service.then(function (response) {
ctrl.TestImportCreation.IsDownloading = false;
if (response.data.IsSuccess) {
$scope.downloadFile(response.data.Entity, "ImportTestFile.xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
}
ctrl.TestImportCreation.Messages = response.data.Messages;
});
};
$scope.downloadFile = function (data, fileName, contentType) {
var blob = new Blob([data], { type: contentType });
var url = window.URL.createObjectURL(blob);
var link = document.createElement("a");
link.setAttribute("href", url);
link.setAttribute("download", fileName);
link.style.display = "none";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};
Вот вызов службы angularjs:
this.createImportFile = function (data) {
let request = $http({
method: "POST",
url: baseUrl "/CreateTestImport",
data: data
});
return request;
};
Вот действие MVC:
[HttpPost]
[Route("CreateTestImport")]
public JsonResult CreateTestImport(int id)
{
SaveEntityDTO<byte[]> response = new SaveEntityDTO<byte[]>();
try
{
response.Entity = CreateTestImportFile(id);
response.IsSuccess = true;
return Json(response, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
response.IsSuccess = false;
response.AddException(ex);
return Json(response);
}
}
ответ.Сущность — это байт[].
Если кто-либо из вас, javascript / AngularJS / .NET гуру, знает, как это сделать, я был бы очень признателен за помощь.
Комментарии:
1. Похоже, вы ищете библиотеку JS для отображения версии файла Excel, доступной только для чтения, и для того, чтобы у нее была кнопка загрузки, которая позволяет пользователю получить файл из данных, которые клиент уже загрузил. SheetJS должен сделать свое дело. Вероятно, вам вообще не нужно это для взаимодействия с AngularJS, поскольку вам это нужно только для рендеринга и загрузки, но на случай, если вы хотите пойти по этому пути, вот демонстрация с AngularJS .