Rückkehr CSV aus .NET-Core-controller
Ich habe Probleme mit einem .NET-Core-API-Endpunkt-Controller beheben, um eine CSV-download. Ich bin mit dem folgenden code die ich zog aus .NET 4.5-controller:
[HttpGet]
[Route("{id:int}")]
public async Task<HttpResponseMessage> Get(int id)
{
string csv = await reportManager.GetReport(CustomerId, id);
var response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new StringContent(csv);
response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/csv");
response.Content.Headers.ContentDisposition =
new ContentDispositionHeaderValue("attachment") { FileName = "report.csv" };
return response;
}
Wenn ich auf diesen Endpunkt aus meinem Winkel 4 app, bekomme ich die folgende Antwort in den browser geschrieben:
{
"version": {
"major": 1,
"minor": 1,
"build": -1,
"revision": -1,
"majorRevision": -1,
"minorRevision": -1
},
"content": {
"headers": [
{
"key": "Content-Type",
"value": [
"text/csv"
]
},
{
"key": "Content-Disposition",
"value": [
"attachment; filename=11.csv"
]
}
]
},
"statusCode": 200,
"reasonPhrase": "OK",
"headers": [ ],
"requestMessage": null,
"isSuccessStatusCode": true
}
Meine Erwartung ist, dass, wenn ich auf den Endpunkt, wird der Benutzer aufgefordert, um den download der CSV.
Fand ich diese post auf, wie Sie "export" wird eine CSV in .NET Core. Das problem ist, dass ich beim abrufen der CSV-im-Speicher von ihm die Quelle (AWS S3 bucket) in der Erwägung, dass dieser code scheint zu funktionieren nur, wenn Sie haben eine IEnumerable<object>
.
Frage ich mich, ob mein problem liegt entweder im request oder in der response-Header, wo es etwas zu verhindern das der browser abrufen einer CSV von meiner API. Hier ist, was ich sehe, in der browser-Konsole:
Ein weiterer Hinweis, in solchen Fällen oft besser outputformatters, die Lesen acceptencoding zum Beispiel, oder durch andere Regeln. Wenn Sie arbeiten an einem großen Projekt, müssen Sie wahrscheinlich zu verwenden, csv-export für die Anzahl der Methoden und, wenn Sie erstellen von generischen formatiert vermeiden Sie unnötige arbeiten in der Zukunft. Es kann ein layer in der middleware
Haben Sie etwas hinzuzufügen? Sie verlinken einen Artikel, auf den verwiesen wird, in einem link von meinem post ist nicht sehr hilfreich.
Es sieht aus, als ob Sie sind, Holen Sie den download über AJAX. Wenn Sie das tun, müssen Sie die
responseType
als arraybuffer
und erstellen Sie ein blob aus der response-Daten an den Erfolg der Methode. Sie müssen auch behandeln die aktuellen download manuell durch erstellen einer Verknüpfung mit Daten und "Klick" es. Nichts davon geschieht automatisch für Sie.In den Netzwerk-Verkehr screenshot, ich war zu schlagen, die URL direkt in den browser.
InformationsquelleAutor im1dermike | 2017-10-27
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den richtigen Weg zu zwingen, eine Datei heruntergeladen werden, statt angezeigt wird inline mit dem
Content-Disposition
- header der Antwort., Während die unterhalb Lösung funktioniert (siehe Dokumentation) es ist schon darauf hingewiesen, dass dies unerwünschte Nebenwirkungen.Alte Antwort
Einstellung der
Content-Type
Antwort-headerapplication/octet-stream
zwingen wird, die meisten gängigen Browsern der Benutzer aufgefordert, die Datei zu speichern anstatt es in das Fenster.Versuchen, etwas wie das zu tun:
Siehe meine Antwort zu dieser ähnlichen Frage für mehr info
Mit
application/octet-stream
ist für ausführbare Dateien wieexe
oderbin
... Das ist schlechte Praxis, wie es bricht, web-standards und wird wahrscheinlich Einfluss auf Ihre web-Anwendung in negativer Weise, wenn es darum geht, web-crawler und langfristige Wartbarkeit, etc. Es gibt einen Grund, warum es web-standards. Sie sollten sich darüber im klaren sein, die Inhalte, die Sie dienen, um Ihre Kunden."Dies ist der Standardwert für eine binäre Datei.", für die ich sagen würde, dass jede Datei zählt. Dein argument gegen die Verwendung dieses content-type scheint ziemlich schwach, aber Sie sind nicht falsch, es ist eine schlechte Praxis. In jedem Fall habe ich aktualisiert meine Antwort mit der richtigen Antwort-header gesetzt werden, die den gleichen Effekt erzielt.
Es gibt wenig Raum für alternative Interpretationen. Ein
text/csv
ist ein text - Datei, nicht ein Binär - Datei... Entsprechend der web-standards unbekannt-text-Datei isttext/plain
-- und -- unbekannt-Binärdatei istapplication/octet-stream
. Wenn Sie wollen einfach nur eine download-Aufforderung angezeigt, sich zu zeigen, dann wieder einFile
- Typ mit einembyte[]
oderstream
. Don ' T hack es mitContent-Types
-- gibt es keine Notwendigkeit.Die Behandlung einer text-Datei als binary ist nicht anders als die Behandlung einer
string
alsobject
. Wartbarkeit mitapplication/octet-stream
vstext/plain
ist wahrscheinlich irrelevant in OP ' s Fall, wie web-crawler, wenn er gezielt versucht, den Benutzer aufzufordern, die Datei herunterzuladen. Dies ist nicht gegen den standard, indem Sie versuchen, passieren Sie eine text-Datei um, als video, es ist einfach zu sagen: "die Behandeln mich wie ein binary blob", das ist nicht zu brechen, standard, er macht Gebrauch davon.InformationsquelleAutor Neil
Lösung: Verwenden Sie
FileResult
Diese sollte verwendet werden, wenn Sie möchten, dass der client, um die "Datei Speichern" Dialogfeld.
Gibt es eine Vielzahl zu wählen, von hier aus, wie
FileContentResult
,FileStreamResult
,VirtualFileResult
,PhysicalFileResult
; aber Sie alle stammen ausFileResult
- so gehen wir mit, dass für dieses Beispiel.Extra: Content-Disposition
Den
FileResult
wird automatisch die richtigeContent-Disposition
headerattachment
.Wenn Sie möchten, öffnen Sie die Datei im browser ("inline"), statt der Aufforderung "Datei Speichern" - dialog ("attachment"). Dann können Sie tun, dass durch eine änderung der
Content-Disposition
- header-Wert.Nehmen wir zum Beispiel zeigen wollen, die
PDF
- Datei im browser.Kredit zu diesem SO Beantworten
Benutzerdefinierte Formatierer
Benutzerdefinierte Formatierer ist eine gute Wahl, weil es ermöglicht den client zu Fragen, für den Typ, den Sie wollen, dass die Daten, wie die mehr populären JSON-oder eine der weniger populären XML.
Dies funktioniert in Erster Linie durch den Dienst, den Inhalt, wie angegeben, in der
Accept
- header, die der client übergibt dem server, wie CSV, XLS, XML, JSON, etc.Da Sie mit den format-Typ der
"text/csv"
-- derzeit gibt es keine input/output formatter für diese, wenn Sie die pre-gebündelt Optionen wieAddMvc()
... So haben Sie es hinzufügen, in etwa so:Sehr Einfache Benutzerdefinierte Formatter -
Hier ist eine sehr einfache version einer benutzerdefinierten Formatierer, das ist eine abgespeckte version, die wurde mit der Microsoft Docs Beispiel.
Zwingen, ein Bestimmtes Format
Weitere Informationen würde ich empfehlen, dass Sie Lesen:
es war ein Tippfehler. Es ist schon korrigiert.
InformationsquelleAutor Svek