Im Folgenden finden Sie meine Lösung zum Herunterladen mehrerer Dateien, abhängig von einer Liste, die aus einigen IDs besteht und nach dem Durchsuchen der Datenbank werden die Dateien bestimmt und zum Download bereit sein - falls diese existieren. Ich rufe die C# MVC-Aktion für jede Datei mit Hilfe von Ajax auf.
Und ja, wie andere gesagt haben, es ist möglich, es mit jQuery Ajax zu tun. Ich habe es mit Ajax-Erfolg gemacht und sende immer eine Antwort 200.
Also, das ist der Schlüssel:
success: function (data, textStatus, xhr) {
Und das ist mein Code:
var i = 0;
var max = 0;
function DownloadMultipleFiles() {
if ($(".dataTables_scrollBody>tr.selected").length > 0) {
var list = [];
showPreloader();
$(".dataTables_scrollBody>tr.selected").each(function (e) {
var element = $(this);
var orderid = element.data("orderid");
var iscustom = element.data("iscustom");
var orderlineid = element.data("orderlineid");
var folderPath = "";
var fileName = "";
list.push({ orderId: orderid, isCustomOrderLine: iscustom, orderLineId: orderlineid, folderPath: folderPath, fileName: fileName });
});
i = 0;
max = list.length;
DownloadFile(list);
}
}
Dann rufe ich auf:
function DownloadFile(list) {
$.ajax({
url: '@Url.Action("OpenFile","OrderLines")',
type: "post",
data: list[i],
xhrFields: {
responseType: 'blob'
},
beforeSend: function (xhr) {
xhr.setRequestHeader("RequestVerificationToken",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
success: function (data, textStatus, xhr) {
// Überprüfen auf einen Dateinamen
var filename = "";
var disposition = xhr.getResponseHeader('Content-Disposition');
if (disposition && disposition.indexOf('attachment') !== -1) {
var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
var matches = filenameRegex.exec(disposition);
if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
var a = document.createElement('a');
var url = window.URL.createObjectURL(data);
a.href = url;
a.download = filename;
document.body.append(a);
a.click();
a.remove();
window.URL.revokeObjectURL(url);
}
else {
getErrorToastMessage("Produktionsdatei für Auftragszeile " + list[i].orderLineId + " existiert nicht");
}
i = i + 1;
if (i < max) {
DownloadFile(list);
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
},
complete: function () {
if(i===max)
hidePreloader();
}
});
}
C# MVC:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult OpenFile(OrderLineSimpleModel model)
{
byte[] file = null;
try
{
if (model != null)
{
// Code zum Abrufen der Datei von der API - Teil fehlt hier, da nicht für dieses Beispiel wichtig
file = apiHandler.Get(downloadApiUrl, token);
var contentDispositionHeader = new System.Net.Mime.ContentDisposition
{
Inline = true,
FileName = fileName
};
// Response.Headers.Add("Content-Disposition", contentDispositionHeader.ToString() + "; attachment");
Response.Headers.Add("Content-Type", "application/pdf");
Response.Headers.Add("Content-Disposition", "attachment; filename=" + fileName);
Response.Headers.Add("Content-Transfer-Encoding", "binary");
Response.Headers.Add("Content-Length", file.Length.ToString());
}
}
catch (Exception ex)
{
this.logger.LogError(ex, "Fehler beim Abrufen von PDF", null);
return Ok();
}
return File(file, System.Net.Mime.MediaTypeNames.Application.Pdf);
}
Solange Sie eine Antwort 200 zurückgeben, kann der Erfolg in Ajax damit arbeiten. Sie können überprüfen, ob die Datei tatsächlich existiert oder nicht, da die Zeile unten in diesem Fall falsch wäre, und Sie den Benutzer darüber informieren können:
if (disposition && disposition.indexOf('attachment') !== -1) {