Wie übergebe ich einen Stream von der Web-API an den Azure Blob-Speicher ohne temporäre Dateien?

8

Ich arbeite an einer Anwendung, bei der Datei-Uploads oft vorkommen und ziemlich groß sein können.

Diese Dateien werden in die Web-API hochgeladen, die dann den Stream von der Anfrage erhält und an meinen Speicherdienst weiterleitet, der sie dann in Azure Blob Storage hochlädt.

Ich muss sicherstellen, dass:

  • Keine Temp. Dateien werden in die Web-API-Instanz
  • geschrieben
  • Der Anforderungsstream wird nicht vollständig in den Speicher gelesen, bevor er an den Speicherdienst übergeben wird (um Out-of-Memory-Ausnahmen zu verhindern).

Ich habe diesen Artikel , das beschreibt, wie die Pufferung der Eingabedatenströme deaktiviert wird. Da jedoch viele Dateiuploads von vielen verschiedenen Benutzern gleichzeitig ausgeführt werden, ist es wichtig, dass sie tatsächlich das tut, was auf dem Papier steht.

Das habe ich gerade in meinem Controller:

%Vor%

Ich weiß nicht, wie ich das zuverlässig testen kann.

BEARBEITEN : Ich habe vergessen zu erwähnen, dass das Hochladen direkt auf Blob Storage (um meine API zu umgehen) nicht funktioniert, da ich eine Größenprüfung mache (zB kann dieser Benutzer 500mb hochladen? Hat diesen Benutzer seine Quote verwendet?).

    
Jeff 04.05.2015, 13:30
quelle

2 Antworten

7

Gelöst es, mit Hilfe von diesem Gist .

Hier ist, wie ich es benutze, zusammen mit einem cleveren "Hack", um die tatsächliche Dateigröße zu erhalten, ohne die Datei zuerst in den Speicher zu kopieren. Oh, und es ist doppelt so schnell (offensichtlich).

%Vor%

Voilá, Sie haben die Größe Ihrer hochgeladenen Datei, ohne die Datei in den Speicher Ihrer Webinstanz kopieren zu müssen.

Um die Dateilänge zu erhalten, bevor die Datei hochgeladen wird, ist das nicht so einfach, und ich musste auf einige ziemlich unpassende Methoden zurückgreifen, um nur eine Annäherung zu erhalten.

>

In BlobStorageMultipartStreamProvider :

%Vor%

Dies gibt mir eine ziemlich enge Dateigröße, die um ein paar hundert Bytes abweicht (hängt vom HTTP-Header ab, den ich vermute). Das ist gut genug für mich, da meine Quotenerzwingung akzeptieren kann, dass ein paar Bytes abgeschabt werden.

Nur zur Andeutung, hier ist der Speicherbedarf, der von der wahnsinnig genauen und fortgeschrittenen Registerkarte Leistung im Task-Manager berichtet wird.

Bevor Sie MemoryStream verwenden, lesen Sie es vor dem Hochladen in den Speicher

Nach - Schreiben direkt in Blob Storage

    
Jeff 05.05.2015, 18:45
quelle
5

Ich denke, ein besserer Ansatz besteht darin, dass Sie direkt von Ihrem Client zu Azure Blob Storage wechseln. Durch die Nutzung der CORS-Unterstützung in Azure Storage wird die Belastung Ihres Web-API-Servers reduziert, was zu einer besseren Skalierbarkeit Ihrer Anwendung führt.

Grundsätzlich erstellen Sie eine SAS-URL (Shared Access Signature), die Ihr Client verwenden kann, um die Datei direkt in den Azure-Speicher hochzuladen. Aus Sicherheitsgründen wird empfohlen, den Zeitraum zu begrenzen, für den der SAS gültig ist. Best-Practices-Anleitungen zum Generieren der SAS-URL finden Sie hier .

Für Ihr spezifisches Szenario sehen Sie sich dies an blog vom Azure Storage-Team, wo sie die Verwendung von CORS und SAS für dieses genaue Szenario besprechen. Es gibt auch eine Beispielanwendung, die Ihnen also alles geben soll, was Sie brauchen.

    
Rick Rainey 04.05.2015 14:23
quelle