Hallo.
Ich habe eine statische Methode zum hochladen von einer Datei und weiteren Informationen. Das Hochladen geschieht per PostAsync() aus der HttpClient-Klasse.
Die Anfrage soll sich mittels eines Authentifizierungstokens beim Server gepüft werden. Sende ich einen ungültigen Token, so bekomme ich korrekter Weise vom Server einen 403 zurück. Soweit so gut.
Meine Schwierigkeit bekomme ich nun dabei diesen 403 auch innerhalb meiner Windowsanwendung zur greifen um ihn anzuzeigen. Beim der unten stehenden Methode versuche ich den Status abzufragen und dann auszugeben, allerdings kommt er nie über ".. client.PostAsync(url, formData).Result;" hinweg!
Die Methode loadFromDownloadDirToURL() wird beim Aufrufer innerhalb einer try catch Anweisung ausgeführt die eine Ausnahme anzeigt mit der Beschreibung. "Es ist mindestens ein Fehler aufgetreten"?!
Diese Mechanik mit asynchronen Aufrufen ist mir relativ neu und ich komme nur schwer damit zurecht. Wenn ich debugge kommt er nie an die Stelle unterhalb dieses Aufrufes.
Was mache ich falsch? Bitte um Hilfestellung.
public static void loadFromDownloadDirToURL(string url, string fileName, string token)
{
// Datei einlesen
byte[] file = IOMgmt.readBytesFromDownloadDir(fileName);
// Formulardaten
MultipartFormDataContent formData = new MultipartFormDataContent();
formData.Add(new StringContent(Convert.ToBase64String(file)), "file");
formData.Add(new StringContent(fileName), "filename");
formData.Add(new StringContent(token), "token");
HttpClient client = new HttpClient();
HttpResponseMessage response = client.PostAsync(url, formData).Result;
if (!response.IsSuccessStatusCode)
{
throw new Exception(response.StatusCode.ToString());
}
}
Mit dem .Result untertdrückst Du Fehler und kannst einen Deadlock auslösen.
Wieso verwendest Du den async/await Pattern nicht einfach richtig? Ja, kann gut sein, dass man sich mit dem Pattern vertraut machen muss 😃 Aber dafür gibts eine sehr gute Dokumentation in der MSDN.
Statische Methode sieht auch nicht gerade gut überlegt aus 😉
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Diese Mechanik mit asynchronen Aufrufen ist mir relativ neu und ich komme nur schwer damit zurecht.
Ich würde mich über ein Bespiel mit einer besseren Version (angelehnt an meine) sehr freuen 😃
Naja, ich werd Dir jetzt nicht den Code schreiben; mit Sicherheit nicht.
Wieso nicht einfach die Doku lesen, wo es gut erklärt ist?
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Man soll mir auch nicht mein komplettes Programm schreiben sondern nur den Teil mit dem Upload anhand von Besipielen erläutern, thats all
OK ich seh schon...ich versuch mal Hilfe in anderen Foren zu finden.
Da kann ich nur sagen: viel Erfolg 😃
Hätte ich mehr Eigeninitiative gesehen, dann hätte ich Dir trotz [Hinweis] Wie poste ich richtig? Punkt 4 nen Code Beispiel genannt.
Aber Du hast leider nicht mal auch nur den Hauch des Interesses (Antwort 2 Min nach meinem Beitrag) die Doku zu lesen gezeigt. Sieht eher nach "abwälzen" aus und ich lass mich nicht ausnutzen. Schade drum.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Herr Gott, was ist denn hier los?!
Da stellt man eine Frage und wird derart abweisend behandelt. Ich würde hier nicht posten wenn ich nicht schon den ganzen Tag rumsurfen würde nach einer Lösung. Vielleicht such ich an den falschen Stellen oder kapier es halt noch nicht, kann alles sein. Aber eine Antwort wie "Such die Lösung selbst und dann wenn du sie kennst kannst hier nochmal posten" ist auch reltiv wertlos.
Davon abgesehen, dass ich Dein Zitat weder wörtlich noch inhaltlich geschrieben habe, habe ich Dich auf die mehr als ausführliche Dokumentation der MSDN (Asynchrone Programmierung mit Async und Await (C# und Visual Basic)) verwiesen - freundlich und sachlich.
Dort ist eine ausführliche Beschreibung, Prinzipien und ein vollständiges Beispiel enthalten.
Ich kann mir - sorry - wirklich nicht vorstellen, dass man diese Seite nicht findet.
Statt den Rat anzunehmen hast Du direkt, keine 2 Minuten später ein Beispiel "gefordert".
Ich erkenn hier also weder Initiative noch Wille; wieso sollte ich Dir dann den Code schreiben, wenn die Gegenseite kein wirkliches Interesse hat sondern - gefühlt - die Arbeit auf das Forum abladen will?
Genau so hört sich auch der Satz "geh ich halt wo anders hin" an.
Mir vorzuwerfen, dass ich nicht helfen wollen würde, naja... 😉
Ich helfe gerne - ich denke, dass das mehr als offensichtlich ist. Aber nicht, wenn jemand nur den fertigen Code will. Ob das Tatsache ist oder nur falsch ausgedrückt... liegt nicht in meiner Hand.
Zudem hab ich Dir eigentlich auch schon gesagt, warum Du keinen Fehler bekommst - im ersten Post von mir hier (Result unterdrückt).
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Also die Sache ist die:
Ich möchte versuchen meinen Quellcode möglichst simpel zu halten. Weder mir noch einem Kollegen möchte ich wegen eines eigentlich simplen uploads einer Datei, dieses doch - wie ich finde - recht komplizierte Konstrukt von "async und wait" aufzwingend. Stichwort Wartbarkeit des Quelltextes.
Ich nutze zwar diese asynchrone Methode "PostAsync(url, formData)" aber eigentlich würde ich viel lieber synchron arbeiten. Deswegen hatte ich nach einigen Recherchen auf Seiten wie z.B. dieser Seite versucht dan Aufruf synchron zu machen mit eben dm ".Result" am ende der Funktion.
Dies führt zum oben beschriebenen Problem. Es wird dabei durchaus eine Exception ausgelöst, nur keine in der ich den StatusCode (403) abfragen könnte.
In der oberen Variante kann ich die Formulardaten bequem per MultipartFormDataContent-Objekt erzeugen und an die Funktion übergeben. Ich habe leider keine vergleichsweise simple Vorgehensweise im Internet finden können um die Formulardaten zu senden.
Eventuell weiß ja jemand ein alternative Vorgehensweise, die ohne asynchrone Funktion auskommt?!
Hallo Marcel,
bei einer Async Methode werden im Falle eines Fehlers immer eine AggregateException geworfen. Die eigentliche Ursache steckt aber in der InnerException der AggregateException:
Beispiel ungetestet:
try
{
loadFromDownloadDirToURL(...);
}
catch (AggregateException ex)
{
MessageBox.Show(ex.InnerException);
}
D.h. schau mal in die InnerException ob du da mehr Infos rauslesen kannst...
Grüße
Steffen
bei einer Async Methode werden im Falle eines Fehlers immer eine AggregateException geworfen.
Das stimmt leider nicht 😃
Auch zeigst Du leider keine korrekte Anwendung des async/await Patterns
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Hallo Steffen.
Ich habe das mal versucht und der InnerException ist leider auch nicht der StatusCode des Servers. In diesem Falle wird eine "TaskCanceledException" geworfen un dder Text der InnerException lautet > Fehlermeldung:
Error while copying content to a stream. Hier mal eine Ausschnitt as dem Log:
09:23:15.657> bei System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
bei System.Threading.Tasks.Task1.GetResultCore(Boolean waitCompletionNotification) bei System.Threading.Tasks.Task
1.get_Result()
bei LlPortalDesigner.IOMgmt.loadFromDownloadDirToURL(String url, String fileName, String token) in c:\Users\XGWSWGM\Documents\Visual Studio 2013\Projects\LlWebService\LlPortalDesigner\IOMgmt.cs:Zeile 101.
bei LlPortalDesigner.MainForm.startUpload() in c:\Users\XGWSWGM\Documents\Visual Studio 2013\Projects\LlWebService\LlPortalDesigner\MainForm.cs:Zeile 277.
09:23:15.610> Fehler beim Hochladen der Projektdateien: Error while copying content to a stream.
09:23:15.610> Fehler beim Hochladen der Projektdateien: Mindestens ein Fehler ist aufgetreten.
Bitte benutze die richtigen Code-Tags [Hinweis] Wie poste ich richtig? Punkt 6
Da Du die System.Net.Http Klasse verwendest vermute ich, dass Du entweder eine Windows 8(.1) oder eine Universal App verwendest.
Dazu passt auch der Link, den Du gepostet hast.
Jetzt ist es im App/UWP-Umfeld so, dass asynchrone Programmierung kein Kann-Zustand ist, sondern ein Muss-Zustand. Da hilft auch kein Bockig-sein oder mit den Füßen auf den Boden stampfen.
Implementierst Du nichts async oder nicht richtig, dass schießt der AppScheduler die App ab (und das ist auch gut so).
Das kannst Du übrigens auch in der Dokumentation nachlesen bzw. wird das auch bei zahlreichen Channel9 Videos zum Einstieg in die App-Welt ausdrücklich gesagt. Man muss sich nur die Mühe geben und mal zuhören können 😉
Die Aussage
Ich nutze zwar diese asynchrone Methode "PostAsync(url, formData)" aber eigentlich würde ich viel lieber synchron arbeiten.
ist also leider keine Option.
Du wirst Dich zwangsläufig mit async/await und korrekter Task-Implementierung beschäftigen müssen, wenn Du in diesem Umfeld etwas programmieren möchtest - ob Du willst oder nicht.
Deswegen wirst Du auch normalerweise/meistens in den Namespaces für diese Zielapplikationen nur noch asynchrone Implementierungen finden.
public async Task<String> loadFromDownloadDirToURL(string url, string fileName, string token)
{
// Datei einlesen
// keine Ahnung was IOMgmt sein soll; dem Namen nach liest es irgendwo (Extern) Bytes und _muss_ daher asynchron implementiert sein
byte[] file = await IOMgmt.readBytesFromDownloadDirAsync(fileName);
// Formulardaten
MultipartFormDataContent formData = new MultipartFormDataContent();
formData.Add(new StringContent(Convert.ToBase64String(file)), "file");
formData.Add(new StringContent(fileName), "filename");
formData.Add(new StringContent(token), "token");
// Ebenfalls externer Zugriff (Web) und damit asynchron Pflicht
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.PostAsync(url, formData);
if (!response.IsSuccessStatusCode)
{
throw new Exception(response.StatusCode.ToString());
}
// hier kein await obwohl async, weil Task durchgereicht wird
return response.Content.ReadAsStringAsync();
}
Und jetzt endlich mit Tasks beschäftigen.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Das ich nicht asynchron arbeiten möchte hat eben einige Gründe:
Aber las uns doch lieber fachlich diskutieren. Ich habe mir nämlich mittlerweile durchaus diverse Seiten mit diesem Thema angeschaut. In deiner Version mit den async und await Markern bekomme ich ich bei mir die Compiler-Meldung:
"Da es sich hierbei um eine asynchrone Methode handelt, muss der Rückgabetyp den Wert 'string' anstelle von Task<string> aufweisen."
Interessante Ansichten...
Also Du kannst Dich da ruhig im Kreis drehen oder bockig stellen; aber bei Apps ist Async nun mal per System-Design notwendig und pflicht, sonst wird die App abgeschossen. Da hilft es auch nicht mit "nicht notwendig" zu argumentieren oder für "beendet" erklären.
Akzeptier diese Tatsache oder lass es halt bleiben. Dann muss man halt zur Not die App Programmierung auslagern. 🤔 Alternativ einen Beschwerdebrief verfassen oder ein Feature Request für synchrone Umsetzungen in Windows Apps einreichen.
Hilft halt der Problemlösung nicht. Wie es korrekt geht hab ich Dir jetzt sogar als Snippet gegeben.
Du hast fachlich jetzt alles was Du brauchst, auch wenn Du es irgendwie nicht ganz verstehen willst.
Und dass man als Entwickler hin und wieder sein Wissen auffrischen und neue Technologien erlernen muss; das ist eigentlich selbstverständlich und gehört in die Ressourcenplanung.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Ich glaube du verstehst mich einfach nicht. Ich entwickle eine normale Windows Form Anwendung und in diesem konkreten Fall ist es egal ob das Formular mal ne Sekunde still steht weil Deteien hochgeladen werden. Darauf basiert meine Aussage: "Es ist garnicht notwendig".
Aber wir machen den Thread hier am besten zu denn ich habe es nun synchron gelöst (und es funktioniert ganz wunderbar) und fertig.
Dann solltest Du das mal sagen (was man nach 10 Jahren im Forum erwarten kann), denn der Link den Du gepostet hast, ist halt Windows Phone.
In der Windows Forms Namespace hast Du auch Methode, die nicht async sind. Nimm halt die.
Hätte hier einiges gespart.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code