Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Portal
  • |
  • Mitglieder
Beiträge von Duesmannr
Thema: Datei Upload über eine Web-API
Am im Forum: Web-Technologien

Zitat von Abt
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..

Hatte ich im nachhinein erstellt, weil die englische .NET Community nicht in diesem Forum vertreten ist.
Ist aber gelöscht.
Zitat von Abt
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.

Thema: Datei Upload über eine Web-API
Am im Forum: Web-Technologien

Ich habe den Upload auch gerade nochmal mit Blazor WebAssembly versucht.

Es fliegt genau die gleiche Exception.

Thema: Datei Upload über eine Web-API
Am im Forum: Web-Technologien

Zitat von Abt
Sieht man im Endeffekt auch am Markt: alle, die können, setzen bereits auf den Client.

Meinst du damit Blazor WebAssembly?

Thema: Datei Upload über eine Web-API
Am im Forum: Web-Technologien

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.

Thema: Gibt es eine Lösung, um eine Website in Chrome zu blockieren?
Am im Forum: Smalltalk

- Kannst eine Seite im Router blockieren.
- Gibt bestimmt eine Extensions dafür

Thema: Datei Upload über eine Web-API
Am im Forum: Web-Technologien

Issue ist erstellt.
Sollte was dabei raus kommen, werde ich die Lösung hier bekannt geben.

Schönen Abend noch

Thema: Datei Upload über eine Web-API
Am im Forum: Web-Technologien

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.

Thema: Datei Upload über eine Web-API
Am im Forum: Web-Technologien

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.

Thema: Datei Upload über eine Web-API
Am im Forum: Web-Technologien

Wie ich es herausfinden soll, stellt mich gerade auf die Probe.

Mit deinem Link:

Zitat
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);

Thema: Datei Upload über eine Web-API
Am im Forum: Web-Technologien

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.

Thema: Datei Upload über eine Web-API
Am im Forum: Web-Technologien

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

Thema: Datei Upload über eine Web-API
Am im Forum: Web-Technologien

Ich nutze Streaming, wegen der Aussage von mir:

Zitat von Duesmannr
Der Upload soll gestreamt werden, weil Dateien von 0-20 GB übertragen werden.

Da werde ich IFormFile nicht verwenden

Thema: Datei Upload über eine Web-API
Am im Forum: Web-Technologien

Zitat von Abt
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.
Zitat von Abt
- 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?
Zitat von Abt
- Datenbank-Operationen darf man auch ruhig auslagern, muss man nich mit Logik mischen ;-)

Kommt

Aber danke für dein Feedback

Thema: Datei Upload über eine Web-API
Am im Forum: Web-Technologien

Ich werde es mal einbauen und dann gucken ob es funktioniert.

Morgen Abend gibts dann Rückmeldung

Thema: Datei Upload über eine Web-API
Am im Forum: Web-Technologien

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

Thema: Blazor Server-Side Cookie Authentication
Am im Forum: Web-Technologien

Zitat von Abt
bei Blazor meist über ProtectedSessionStorage; nicht über Cookies.
Der Storage sagt mir auf Anhieb nichts, gucke ich mir mal an.
Zitat von Abt
Soweit ich weiß wird aber nichts in AuthenticationStateProvider per default gespeichert.
Das ist korrekt.
Zitat von Abt
Edit: erster Google Treffer dazu: Session Authentication with ASP.NET Core 3.1 Blazor Server Side

Habe ich auch schon des Öfteren überflogen. Dann gucke ich mir das nochmal genauer an.

Vorerst danke

Thema: Blazor Server-Side Cookie Authentication
Am im Forum: Web-Technologien

Moin Abt,

ich meine die Standard implementierte Authentifizierung von Microsoft, wenn man bei der Erstellung den Authentication Type auf Individual Accounts setzt.

Der dadurch erzeugte ApplicationDbContext der vom IdentityDbContext erbt, sowie die Standard Login/Logout etc. Seiten von Identity, brauche ich alles nicht.

Bei Blazor Server-Side gibt es keinen direkten HttpContext, weil die Kommunikation über SignalR läuft.
Dafür ist ja dann der AuthenticationStateProvider da.

Mit dem Code kann ich mich auch anmelden (Razor Page, User Verifizierung seitens DB ausgeschlossen)


List<Claim> claims = new()
        {
            new(ClaimTypes.Email, this.Model.Username)
        };

        ClaimsIdentity claimsIdentity = new(claims, CookieAuthenticationDefaults.AuthenticationScheme);

        ClaimsPrincipal claimsPrincipal = new(claimsIdentity);

        AuthenticationState authenticationState = new AuthenticationState(claimsPrincipal);

        (AuthenticationStateProvider as ServerAuthenticationStateProvider).SetAuthenticationState(Task.FromResult(authenticationState));

Durch das setzen des AuthenticationState sehe ich beispielsweise diese h1

<AuthorizeView>
    <Authorized>
        <h1>You´re authorized.</h1>
    </Authorized>
</AuthorizeView>

auf der gleichen Seite.

Was mir aber jetzt fehlt, dass der State gespeichert wird, was ja über das Cookie laufen würde, wenn ich es richtig verstehe.
Und wie dieser dann wieder dazu führt, dass der User weiterhin angemeldet ist.

Thema: Blazor Server-Side Cookie Authentication
Am im Forum: Web-Technologien

Morgen,

Ausgangssituation: Blazor Server-Side .NET 5
Ziel: Einfache Authentication ohne Identity via Cookie.

Soweit ich das verstanden habe, wird man ein- und ausgeloggt über den


AuthenticationStateProvider

Dieser kann bei den Services mit


ServerAuthenticationStateProvider

registriert werden.

Dann kann man mit einem AuthenticationState


AuthenticationState authenticationState = new AuthenticationState(ClaimsPrincipal)

als Parameter den StateProvider aufrufen


(AuthenticationStateProvider as ServerAuthenticationStateProvider).SetAuthenticationState(authenticationState);

Was mir jetzt fehlt, dass die Informationen gespeichert und ausgelesen werden. Und da kommt Cookie ins Spiel.

Bei den Services habe ich das hinzugefügt


services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddCookie(options =>
                {
                    options.LoginPath = "/User/Login";
                    options.LogoutPath = "/User/Logout/";
                });

und bei der App, dass


app.UseAuthentication();
app.UseAuthorization();

Aber wie geht es jetzt weiter mit dem Cookie?
Was man noch machen kann, ist eine eigene Implementierung vom AuthenticationStateProvider, aber das hilft mir auch nicht weiter.

Alle Beispiele die ich finde nehmen irgendein HttpContext um sich anzumelden etc. (Bspw. hier: how-to-authenticate-a-user-with-blazor-server)
Aber ich habe noch keine Lösung ohne Identity gefunden bzw. auch keine mit Identity die ich auf meinen Fall adaptieren könnte.

Habt Ihr eine Idee?

Grüße
duesmannr

Thema: Code Sharing between Projects
Am im Forum: Web-Technologien

Moin,

ich bin gerade am überlegen, wie ich das folgende Problem löse.

Ich habe eine
- Web-Anwendung (Blazor, Server-Side, .NET5)
- Razor Class Library (.NET5) (RCL)

Ich habe in der RCL mehrere Komponenten, die auch den CSS Scope Identifier von Blazor nutzen.

Die hinterlegte css Datei wird von einer scss Datei generiert.
Die genannte scss Datei importiert eine "_mixins.scss" Datei, um mixins zu nutzen, die das Leben vereinfachen. (_mixins.scss Datei liegt auch in der RCL)

Funktioniert alles soweit.

Problem ist jetzt, dass ich die "_mixins.scss" Datei auch gerne in der Web-Anwendung in eine scss Datei importieren würde, nur weiß ich nicht wie.
Ein einfacher Import über einen relativen Pfad funktioniert nicht, weil Web Compiler, die Datei nicht findet.

Dann hatte ich gegooglet und bin auf "Shared Project" gestoßen.

Habe ich dann mal ein Projekt erstellt, die scss Datei hinzugefügt und in der Web-Anwendung hinzugefügt. Konnte die Datei ohne Probleme in einer anderen scss Datei importieren.
Nur kann ich die RCL nicht in das Shared Project migrieren, weil da die CSS Isolation fehlt.

Und ein drittes Projekt für nur ein paar scss Dateien finde ich, ist ein zu großer Overhead.

Andere Möglichkeit die ich noch gesehen hatte, die scss Datei zu linken in einen Ordner in der Web-Anwendung. Funktioniert aber ebenfalls auch nicht, weil der die Datei ebenfalls nicht findet.

Habt Ihr eine Idee?
Grüße

P.S.: Noch einmal hier die Struktur:


RazorClassLibrary
    - Components
        - Component.razor
        - Component.razor.css
        - Component1.razor
        - Component1.razor.css
    - wwwroot
        - scss
            - _mixins.scss
            - Component.scss (importiert die _mixins.scss)

BlazorServerSide
    - wwwroot
        - scss
            - anotherScssFile (soll die _mixins.scss auch importieren)

Thema: Expression<Func> Mapping - InvalidOperationException - Could not be translated
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Als Nachtrag, hab es über Automapper geschafft.
Aber nicht das ganze Objekt direkt, sondern die Properties einzelnt zu mappen.

Man braucht dafür das Nuget Package von Automapper 'AutoMapper.Extensions.ExpressionMapping'.
Und dann muss man noch beim hinzufügen des Automappers im Service die Methode aufrufen


automapper.AddExpressionMapping();

//So sieht das dann ganz aus
services.AddAutoMapper((serviceProvider, automapper) =>
            {
                automapper.AddExpressionMapping();
                automapper.AddProfile<AutoMapping>();
            }, typeof(ApplicationDbContext).Assembly);

Das hatte ich davor auch schon alles.

Was ich nun mache, das ich die einzelnen Properties vom Specification Objekt durch gehe und diese mappe:


protected virtual ISpecification<TEntity> MapSpecification(ISpecification<TDTOEntity> specification)
        {
            Expression<Func<TEntity, bool>> criteriaExpression = this.Mapper.Map<Expression<Func<TEntity, bool>>>(specification.Criteria);

            ISpecification<TEntity> result = new BaseSpecification<TEntity>(criteriaExpression);

            foreach (Expression<Func<TDTOEntity, object>> includeDTOExpression in specification.Includes)
            {
                Expression<Func<TEntity, object>> includeExpression = this.Mapper.Map<Expression<Func<TEntity, object>>>(includeDTOExpression);

                result.AddInclude(includeExpression);
            }

            specification.IncludeStrings.ForEach(x => result.AddInclude(x));

            result.AddPaging(specification.PagingSpecification);

            return result;
        }

Und das funktioniert auch. Nur unvorteilhaft, wenn Properties dazu kommen, muss man diese ebenfalls mit aufnehmen.

Thema: Expression<Func> Mapping - InvalidOperationException - Could not be translated
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Nabend Leute,

Verwendete Systeme/Bibs: EF Core 5, Automapper

Ich kann von der UI eine Specification erhalten, die verschiedene Properties enthält, um den Get Request zu steuern.


public interface ISpecification<TEntity>
    {
        #region Properties

        Expression<Func<TEntity, bool>> Criteria { get; }

        List<Expression<Func<TEntity, object>>> Includes { get; }

        List<string> IncludeStrings { get; }

        PagingSpecification PagingSpecification { get; }

        #endregion //Properties

        #region Methods

        void AddInclude(Expression<Func<TEntity, object>> includeExpression);

        void AddInclude(string includeString);

        void AddPaging(PagingSpecification pagingSpecification);

        #endregion //Methods
    }

Das TEntity ist bei mir ein DTO.
Und in der BLL will ich dann die Specification<DTO> zu Specification<Entity> mappen.

Das würde z.B. ankommen:


ISpecification<CategoryDTO> specification = new BaseSpecification<CategoryDTO>(x => x.Id == idToGet);
//idToGet = Guid variable.


Mit Automapper schaffe ich es nicht, es zu mappen. Der Wert ist immer null. (Criteria)
Deshalb manuell mappen.
Wie mappt man eine Expression? I dont know => google.

Bin dann auf den Eintrag gestoßen.

Wobei ich bei der _parameter Variable das 'c' entfernt habe.
Mapping erfolgreich.

1. Bild im Anhang: So sieht es dann im Debugger aus.

Lass ich die Expression nun gegen die Db laufen, erhalte ich eine InvalidOperationException, sobald ich auf den Entites mit Where und dem Criteria filtere.
Message:

The LINQ expression 'DbSet<Category>()
    .Where(c => x.Id == __idToGet_0)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See [url]https://go.microsoft.com/fwlink/?linkid=2101038[/url] for more information.

In der Message steht "c => x.Id....".
Ich gehe davon aus, dass es an dem "c" liegt. Aber woher kommt das?

P.S.: Ich weiß wie Expressions oberflächlich funktionieren, aber so genau, wie man diese mappt, woraus die konkret bestehen weiß ich nicht. Deswegen habe ich vorerst die Methoden aus dem SO Beitrag 1:1 übernommen.

Grüße
Duesmannr

Thema: Wie kann ich eine USB-Hardware-Sperre programmieren?
Am im Forum: Grundlagen von C#

Geht von Haus aus.

Und auf den Geräte-Manager oder Regedit zugreifen zu können, muss man Admin sein.

10 Sekunden gegooglet.

Erste Seite

Zweite Seite

Thema: Netzwerk Adapter Name ändern
Am im Forum: Netzwerktechnologien

Durch die Google Suche von @Abt findet man folgende Stackoverflow Einträge:

how-to-change-the-name-of-a-networkadapter-in-c
get-name-of-network-that-a-network-interface-is-connected-to

Thema: WPF DataGrid - Refresh single Item
Am im Forum: GUI: WPF und XAML

Zu den Methodenaufruf


OnPropertyChanged()
würde ich keine magic strings nehmen, sondern


nameof(PropertyName)

Thema: C# Konvertierung einer FormApp in eine KonsolenApp
Am im Forum: GUI: Windows-Forms

Moin,

WinForms ist eine Konsolenanwendung.
Es gibt in deinem Projekt die Program.cs, die die Form aufruft.

Das ist der Einstiegspunkt in deiner WinForms Anwendung und in einer Konsolenanwendung ist es ebenfalls der Einstiegspunkt.

Da du die GUI dann nicht brauchst, kannst du die Logic in die Program.cs implementieren die dann 24/7 läuft oder immer wieder ausgeführt wird.

Erstell doch mal eine Konsolenanwendung und guck es dir an, ist sehr einfach.

Grüße

Thema: Warum geht ein Request zum FileUpload im PostMan durch aber im HttpClient gibt es Fehler?
Am im Forum: Netzwerktechnologien

Nabend :)

versuche seit Gestern ein Postman Request nachzubauen mit dem HttpClient, den ich über den Proxy von einer Anwendung abgefangen habe. (POST Request)

Der Request lädt eine Datei hoch.

Anbei ein Foto von Postman mit den ganzen Request Headers.
Und hier der raw Body vom Request:

----------010521174505517
Content-Disposition: form-data; name="sess_id"

aravtx27odgrsoba
----------010521174505517
Content-Disposition: form-data; name="file"; filename="testfile.txt"
Content-Type: application/octet-stream

****file content****
----------010521174505517--

Die Authentication läuft über die "sess_id".

In der API Doku steht nur das (und der Support schreibt nur Einzeiler als Antwort)

Endpointhttps://api-v2.ddownload.com/api/upload/server?key=key

Parameters
key : String : API key Example: 1hj124iod23j12gd3

Response

{
    "msg": "OK",
    "server_time": "2017-08-11 04:29:54",
    "status": 200,
    "result": "https://s1.ddownload.com/upload/01"
}

Mein Code ist wie folgt:

Service service = new("api key", null);

            using FileStream fs = File.Open(@"C:\Users\User\Downloads\testfile.txt", FileMode.Open, FileAccess.Read);

            Result<string> result = await service.GetServerUrlAsync();

            string boundary = "--------" + DateTime.Now.Ticks.ToString("x");

            StreamContent sc = new(fs);
            sc.Headers.ContentType = new("application/octet-stream");

            MultipartFormDataContent content = new(boundary)
            {
                { new StringContent(result.SessionId), "sess_id" },
                { sc, "file", "test.dat" }
            };

            content.Headers.ContentType = new("multipart/form-data");

            try
            {
                HttpResponseMessage response = await service.Client.PostAsync(result.Response, content);
                string responseString = await response.Content.ReadAsStringAsync();
            }
            catch (Exception ex)
            {

            }

Service: Erstellt einen default HttpClient.
service.GetServerUrlAsync(): ruft die oben angegeben Endpoint Adresse auf, wo ich als response die Session ID und die URL zum hochladen bekomme.

Response hat einen 200er.
Im Content steht nur:
<h1>Internal Server Error</h1>\n<p>The server encountered an internal error or\nmisconfiguration and was unable to complete\nyour request.</p>

Übersehe ich etwas? Oder fehlt irgendetwas, was man bei dem Request nicht sieht?

Grüße
duesmannr

Thema: Migration von WebClient zu HttpClient: Bildupload liefert mit HttpClient ein leeres Bild
Am im Forum: Netzwerktechnologien

Zitat von Abt
PS: kurz gegoogelt. Die Webseite bietet sehr wohl eine API; wenn auch sehr rudimentär.
https://www.directupload.net/api/upload.php

Das habe ich auch nie verleugnet.
Nur das die keine Dokumentation dafür besitzen bzw. nicht öffentlich ist.

Thema: Migration von WebClient zu HttpClient: Bildupload liefert mit HttpClient ein leeres Bild
Am im Forum: Netzwerktechnologien

Zitat von Abt
Die Seite arbeitet mit Content-Type: multipart/form-data; und nicht mit binary/octet-stream.

Der WebClient Code Schnipsel kommt aus deren eigenem Uploader Tool.

Ich habe auch schon versucht mit dem HttpClient und dem MultipartFormDataContent den Request zu senden. Aber gleiches Ergebnis wie beschrieben.

Thema: Migration von WebClient zu HttpClient: Bildupload liefert mit HttpClient ein leeres Bild
Am im Forum: Netzwerktechnologien

Zitat von Abt
Gib doch den potentiellen Helfern ein wenig mehr Infos zur API.... Name? Docs?

Es gibt keine API Dokumentation.
Der Image Hoster ist der hier.

Thema: Migration von WebClient zu HttpClient: Bildupload liefert mit HttpClient ein leeres Bild
Am im Forum: Netzwerktechnologien

Nabend,

ich hänge gerade dabei, den WebClient Request zu einem HttpClient Request zu konvertieren.

Der WebClient Request sieht wie folgt aus und funktioniert auch:


string testImagePath = @"Path.png";

            WebClient client = new();

            client.UploadFileCompleted += Client_UploadFileCompleted;

            client.Headers.Add("Content-Type", "binary/octet-stream");
            Uri address = new("API Endpunkt");
            client.UploadFileAsync(address, "POST", testImagePath);

Mein Versuch mit HttpClient sieht wie folgt aus:


string testImagePath = @"Path.png";
            byte[] imageBytes = File.ReadAllBytes(testImagePath);

HttpClient httpClient = new();
            httpClient.DefaultRequestHeaders.Clear();
            httpClient.DefaultRequestHeaders.Accept.Add(new("*/*"));

            ByteArrayContent byteArrayContent = new(imageBytes);
            byteArrayContent.Headers.ContentType = new("binary/octet-stream");

            var resp = await httpClient.PostAsync("API Endpunkt", byteArrayContent);
            var content = await resp.Content.ReadAsStringAsync();

Habt Ihr eine bessere Idee, bzw. was mache ich falsch?

Grüße und schöne Weihnachten :)

P.S.: Es handelt sich um einem Imagehoster. Die Variante mit dem WebClient liefert lediglich einen String mit der URL zu dem hochgeladenen Foto. Die Variante mit dem HttpClient liefer ebenfalls eine URL zurück, nur wenn ich diesen aufrufe, kommt ein leeres Bild vom Hoster. Quasi "Image not Found" Bild.