Nabend,
Ausgangslage:
Asp.Net Core WEB API .NET 5
Blazor Server-Side .NET 5
Ich habe eine Controller Methode die den Upload verwaltet, was ich durch diese Seite realisiert habe.
Der Upload soll gestreamt werden, weil Dateien von 0-20 GB übertragen werden.
Mein Code sieht so aus:
[HttpPost]
[DisableRequestSizeLimit]
public async Task<IActionResult> UploadFileAsync()
{
if (!MultipartRequestHelper.IsMultipartContentType(this.Request.ContentType))
{
this.ModelState.AddModelError("File", "The request couldn't be processed (Error 1).");
return this.BadRequest(this.ModelState);
}
string boundary = MultipartRequestHelper.GetBoundary(
MediaTypeHeaderValue.Parse(this.Request.ContentType), _defaultFormOptions.MultipartBoundaryLengthLimit);
MultipartReader reader = new(boundary, this.HttpContext.Request.Body);
MultipartSection section = await reader.ReadNextSectionAsync();
while (section != null)
{
bool hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(
section.ContentDisposition, out ContentDispositionHeaderValue contentDisposition);
if (hasContentDispositionHeader)
{
if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
{
try
{
await this._fileBLL.UploadFileAsync(section, contentDisposition);
}
catch (Exception ex)
{
this.ModelState.AddModelError("Processing", ex.ToString());
}
}
else
{
this.ModelState.AddModelError("File", "The request couldn't be processed (Error 2).");
}
}
section = await reader.ReadNextSectionAsync();
}
return this.Ok(this.ModelState);
}
Die UploadFileAsync BLL Methode ist diese hier
public async Task UploadFileAsync(MultipartSection section, ContentDispositionHeaderValue contentDisposition)
{
string trustedFileName = WebUtility.HtmlEncode(contentDisposition.FileName.Value);
IMongoDatabase mongoDatabase = this._mongoClient.GetDatabase(this._mongo_DatabaseName);
GridFSBucket bucket = new(mongoDatabase, new()
{
BucketName = this._mongo_CollectionName,
ChunkSizeBytes = this._mongo_ChunkSizeBytesLength
});
Guid videoId = Guid.NewGuid();
using GridFSUploadStream uploadStream = await bucket.OpenUploadStreamAsync(trustedFileName, new()
{
Metadata = new()
{
{ "Id", videoId.ToStringValue() }
}
});
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = await section.Body.ReadAsync(buffer.AsMemory(0, buffer.Length))) != 0)
{
await uploadStream.WriteAsync(buffer.AsMemory(0, bytesRead));
}
await uploadStream.CloseAsync();
await section.Body.DisposeAsync();
}
Mit Postman (Foto im Anhang) funktioniert der Upload einwandfrei und die Datei wird in die MongoDB geschrieben.
Das ganze will ich nun auch mit der Blazor Server-Side App realisieren.
Dafür habe ich den Code
public async Task UploadFileAsync(IBrowserFile browserFile)
{
HttpRequestMessage requestMessage = new(HttpMethod.Post, "api/v1/File");
MultipartFormDataContent multipartFormDataContent = new();
multipartFormDataContent.Add(new StreamContent(browserFile.OpenReadStream(long.MaxValue)),
browserFile.Name, browserFile.Name);
//requestMessage.Content = multipartFormDataContent;
//HttpResponseMessage response = await this._client.SendAsync(requestMessage);
HttpResponseMessage response = await this._client.PostAsync("api/v1/File", multipartFormDataContent);
if (response.IsSuccessStatusCode)
{
string responseString = await response.Content.ReadAsStringAsync();
}
}
IBrowserFile browserFile
kommt von der UI:
<input type="file" multiple />
Das ganze funktioniert nur bedingt.
Der Code-Block der nicht ausgeführt wird auf diesem Weg ist der:
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = await section.Body.ReadAsync(buffer.AsMemory(0, buffer.Length))) != 0)
{
await uploadStream.WriteAsync(buffer.AsMemory(0, bytesRead));
}
await uploadStream.CloseAsync();
await section.Body.DisposeAsync();
Er überspringt die while Schleife, weil der Body anscheinend leer ist.
Aber was mache ich beim Post Request falsch? Durch googlen bin ich bis jetzt auch nicht schlauer geworden.
Ob ich HttpClient.PostAsync oder HttpClient.SendAsync aufrufe, ändert nichts.
Habt Ihr Anregungen?
Grüße und einen schönen Abend 🙂
Mach Dir selbst nen SDK Deiner API durch Refit. So musst Du den ganzen File HTTP Quark nicht selbst schreiben.
reactiveui/refit
Hast dann am Ende nur
public interface MyAPI
{
[Multipart]
[Post("/myfile/upload")]
Task UploadImages([AliasAs("files")] IEnumerable<StreamPart> streams);
}
Genaue Doku sieh reactiveui/refit
Auf der Server-Seite brauchst Du dann nur ein Multipart Upload Action.
Brauchst keine 20 Zeilen dank Refit dafür.
Aber Feedback zum Code:
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Ich werde es mal einbauen und dann gucken ob es funktioniert.
Morgen Abend gibts dann Rückmeldung 🙂
Aber Feedback zum Code:
- Du hast viel obsolete Code vermutlich aus verschiedenen Quellen zusammenkopiert, selbst die Error Code haste übernommen (???)
Stimmt. Derzeit aber nur zum testen, bis es funktioniert, danach wird der Code deutlich verbessert.
- Man sollte IFormFile verwenden
Warum? Werden die Files dann nicht im Arbeitsspeicher zwischen gespeichert? Warum nutzt die Microsoft Doku das ebenfalls nicht um große Dateien hochzuladen?
- Datenbank-Operationen darf man auch ruhig auslagern, muss man nich mit Logik mischen 😉
Kommt 🙂
Aber danke für dein Feedback 🙂
Warum? Werden die Files dann nicht im Arbeitsspeicher zwischen gespeichert? Warum nutzt die Microsoft Doku das ebenfalls nicht um große Dateien hochzuladen? Hochladen von Dateien in ASP.NET Core - IFormFile
Welche Ressourcen (Datenträger, Arbeitsspeicher) für das Hochladen von Dateien verwendet werden, ist von der Anzahl und Größe gleichzeitig hochgeladener Dateien abhängig. Wenn eine App versucht, zu viele Uploads zu puffern, stürzt die Website ab, sobald der Arbeitsspeicher oder Speicherplatz auf dem Datenträger ausgelastet ist.
Aber okay, wenn ich Dich richtig verstehe, dann willst Du bewusst Streaming verwenden.
Das hab ich zuerst übersehen.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Ich nutze Streaming, wegen der Aussage von mir:
Der Upload soll gestreamt werden, weil Dateien von 0-20 GB übertragen werden.
Da werde ich IFormFile nicht verwenden 🙂
Da melde ich mich wieder.
[Blazor App]
Refit installiert, Interface erstellt, Services hinzugefügt => Exception.
[Console App]
Copy Paste => Funktioniert. (Lokale Datei, 8.7GB)
Hier ist einmal das Interface
public interface IFileApi
{
[Multipart]
[Post("/api/v1/File")]
Task<HttpResponseMessage> UploadFileAsync(StreamPart streamPart);
}
So registriere ich die Services in der Startup Klasse
services.AddRefitClient<IFileApi>()
.ConfigureHttpClient(c => c.BaseAddress = new Uri(apiBaseAddress)); //apiBaseAddress = https://localhost:5003/
In der Razor Datei injecte ich das Interface, iteriere durch die IBrowserFiles und rufe die Methode auf.
foreach (IBrowserFile file in this._selectedFiles)
{
try
{
StreamPart streamPart = new(file.OpenReadStream(long.MaxValue), file.Name);
var res1 = await this.FileApi.UploadFileAsync(streamPart);
}
catch (Exception ex)
{ }
}
Lande im Catch. Siehe UI Info im Anhang. Und aus dem Stacktrace, kann ich nicht erkennen, woran es liegt.
Ich denke es liegt an dem IBrowserFile Interface bzw. der OpenReadStream Methode die aufgerufen wird.
Die Datei die hochgeladen wurde, war 8,7GB groß. Eine TextDatei von 0 Bytes konnte ich ohne Probleme hochladen bzw. ist der Call zur API durch gegangen.
Aber woran kann es liegen?
Hier noch einmal der Stacktrace von der Exception:
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Threading.Tasks.ValueTask`1.get_Result()
at Microsoft.AspNetCore.Components.Forms.RemoteBrowserFileStream.<FillBuffer>d__9.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.IO.Pipelines.PipeCompletion.ThrowLatchedException()
at System.IO.Pipelines.Pipe.GetReadResult(ReadResult& result)
at System.IO.Pipelines.Pipe.ReadAsync(CancellationToken token)
at System.IO.Pipelines.Pipe.DefaultPipeReader.ReadAsync(CancellationToken cancellationToken)
at Microsoft.AspNetCore.Components.Forms.RemoteBrowserFileStream.<CopyFileDataIntoBuffer>d__10.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ValueTaskAwaiter`1.GetResult()
at Microsoft.AspNetCore.Components.Forms.BrowserFileStream.<ReadAsync>d__22.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.IO.Stream.<CopyToAsyncInternal>d__29.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Net.Http.HttpContent.<<CopyToAsync>g__WaitAsync|56_0>d.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Net.Http.MultipartContent.<SerializeToStreamAsyncCore>d__23.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Net.Http.HttpContent.<<CopyToAsync>g__WaitAsync|56_0>d.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Net.Http.HttpConnection.<SendRequestContentAsync>d__62.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Net.Http.HttpConnection.<SendAsyncCore>d__56.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Net.Http.HttpConnection.<SendAsyncCore>d__56.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at System.Net.Http.HttpConnectionPool.<SendWithRetryAsync>d__72.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Threading.Tasks.ValueTask`1.get_Result()
at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable`1.ConfiguredValueTaskAwaiter.GetResult()
at System.Net.Http.RedirectHandler.<SendAsync>d__4.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at System.Net.Http.DiagnosticsHandler.<SendAsyncCore>d__5.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at Microsoft.Extensions.Http.Logging.LoggingHttpMessageHandler.<SendAsync>d__5.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.<SendAsync>d__5.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at System.Net.Http.HttpClient.<SendAsyncCore>d__85.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at Refit.RequestBuilderImplementation.<>c__DisplayClass14_0`2.<<BuildCancellableTaskFuncForMethod>b__0>d.MoveNext() in /_/Refit/RequestBuilderImplementation.cs:line 296
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at RD.Intelligence.Web.Components.AddFilesComponent.<UploadFilesAsync>d__14.MoveNext() in D:\Repositories\RD.Intelligence\RD.Intelligence.Web\Components\AddFilesComponent.razor:line 87
Statt 8492734 Zeilen Exception Text und nem Bild wäre die Server-Antwort, die bemängelt wird, interessanter 😉Refit Handling Exceptions
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Da stimme ich dir zu.
Nur komme ich gar nicht bis zur API Methode.
Die wird quasi nicht ausgeführt und hab daher auch keine Response vom Server.
Dann find mal raus, welche Zeile wirklich knallt. Kann auch die Blazor Komponente sein.
Sonst raten wir hier nur.
StreamPart streamPart = new(file.OpenReadStream(long.MaxValue), file.Name);
Bin mir nicht sicher, ob das vielleicht ein Dont ist.ASP.NET Core Blazor-Dateiuploads
Hab leider kein Zugriff mehr auf den Kunden-Code den ich so mit Blazor und Refit gemacht hab.
Waren Dateien bis 5 GB - und das ging am Ende problemlos (ebenfalls Streaming).
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Wie ich es herausfinden soll, stellt mich gerade auf die Probe.
Mit deinem Link:
Der folgende Ansatz wird für Microsoft Azure Blob Storage empfohlen, da die Stream-Klasse der Datei direkt für UploadBlobAsync bereitgestellt wird:
Das ganze will ich ja auch und mache ich eig. ja auch. Nur das es nicht Azure ist.
Edit:
Selbst wenn ich den StreamPart von Refit weg lasse, bekomme ich das gleiche Ergebnis.
Stream stream = file.OpenReadStream(long.MaxValue);
response = await this.FileApi.UploadFileAsync2(stream);
Vielleicht gibts bei Blazor Server Side hier eine Besonderheit, die ich auch noch nicht kenne.
Das allgemeine Kommunikationsmodell ist hier ja anders als bei Client Side Blazor.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Dann erstelle ich mal ein Github Issue.
Habe jetzt mal mehrere Dateien getestet.
3,56GB => Kommt an, kann aber nichts von gelesen werden (die while Schleife wird übersprungen)
über 2GB gleiches Verhalten.
Unter 2 GB => Kommt ebenfalls an, aber der Content von der Datei kann auch gelesen werden.
Ich könnte mir vorstellen, da Blazor Server Side über SignalR kommuniziert, Du hier in ein Limit laufen könntest.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Dann dürfte es laut einem Github Issue eine Fehlermeldung seitens SignalR werfen.
Aber auch mit
services.Configure<HubOptions>(options =>
{
options.MaximumReceiveMessageSize = null;
});
Was mit Workaround in dem Issue gemeint ist, ändert es nichts.
Issue ist erstellt.
Sollte was dabei raus kommen, werde ich die Lösung hier bekannt geben.
Schönen Abend noch 🙂
Nabend,
zur Info, dass Github Issue wurde ins Backlog verschoben.
Falls da was neues kommen sollte, sag ich hier Bescheid.
Dann dachte ich, löse ich das nicht über Streaming der ganzen Datei, sondern transferiere die Datei in Chunks.
buffer = new byte[8120];
using Stream stream = file.OpenReadStream(long.MaxValue); //file = IBrowserFile vom <InputFile> Element
await stream.ReadAsync(buffer, 0, buffer.Length);
Der Code-Schnipsel sorgt ebenfalls für die gleiche Exception. (3. Zeile)
Also gibt es derzeit mit der Blazor Componente keine Möglichkeit, Dateien über 2? GB zu handlen.
Für meinen Test war es eine Datei mit 9,7 GB.
Werde das ganze über Plain JS lösen, weil da funktioniert das..
Grüße
Edit:
Habe gerade nochmal gegooglet und spontan vom 15.11.2020 das Github Issue gefunden. Gleicher Fehler, ist aber auch nicht gefixt.
Vor allem dem zweiten Issue entnehme ich, dass meine Vermutung, dass Du in ein Websocket-Limit läufst, richtig sein wird.
Die Datei wird nämlich nicht vom Client zur API geschickt, sondern erst vom Client zur Server App und dann erst zur API.
Dass JS funktioniert, weil Du damit den Socket umgehst: klar.
Blazor Server ist eine gute Idee als Übergangslösung - und so ist sie auch gedacht und sollte verwendet werden. Sie deckt aber bei weitem nicht alle Client-Szenarien ab.
Sieht man im Endeffekt auch am Markt: alle, die können, setzen bereits auf den Client.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Sieht man im Endeffekt auch am Markt: alle, die können, setzen bereits auf den Client.
Meinst du damit Blazor WebAssembly?
Korrekt. Blazor WebAssembly ist die Bezeichnung für Blazor Client Side.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Ich habe den Upload auch gerade nochmal mit Blazor WebAssembly versucht.
Es fliegt genau die gleiche Exception.
Schade, dass uns andere statt Du den Hinweis gegeben haben, dass Du das Thema auch noch wo anders veröffentlich hast 🙂unable-to-upload-files-that-are-larger-than-2-gb-to-web-api-blazor-server-side
Nicht nett -> [Hinweis] Wie poste ich richtig? 2.2 Keine Crossposts
Ebenso verstößt Du damit den Regeln von Stackoverflow..
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Ich hab mir mal angeschaut, warum das in JavaScript funktioniert aber in der WebAssembly nicht, sofern man das über eigenen Code lösen will.
Denn ein stupides HTML-Formular funktioniert problemlos.
Der Fehler taucht nicht bei OpenReadStream
auf, sondern bei der Verarbeitung des Buffers im HTTP Client.
Dadurch hab ich mir durchgelesen, wie das aktuell funktioniert; und es ist wohl so, dass es derzeit keine Streaming Möglichkeit von WebAssembly gibt (egal ob Blazor oder was anderes).
https://github.com/dotnet/aspnetcore/issues/31873
Javier Nelson schreibt, dass dies mit Chrome 87 in die Testphase kam - aber ich sehe nirgends, dass es mittlerweile im Release ist.
Auch die entsprechenden Chrome Flags enable-experimental-webassembly-features
geben keine Hinweise dazu.
Der aktuelle MemoryLeak in diesem Fall hat bei mir übrigens zum Bluescreen geführt..
D.h. sofern die jeweiligen Browser entsprechendes nicht unterstützen, dann wirds auch nichts mit WebAssembly Streaming in Blazor.
Dass JavaScript funkioniert liegt eben an a) Bypass vom Socket (weil hier auch gebuffert wird) und b) Bypass dieser Limits.
Die minimalistischste Variante ohne Refit zur Nachvollziehbarkeit ist:
private async Task UploadFile(InputFileChangeEventArgs e)
{
HttpClient httpClient = new HttpClient();
var stream = e.File.OpenReadStream(long.MaxValue);
var content = new MultipartFormDataContent();
content.Add(new StreamContent(stream), e.File.Name);
HttpResponseMessage response =
await httpClient.PostAsync("https://localhost:5001/filestreamtest", content);
response.Dispose();
}
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Schade, dass uns andere statt Du den Hinweis gegeben haben, dass Du das Thema auch noch wo anders veröffentlich hast 🙂
>Nicht nett ->
> 2.2 Keine Crossposts
Ebenso verstößt Du damit den Regeln von Stackoverflow..
Hatte ich im nachhinein erstellt, weil die englische .NET Community nicht in diesem Forum vertreten ist.
Ist aber gelöscht.
Dadurch hab ich mir durchgelesen, wie das aktuell funktioniert; und es ist wohl so, dass es derzeit keine Streaming Möglichkeit von WebAssembly gibt (egal ob Blazor oder was anderes).
Ja läuft^^
Wie erwähnt, habe ich das dann mit Javascript umgesetzt.