Laden...
Avatar #avatar-4119.png
Abt myCSharp.de - Team
Principal Software Engineer Dabei seit 20.07.2008 16.861 Beiträge
Benutzerbeschreibung
Als Principal Software Engineer berate und unterstütze in Form von Entwicklungsleistung aktiv Projekte und Unternehmen in Sachen technischer Zukunft mit dem Fokus auf auf .NET und hoch-moderne Web-Anwendungen/-Landschaften in der Cloud. Ich präsentiere die Technologien von Morgen und helfe bei der Analyse der korrekten Strategie und Methodiken für die Umsetzung. Neben meinem Tech-Blog SCHWABENCODE.com bin ich seit 2011 in exekutiver Funktion dieses Forums tätig, schreibe Artikel und halte ab und zu Vorträge in kleineren Runden zum Thema Cloud, Web-Development und IoT. Seit 2015 wurde ich jedes Jahr zum Microsoft MVP für (.NET / Azure) ernannt.

Forenbeiträge von Abt Ingesamt 16.861 Beiträge

22.05.2024 - 13:13 Uhr

Dann nimm Dir wenigstens 4h Zeit, und mach die Grundlagen in der .NET Doc durch. Weil aktuell wirkt es so, dass Du eher nach dem Stocher-Prinzip vorgehst - das wird nix. Da brauchste 100x so lang für nen Fortschritt - und die Leute um Dich herum ziehen an Dir mit Wissen vorbei.

22.05.2024 - 00:03 Uhr

Zitat von FrankenDerStein

Mit Standard meine ich ein genormtes Protokoll welches ein Datei System abbildet und ein Synchronisation ermöglich.

Wenn ich die Aussage so lese: ich hab den Eindruck, dass Dir nicht bewusst ist, wie Systeme mit Dateien arbeiten und dass es keinen fixen Standard für Dateien gibt. Wie eine Datei aussieht ist im Endeffekt Aufgabe vom Dateisystem - und das Betriebssystem hat eine Abstraktion davon, die dann in das jeweilige Dateisystem übersetzt wird.

Es gibt auch kein Protokoll, was eine Dateisystem zu Dateisystem synchronisation durchführt, sondern das sind nachher Layer wie SMB und Co - oder dann entsprechende Systeme.

Kann Http ein Datei System abbilden mit allen Informationen, die Synchronisation ermöglicht?

HTTP ist ein Transportprotokoll - mehr nicht. Was Du damit aber überträgst ist "egal" - und ja, alle modernen Speicherdienste verwenden genau dafür HTTP.

Willst Du was wie SMB - das ist aber im Endeffekt kein "Internetprotokoll" - dann bist Du mit HTTP auf dem falschen Weg. Aber Protokolle wie SMB3 sind keine Applikationsprotokolle, sondern Systemprotokolle - mit all deren Vor- und Nachteilen. Und ne - für mich hört sich das nicht nach WebDAV an.

Nur mal als Beispiel, wenn man ein Tool bauen will der mit jeder Cloud Kommunizieren können soll. Kann man das simple Http Protokoll verwenden?

Mir ist schleierhaft was Du vor Dir hast, gib halt mal mehr Infos - weil ich glaube Du 2 Dinge miteinander vermischt. Und das ist Dateisystem und "Dateien in der Cloud". Das Thema heisst "Web-Cloud Standard" - was soll das denn heissen?

Ja, Cloud-Systeme wie Azure Blob Storage, AWS S3 oder Cloudflare R2 sind Blobspeicher aka Objektspeicher. Das sind alles Systeme, die keine Dateisysteme alá NTFS sind. Sie kommunizieren maßgeblich über HTTP, wobei eine Datei dann unterteilt ist als "Blob" und "Metadaten". Ein Blob ist der rohe Inhalt, Metadaten sind dann Infos wie Zeitstempel und Co, was man zB bei NTFS auch kennt. Wie die Datei unter der Haube abgespeichert wird: Dir egal.
Genau so funktionieren auch Services wie OneDrive, Dein privates Synology NAS und Co.

Konkretes Beispiel: Eine Datei auf NTFS hat Daten und File Attributes. Wird die Datei auf OneDrive, Azure Blob Storage etc übertragen... dann via HTTP. Dazu gibt es den HTTP Stream (über Chunks) und dann die Attribute. Im Blob Storage dann wie beschrieben als Metadaten abgelegt. Willst Du Dateien dann wieder runterladen, wird der Inhalt runtergeladen, danach die Metadaten und vom Client lokal als Attribute gesetzt.
Völlig simpel, stabil - sicher.

Bei HTTP hast Du gegenüber allen anderen Wegen nämlich den enormen Vorteil, dass Du keinerlei Firewallkonfiguration durchführen musst; daher funktionieren solche Dienste eben auch für jeden 0815 Endanwender.

Um daher die Frage zu beantworten, ob das mit HTTP geht: natürlich, so funktionieren eben genau diese Dienste.
Die Frage "welchen sicheren Web Standard für Dateien gibt es" - nein, sowas gibts natürlich nicht. So funktioniert weder das Internet noch die Clouddienste.


Willst Du ein Tool schreiben, das sicher Dateien auf Azure Blob Storage, AWS S3 oder Cloudflare R2 übertragen kann, dann musst Du alle drei Systeme in ihrer invididuellen Art und Weise selbst umsetzen.
Alle drei verwenden für die Übertragung HTTPS - aber alle drei haben verschiedene Authentifizierungssysteme, verschiedene Funktionalitäten und verschiedene Endpunkte.
Die einzige Gemeinsamkeit ist quasi: Du kannst damit sehr effizient Daten transportieren und speichern - über HTTP.


Aber ich hab den Eindruck, dass Du Dich da vielleicht vorher etwas tiefer einlesen solltest, wenn Du OneDrive und Co als eigenes Tool nachprogrammieren willst. Technisch ist das mit HTTP absolut kein Problem - im Gegenteil: bestehende und etablierte Services zeigen Dir, wie perfekt das funktioniert.

20.05.2024 - 18:46 Uhr

Was meinst Du mit Standard, was für ein Standard?

Ich kann mir nicht vorstellen das HTTP mit TLS(HTTPS) für die Dateien Austausch verwendet wird

Doch, HTTP ist die Standardverbindung und hat prozentual sehr wenig Overhead und ist sehr kompatibel. Kannst auch mit jedem Package-Inspection Tool wie Wireshark einfach nachvollziehen.

da das Protokoll nicht gerade für ein Datei Transfer gemacht ist zumindest nicht ohne Overhead.

Mh? Wie kommst Du drauf?
HTTP als Protokol hat eingebaute Optimierungen extra für Dateien, zB HTTP Streaming etc, die enorm effizient sind, eine maximale Skalierbarkeit und Real-Time-Data Delivery bieten.

Kann daher die Behauptung nicht nachvollziehen.

FTPS ist dafür zwar gemacht, aber gilt nicht als Sicher (zumindest was ich hörte).

FTPS gibts i.d.R. keine Option für; aber SFTP wird optional angeboten - aber bei den Clients (zB AWS CLI oder Azure CLI) nicht verwendet.

20.05.2024 - 18:39 Uhr

Laut Statistik (letzte 30 Tage) werden vom Forum die Requests in 95% der Fälle innerhalb von 48ms und bei 99% bei 127ms verarbeitet.
Die Antwortzeit der Frontdoor beträgt 72ms im Schnitt.

Die aktuell langsamste Seite ist die Suche mit 2,05 Sekunden im Schnitt.

Daher nein, kann nirgends etwas von mehreren Minuten erkennen.


Du kannst ja mal ein Tracert zum Forum durchführen, vielleicht sieht man da, welcher Hop langsam sein soll.
Aber was dran ändern können wir aktuell nicht. Von unserer Seite sehe ich keine Issues.

16.05.2024 - 13:35 Uhr

So startet Spaghetti-Code. Daher: ja.

Wie gesagt; goto hat in strukturierten Sprachen keinen direkten Anwendungsfall mehr. Verwende eine Sprache so, wie sie gedacht ist.

16.05.2024 - 13:12 Uhr

Siehe mein Beitrag in https://mycsharp.de/forum/posts/3841689 unterer Teil.

Erst 3 Wochen alt.

16.05.2024 - 12:07 Uhr

..und den goto-Käse sein lassen.

14.05.2024 - 22:18 Uhr

Für mich ist allerdings folgendes noch immer unklar, wenn der Port einige Stunden lief ohne Probleme und auf einmal reagiert er nicht mehr auf die gesendeten Daten da der Port angeblich geschlossen ist.

Technisch gesehen ist es so, dass ein SerialPort gar keine Verbindung besitzt. Es gibt kein State "Connected" oder sowas.
Die Realität sieht so aus, dass versucht wird Daten zu senden und entweder es wird akzeptiert, oder nicht. Das "Open" in der .NET Implementierung erstellt dazu nur das Handle, mehr nicht.

Siehe Quellcode dazu hier.

Ein "geschlossen" heisst einfach nur, dass ein Fehler beim Senden passiert ist - oder Du zB in das ReadTimeout läufst.

Hast das Error Event abonniert?

Jedes Mal beim senden fragt er zuvor allerdings ab ob der Port bereits geöffnet ist oder nicht. Ist er geöffnet, sendet er die Daten. Sofern er nicht geöffnet ist probiert er ihn zu öffnen und schlägt dabei aber fehl.

Du kannst auf einen offenen SerialPort kein erneutes Open ausführen. Du musst alles sauber "schließen" via Close, nur dann kann man erneut Open ausführen.

Siehe auch hier der Code dazu aus dem Link:

public void Open()
{
  if (IsOpen)
     throw new InvalidOperationException(SR.Port_already_open);

Wenn ich nun allerdings meine Anwendung neustarte, kann er den Port ganz normal öffnen auch wenn keine Close Methode beim Schließen vorhanden ist, warum kann er es beim Neustart aber nicht wenn ich zuvor Abfrage ob der Port geöffnet ist oder nicht ?

Kenne nun die genaue Implementierung von SerialPort etc nicht; und auch gibts teilweise Unterschiede bei Windows Versionen; aber vielleicht wird hier das Handle automatisch von Windows aufgeräumt, wenn der Parent-Prozess (also Deine Anwendung) geschlossen wird. Oder die Implementierung in .NET ist doch managed, dann wird es automatisch aufgeräumt, wenn der .NET Prozess beendet wird. Müsste man nun im Quellcode mal durch gehen..


Du musst Dir bewusst sein, dass SerialPorts keine stabile Verbindung darstellen; das ist nicht so wie eine Ethernet-Verbindung mit einem entsprechenden Protokoll.

14.05.2024 - 21:21 Uhr

Der SerialPort ist eine Ressource, die von Windows verwaltet wird. Genauer gesagt ist SerialPort nur ein Wrapper für die Windows-Funktionalität.
Wird der Port (bzw. das hinterliegende Handle) nicht korrekt geschlossen, bleibt das Handle als Leiche übrig und der Port ist blockiert. Das passiert mit fast jeder von Windows verwalteten Ressource (Dateien, Ports, Adapter...).

Alle Handles müssen unter Windows immer korrekt geschlossen werden - passiert das nicht, blockiert jeder weitere Zugriff darauf; wie hier.

der Port wird beim Schließen des Programmes nicht extra geschlossen.

Ist also ein grundlegender Fehler.

14.05.2024 - 18:43 Uhr

Das ist relativ; kann ich bzw will ich auch nicht so bejahen oder verneinen - ich verantworte euer Dev(Sec)Ops nicht 😃

Bei uns hat keine einzige Pipeline irgendwo Rechte, etwas in Libs zu schreiben - ist eigentlich auch nicht notwendig.
Die Grundidee ist ja, dass jeder Pipeline ein Deployment hat - teilen sich bei euch zwei Pipelines das gleiche Deployment-Szenario, dann ist das halt nen (begründeter?) Workaround.
Ich bzw. "wir" (Firma, Projekte, Kunden..) halten uns jedoch so streng wie möglich an die optimalen Szenarien von Azure / Azure DevOps.

  • Wir haben ein völlig autarkes Bicep-Setup, das die Infrastruktur aufsetzt.
  • Alle Azure DevOps Steps bekommen ihre notwendigen Daten durch Bicep-Outputs
  • Wir sharen niemals Informationen über Pipelines hinweg; alle Libs sind nur read-only, allein schon aus Berechtigungsgründen

Aber auch wir arbeiten zwangweise bei ein paar Dingen mit Workarounds:

  • Wir haben oft zwei main.bicep Files: main-run.bicep und main-read.bicep - wir führen das run-file nur aus, wenn sich was an der Infrastruktur verändert hat (git diff) ⇒ dadurch läuft die Pipeline schneller (je nach Pipeline spart das bei uns 80% der Dauer). Das read-file ist viel kleiner, ändert nichts (alles via existing) und liest die Outputs für die weiteren Steps aus.
  • Wir arbeiten bei allen Bicep-Files mittlerweile mit bicepparam-Dateien
  • Brauchen andere Pipelines Werte (zB zentrale Komponenten wie Config Service für Feature Flags), dann sind die in den Param-Files hinterlegt oder sie holen sich die Werte eben über existing - das ist ja eben der Vorteil, wenn man über Bicep das dynamische Zeug generieren lässt: man kann immer darauf referenzieren, weil es idempotent ist.

Wenn Du über die Lib gehen willst, musst das selbst verantworten. Ich würde es im Vergleich als die schmutzigere Workaround-Lösung bezeichnen 😉


Die Funktionsweise, die ich hier beschrieben hab, ist so auch für mycsharp.de umgesetzt (wir haben nur noch keine bicepparam-Files, die sind ja noch nicht so lange GA).

14.05.2024 - 17:04 Uhr

Die Best Practise und auch das vorgesehene Verhalten ist, dass Du in Deinem main.bicep entsprechende Outputs hast.

Bicep spuckt Dir diese Werte als Json aus, sodass Du diese weiter in der Pipeline nutzen kannst.
Dazu bietet sich auch an, dass Du ein PowerShell Script nutzt, das Dein Deployment startet.

// main.bicep

output myOutputVar string = 'Hello World'
// PowerShell

$result = az deployment group create -g test --template-file main.bicep | ConvertFrom-Json
$myOutputVar = $result.properties.outputs.myOutputVar.value

Die $myOutputVarkannst Du dann weiter verwenden; im Script entsprechend über die Variablen - in weiteren Steps über dieses wirre Variablen-Handling in Azure Devops.

Write-Host "##vso[task.setvariable variable=myOutputVar;isoutput=true]$myOutputVar"

Vollständiges Sample siehste hier: Using Bicep params and output in Azure Pipelines | by Philipp Bauknecht | medialesson | Medium


Im Endeffekt würde man also über die main.bicep die kompletten Ressourcennamen ( WebApp, DB...) zurück geben; nicht nur den generierten Teil.
So kann man 100% alles dynamisch umsetzen.


Nur als Disclaimer: Ich hab an dem verlinkten Blogartikel mitgeschrieben. Wer den nervigen Medium-Banner sieht - einfach im Inkognito-Modus öffnen.

10.05.2024 - 13:09 Uhr

Finanzen.net verbietet das Crawling und hat für sowas extra eine API.
Entsprechend haben sie auch Maßnahmen, dass Du eben nicht crawlst. Eine solche siehst Du evtl. hier.

Und da dies eine rechtlich problematische Situation ist - das Anbieten von Daten ist Teil des Geschäfts von Finanzen, daher hätten sie evtl. Schadensersatzansprüche im Fall der Fälle - werd ich Dir da auch nicht helfen, das zu umgehen. Denke da hast Verständnis für.

08.05.2024 - 15:10 Uhr

Danke Dir, ist aufgenommen.

06.05.2024 - 17:03 Uhr

Es ist nicht ersichtlich, was Deine "Main Klasse" darstellen soll.

Soll das eine Page-To-Page Kommunikation werden, oder soll da Business Logik mit dem Fenster kommunizieren....?

06.05.2024 - 14:56 Uhr

Das hört sich nicht so an, als ob Du den MVVM Pattern, den man mit WPF umsetzen sollte, sauber implementiert hast.
[Artikel] MVVM und DataBinding

Was Du mit "andere Klasse" meinst, erschließt sich mir nicht.
Was ist die andere Klasse bei Dir? Eine andere Page? Business Logik...?

06.05.2024 - 10:09 Uhr

Feedback zu Deinem Code (nur die wichtigsten Punkte):

  • Seit >10 Jahren ist die Empfehlung nur noch den HttpClient zu verwenden für Anfragen, das gilt auch für .NET 3.5, wobei es da auch noch den WebClient gab
  • Dein Exceptionhandling ist genau das, was man es nicht in .NET tun sollte - das galt schon immer 😃
  • Dein Thread-Handling so ist nicht robust und kostet sehr viele Ressourcen

Aber ja, .NET 3.5 hat solangsam das Problem, dass ein paar Sicherheitsthemen nicht mehr gut in der Runtime gelöst sind und man das selbst machen muss, was es mit späteren Versionen dann eingebaut gab.

05.05.2024 - 16:47 Uhr

Das aller aller aller schlechteste und unsicherste, das man denkbar machen kann, ist sowas wie ein FTP für Appdaten verwenden.

APIs mit modernen Authentifizierungsverfahren sind der Weg zum Ziel.

02.05.2024 - 16:17 Uhr

Du kannst nicht einfach so weitere Attribute dran klatschen; auch wenn es so aussieht, aber es sind keine HTML-Elemente. Sie funktionieren anders.
Du kannst nur die Attribute verwenden, die Du selbst definierst. Willst Du style haben, dann musst das auch definieren und behandeln.

Es sind keine TagHelper oder ViewComponents, wie man sie aus der ASP.NET Welt kennt.


CSS Styles über ein Style-Attribut zu machen ist ohnehin nicht die Idee in modernen Frameworks wie Angular oder Blazor.
Ansonsten funktionieren deren Style-Systeme wie Blazor CSS Isolation nicht. Beachte, wie Frameworks funktionieren und verwende deren Konzepte.

29.04.2024 - 17:58 Uhr

Wenn du sowas brauchst wie

(Dictionary<int, FIMANInternetAnbieter>)L_ListeInternetAnbieter_sortiert2;

ist das schon nen sehr deutliches Zeichen, dass Du hier mit falschen Annahmen arbeitest.

Wie bekomme ich den Fehler weg, der nur zur Laufzeit auftritt?

Die tritt nur auf, weil Du mit dem harten Cast sagst "Ey, ich hab mehr recht als Du Compiler". Und wenn das dann falsch is, dann knallts - wie hier.
Bei Linq gibts eigentlich keinen Fall, bei dem Du etwas hart casten musst.

Das hier

from Anbieter in L_ListeInternetAnbieter orderby Anbieter.Value.Reihenfolge ascending select Anbieter;

liefert Dir ein OrderedEnumerable<KeyValuePair<<int, FIMANInternetAnbieter, int>> aber Du versuchst es in ein Dictionary<int, FIMANInternetAnbieter> zu stopfen - geht nicht. So ähnlich als wenn Du versuchen würdest bei einem Formwürfel ein Quader in einen Stern drücken zu wollen.

In Deinem Fall ist var nicht mal nen anonymer Typ, sondern ein konkreter. Beachte doch den Typ und verwende ihn einfach richtig?
Willst Du ein Dictionary, dann musst Du über ToDictionary gehen und die Typen korrekt zuweisen.

Auch wegen dem anderen Thema: Schau Dir mal die Linq 101 Tutorials an, dann hast 90% Linq-Wissen.


 FIMANLogging.WriteErrorLog("ERROR", "FIMANInternetAnbieter:AnbieterlisteSortiert", ex);

Es gibt einen Standard (Technologieübergreifend), wie man loggen sollte. So eher nicht 😉

Logging in .NET
.NET Open Telemetry

.NET Basics: Exceptions

23.04.2024 - 18:18 Uhr

Also abgesehen von größeren Strukturprobleme, der Verwendung von goto und anderen Dingen...ist Dein Problem, dass der Code eben blockiert. Das ist nie eine gute Idee.

Eine saubere Umsetzung wirst Du nur hin bekommen, wenn Du grundlegend neu beginnst - und zwar so, wie es auch in den Docs gezeigt wird.
Du hast zwar 50% aus den Docs kopiert - aber Du hast die Verarbeitung im Thread offenbar einfach raus gelöscht - und genau das is die Wurzel des Problems hier.


Die SerialPort Docs sind übrigens etwas alt; man würde heutzutage eher Tasks nehmen als Threads; ebenso asynchrone Implementierungen.
Hier im Forum findest Du viele andere Beispiele, zB Template SerialPort | myCSharp.de

Und lass sowas wie goto hier weg... goto hat nichts in strukturierten Sprachen zu suchen. Existiert nur noch für ganz wenige Fälle in C# - das hier ist keiner.

PS: Docs sind dazu da Dir zu zeigen/erklären, wie etwas funktioniert. Seltenst sind die die Samples 1:1 gedacht für produktiven Code zu verwenden.
Sind eben Samples, keine Templates.

23.04.2024 - 10:52 Uhr

Zitat von perlfred

Kann Microsoft nicht so ein einfaches, intuitives Beispiel wie deins, bei der Beschreibung von SelectSingleNode verwenden? Nein, da muss schon wieder gefiltert werden und eine Abfrage über untergeordnete Knoten (descendand) dargestellt werden. Als zweites Beispiel vielleicht ganz interessant, aber um das Prinzip zu verstehen nicht gerade hilfreich. (Anmerkung: Ich hatte mir die Dokumentation schon angesehen, aber nicht verstanden.)

Das ist halt die Doku zur Methode; keine Dokumentation zur grundlegenden Funktionalität von XPath.

Wenn Du in die Anleitung eines Autos schaust, und schaust wie man den Sitz verstellt, dann steht da auch nicht dran wie man das Auto aufschließt, um sich auf den Sitz zu setzen - da wird schon von ausgegangen, dass Du schon drin sitzt 😉

22.04.2024 - 15:13 Uhr
XmlDocument doc = new();
XmlNamespaceManager ns = new(doc.NameTable);
ns.AddNamespace("ns", "https://energieausweis.dibt.de/schema/Kontrollsystem-GEG-2024_V1_0.xsd");

doc.Load("a.XML");

XmlNode node = doc.SelectSingleNode("//ns:GEG-Energieausweis/ns:Energieausweis-Daten/ns:Registriernummer", ns);


Console.WriteLine(node.InnerText);

Ist im Endeffekt der Code aus dem Beispiel der Docs - funktioniert einwandfrei.

Fazit: immer besser mal kurz nen Blick in die Docs zu werfen und anzuschauen, wie das Zeug funktioniert, das man verwendet 😉

22.04.2024 - 14:52 Uhr

Zitat von perlfred

Die im NameSpace angegebene Schema-Datei (xsd) habe ich nicht.

Hat auch niemand gesagt, dass Du das brauchst. 😃 Aber Du brauchst den Namespace. Hört sich danach an, dass Du nicht weißt, was der Namespace macht: dann les es Dir durch.

In dem MS-Beispiel wird doch für das root-Element auch die Klasse XmlElement benutzt. Was sollte ich denn alternativ verwenden?

Ja wird es, aber es wird zusammen mit dem Namespace verwendet, was Du nicht machst. Es ist halt ein default Namespace, kann also sein, dass kein explizites Verwenden notwendig ist (weiß ich nicht auswendig); aber der Zugriff ist definitiv so nich korrekt.

22.04.2024 - 14:26 Uhr

Zitat von perlfred

ergibt immer null!

Naja, Du verwendest eine XML Implementierung, die auf XPath basiert - dann musst halt auch das machen, wie XPath funktioniert.

Du darfst die Klasse XmlElement nicht verwenden wie XElement. Beide Klassen existieren, beide haben ihre Vor- und Nachteile - aber beide Klassen funktionieren nicht identisch (und das ist gut so).

Der Root-Knoten (root) enthält alle Eigenschaften wie man der Schnellansicht des Debuggers (Anhang) entnehmen kann, aber die Pfad-Angabe scheint noch falsch zu sein, was ich nicht nachvollziehen kann.

Du hast eine XML Namespace (zeigt auf ein Schema), ergo muss Dein Zugriff auch über das Namepsace erfolgen. Auch stimmt einfach der XPath nicht.

Siehe direkt das Sample in der Docs von SelectSingleNode, was Du hier verwendest.

21.04.2024 - 21:06 Uhr
  • Beim Compilern soll eine Warnung aufkommen, wenn bei einer ID für eine Sprache kein Text hinterlegt wurde.

Das würde ja bedeuten, dass das immer Teil eines Kompilats ist - was in der realen Welt eher seltener der Fall sein dürfte, je größer die Anwendung ist.

Daher funktionieren die meisten modernen Localizer auch nicht mehr über diese Art der Sprachverwaltung. Der StringLocalizer wurde ja mit ASP.NET Core eingeführt, daher auch dort in den Docs, der aber so in immer mehr und mehr Frameworks adaptiert wird.

Schaut man sich die Web-Welt an (.NET, Java, Rust, Go..) so wird i.d.R. bei APIs gar kein Text mehr zurück geliefert, sondern Status Keys / Codes, sodass die Lokalisierung im Client stattfindet.

PS: Professionelle Übersetzer, mit denen ich zusammen gearbeitet hab, verwenden immer seltener Excel; die arbeiten selbst mittlerweile mit moderneren CMS-Systemen und exportieren in XML oder Json, teilweise sogar mit einer gewissen Strukturdynamik, wenn man denen Schemen zur Verfügung stellt.

21.04.2024 - 17:34 Uhr

Zitat von Tuskpack

Vielen Dank für die Hilfe an Euch.

Im Debugger-Modus kann ich das Formular gar nicht erst öffnen, dort bekomme ich die  Exception Row 0 nicht vorhanden direkt.

Dann hast Du den Breakpoint vergessen. Siehe Anleitung zum Debugger.

Ich sehe leider keinen Zusammenhang zwischen dem ausführen bzw. nicht ausführen des Debuggers und dem Verhalten Row vorhanden bzw. nicht vorhanden.

Sofern Du nichts extra eingebaut hast, und die Assemblies die gleichen sind, kanns am Debugging nicht hängen.
Dann machst irgendwas falsch.

Wie kann es denn dann aber sein, das die 'GesamtPreisTextBox' den korrekten Preis anzeigt?

Spricht auch dafür, dass Du hier was nicht ganz richtig bedienst.

Wenn keine Row existiert, dann stürzt die Anwendung bei

  preisProTag = Convert.ToSingle(tabelle.Rows[0]["preisProTag"]);

ab und kommt gar nicht zur genannten GesamtPreisTextBox-Zuweisung.

19.04.2024 - 14:49 Uhr

Wenn ich dich richtig verstehe: das liegt an der Funktionsweise von Descendants.

Elements nimmt eine Ebene darunter (siehe mein Code sample), Descendants alle; deswegen auch der Name Descendants.

18.04.2024 - 17:20 Uhr

Zitat von Telefisch
Ich habe ja richtig verstanden, dass es sich hier NICHT um Attribute im Sinne des XML handelt, richtig?

Ja, Du hast XML Elemente, die "Attribute" heißen.

Da diese "Attribute" nach der Ordernumber kommen sollte das doch relativ einfach möglich sein.

In XML gibt es eigentlich keine garantierte Reihenfolge. Im Endeffekt hast Du ein sehr schlechtes XML Schema; für mich nicht ersichtlich wie Du mit diesem XML Schema Ordernumbers von anderen "Attributes" trennst.

Du musst Dir da ne eigene Logik basteln, sowas wie

 XDocument doc = ....
 XElement root = doc.Root; // InternalElement

 bool orderFound = false;
 foreach (XElement attributeNode in root.Elements("Attribute"))
 {
     XElement? valueNode = attributeNode.Element("Value");
     if (valueNode is not null)
     {
         string valueNodeValue = valueNode.Value;

         // wenn order noch nicht gefunden...
         if (orderFound is false)
         {
             if (valueNodeValue.Contains("OrderNumbner"))
             {
                 orderFound = true;
                 continue;
             }
         }
         else
         {
             // order gefunden

             // mach etwas mit den weiteren Values
         }
     }
 }

Ohne jetzt alles zu kennen sondern um den Stil zu zeigen, wäre ein ordentliches XML Schema eher sowas wie

<Order Number="KL6401-2" TypeName="ObjectName_02">
  <Detail>
    <Name>LocationIdentifier IEC</Name>
    <Value>-KF02</Value>
  </Detail>
</Order>

Du scheinst da aber eher ein API-Return zu haben, oder? Du hast schließlich noch Typen-Angaben zu all Deinen Elementen.
Vermutlich sind daher auch die Daten alle in Elementen und nicht in Attributen.

Wenn ja - warum alles von Hand parsen statt sich das über ne fertigen Implementierung schenken lassen?

18.04.2024 - 12:23 Uhr

Der gezeigte Code ändert nichts an prodData

Dein beschriebenes Verhalten kann durch diesen Code nicht sein. Verwende den Debugger um zu schauen, was wirklich passiert.
[Artikel] Debugger: Wie verwende ich den von Visual Studio?


Korrektur, weil ich mich verschaut habe:

Du erzeugst eine neue Instanz, überschreibst diese sofort mit prodData und veränderst dann die Eigenschaft. Dein new() hat kein Effekt, sondern Du arbeitest damit eben auf der Referenz von prodData .

Ja - Du änderst damit die bestehende Instanz. So funktionieren Referenztypen.
Reference types - C# Reference - C# | Microsoft Learn

18.04.2024 - 10:12 Uhr

Zitat von cGiesen

Diese Technologie ist mir neu und ich tue mich schwer.

Daher kann ich Dir, wie im anderen Thread auch, nur nahelegen erst mal die Basics zu lernen. EF Core ist leider einer der Themen, bei denen man mit Try-and-Error nicht weit kommt, weil man ein paar Konzepte verstehen muss, die man mit ausprobieren quasi nicht lernen kann.

Hier eine erste konkrete Frage.

Ich habe zwei Tabellen jeweils mit ID als Key:
- Project incl. Company? Company als Referenz zu Company
- Company

Wenn ich jetzt Project abfrage, bekomme ich wunderbar eine Liste alle Projekte.

Es ist nicht ersichtlich, wie Du das bekommst mit dem Code, den Du zeigst. Denn eine entsprechende Relation, die bei EF in diesem Fall zwar optional aber dennoch für so eine Abfrage vorgesehen wäre, fehlt Dir.

Du hast eine 1:n Verbindung, wenn ich Deiner Beschreibung folge, dann fehlt Dir die Navigation in Company. Die ist prinzipiell optional, aber wenn Du drauf zugreifen willst, dann brauchst sie halt.

public class Company
{
       public ICollection<PointOfSale> PointOfSales { get; set; }
            = new HashSet<PointOfSale>();
...

Ebenso würde man eigentlich in der PointOfSale-Entität neben der Company als Navigation selbst auch die Id angeben.

public long? CompanyId { get; set; }
public Company? Company { get; set; }

EF hat zwar ein internes Handling diese Eigenschaft und damit die Spalte in der DB selbst zu erzeugen (Shadow Property), aber es ist dennoch prinzipiell in EF empfohlen, dass direkt zu markieren. EF wirbt zwar ein wenig dafür, dass es viel Magic gibt und man wenig selbst definieren muss - in der Realität sieht das anders aus, wenn man mehr programmiert als ne Todo-Liste.

Fast! Ich bekomme nur die, die auch eine Verknüpfung zur Company haben.

Okay, aber was fragst Du ab? Du zeigst es nicht.
Wenn Du alls PointOfSales haben willst, dann gehst Du ja auch über das Set der PointOfSale und nicht über die Companies.
Da bekommst ja einfach alle, wenn Du nicht gerade ne Where-Clause hast, die das einschränkt.

IQueryable allPoS = dbContext.PointOfSales;

Wo kann / muss ich suchen?

Das wird in den Basics von EF Core behandelt bei den Navigations.

Introduction to relationships - EF Core | Microsoft Learn


PS:

Das korrekte Naming wäre "CompanyEntity" und "PointOfSaleEntity". Deine Entitäten sind keine Business Modelle.
Ja, aus den Docs geht das nicht hervor, wenn man nur drüber fliegt. Ist leider ein kleiner Makel.

18.04.2024 - 10:05 Uhr

In Deinem Query ist absolut keine Besonderheit, die EF spezifisch wäre, sondern das sind halt Operator-Basics von Lambda bzw. Linq - und halt Basics zu C# 😃

Zu beiden Schreibweisen gibt es sehr ausführliche Dokumentationen und Tutorials; wenn Du sagst dass das schwer für Dich ist, dann hast womöglich einfach noch kein Basic Tutorial durch gemacht? Dann hät ichs auch schwer 😃
101 LINQ samples - Code Samples | Microsoft Learn

Ein Oder vor einem Und ist einfach nur

Where( x=> (x == 1 || y == 2 ) && (x == 5 || y == 6 ) )

Also nichts anderes, wie man Conditions in quasi jeder Programmiersprache umsetzt, oder auch in SQL selbst.

Für %DE% benötigst Du EF.Functions.Like() als Methode.

17.04.2024 - 10:28 Uhr

Es gibt ca. 4.3 Milliarden Ini-Implementierung und externe Pakete, die die Ini-Implementierung umgesetzt haben - vielleicht sogar mehr.
Dann such Dir doch davon eines aus, wenn das Verhalten der Win32 API Dir nicht passt...?

17.04.2024 - 09:30 Uhr

Ohne es zu wissen, aber vielleicht sperrt die Win32 API hier einfach die Datei - was auch richtig wäre, wenn intern gecached wird.
Wenn zwei Applikationen zeitgleich schreibend auf eine Datei zugreifen wollen, dann ist das ohnehin ein Fehlerpotential.
Das wäre dann in diesem Fall eher ein Konzeptfehler. Und ich würde so weit gehen, dass Ini-Dateien in aktuellen Anwendungen ohnehin ein Konzeptfehler sind. Die gehören einfach in die Mottenkiste.

Damit könnte das Thema geschlossen werden - ich glaub, das kann ich selber nicht.

wir schließen Themen nicht; könnte ja jemand kommen mit einem ähnlichen Thema.
Was uns noch fehlt ist ein "Thema als gelöst markieren", aber da sind wir dran.

16.04.2024 - 21:18 Uhr

Zitat von EmilDev

Ich habe Richtugung Caching überlegt - ob die ini Values, die ich während der Applikation verändere, irgendwie erstmal gecacht werden, aber bisher noch nichts dazu gefunden.

Hat jemand von Euch eine Ahnung, in welcher Richtung man hier suchen könnte ?

Einfach mal nach GetPrivateProfileString cache suchen, dann siehst schon Treffer, dass das auch wirklich so ist.

Windows caches .INI files to reduce access time. This design allows the file to remain in memory until a different .INI file is loaded or until an application forces recaching of the file.

Mehr dazu hier: Q68827: Updating Cached Private Profiles (.INI Files) | KnowledgeBase Archive (jeffpar.github.io)

16.04.2024 - 10:38 Uhr

Also an dem Code ist einiges zu verbessern. Feedback:

  • verwende string statt String, denn String ist kein Schlüsselwort sondern eine Klasse und kann (und leider wird auch) von externen Bibliothek überschrieben werden / eigene String-Implementierungen kommen mit
  • "GetAwaiter().GetResult()" ist kein korrekter Umgang von async/await. Verwende es einfach richtig? Hier ist GetAwaiter sogar ein Pitfall.
  • Man initialisiert den HttpClient nicht dauernd neu - steht auch als dicke Warnung in den Docs des HttpClient
  • Die Empfehlung seit einigen Jahren ist System.Text.Json zu verwenden und nicht mehr Newtonsoft. Auch das Serialisieren kann direkt der Client effizienter übernehmen.
  • Der Code ist nicht robust und nicht testbar, dafür gibts die HttpClientFactory.
16.04.2024 - 09:56 Uhr

Tipp: verwende Refit als Bibliothek statt den HttpClient direkt.
Nimmt dir 90% der Arbeit mit HTTP APIs ab.


Bei HTTP 400 bekommst du eigentlich eine Server Antwort, was falsch ist, wenn der Server das richtig implementiert hat.
Lass die dir mal ausgeben.

15.04.2024 - 17:53 Uhr

Update zur Architektur:
Seit einiger Zeit haben wir aus einer handvoll Ländern automatisierte Bot und Spam-"Angriffe", weswegen wir diese Länder - aus denen wir quasi keine regulären Zugriffe erwarten - blockiert.

Genaue Details zu Länder und Regel-Implementierung lass ich mal aus Gründen weg.

12.04.2024 - 13:58 Uhr

Prinzipiell gilt: verwende einfach den Konstruktor, wenn Du in einer Projektion eine Klasse initialisierst. Auch wegen solchen Sitationen wurden records eingeführt.
Dann hast Du auch einen entsprechenden Compiler Support, wenn mal eine neue Eigenschaft dazu kommt.

12.04.2024 - 10:50 Uhr

Danke, hat sich letzte Woche eingeschlichen... fix ich gleich.

11.04.2024 - 18:52 Uhr

Zitat von mkolb

warum sollte es mit der EXE nicht gehen?

Das steht direkt in der zweite Zeile meiner Antwort.

Zitat von Abt

Grund: die Verbindung wird nicht durch deine Anwendung eröffenet, sondern durch einen Daemon.
Siehe WCF - Configuring HTTP and HTTPS

Im Kapitel - man sollte alles lesen - kommst Du dann auf Working with NATs and Firewalls
Grundlagen wie WCF und wie die Verbindungsarten funktionieren: Was ist die Windows Communication Foundation?.


Es ging mit Windows10 + WindowsServer2019. Bei Windows11 + WindowsServer2022 wird das wohl blockiert.

Dann hast Du das Loch in die Firewall über einen anderen Weg gebohrt - man kann eben nicht nur Anwendungen direkt freigeben, auch hier gern erneut: siehe Link. Oder die Firewall Regeln wurde eben in der neuen Windows-Version angepasst. Niemand sieht hier, wie Du bisher die Firewall-Regel gesetzt hast und welche Regel bei Dir tatsächlich greift.

Alternativ Google Suche WCF Firewall für mehr Wege und Details, wie das ganze funktioniert. zB WCF - Firewall-Anweisungen

Falsche Firewall-Einstellungen sind 99% der typischen WCF-Probleme, daher ist das auch alles sehr gut dokumentiert.

PS: Gibt es ggf. eine alternative Technik zu WCF?

WCF ist seit ~10 Jahren abgekündigt. Aber WCF ist nur ein Framework. Je nachdem was für eine Verbindungsart Du hast ist für RPC eben gRPC die Alternative bzw. zB REST-basierte Wege für Klartext-Verbindungen.
Die Firewall-Probleme, die es bei WCF aufgrund des Konzepts immer gab, sind eine der mehreren Gründe, dass WCF in seiner Form keine Zukunft mehr hat.

PS: suchst Du im Forum einfach nach "WCF Firewall" findest exakt das gleiche Problem - und auch hier wieder der Hinweis, dass eine Exe in der Firewallfreigabe nicht funktioniert ⇒ WCF und Firewall | myCSharp.de

11.04.2024 - 17:49 Uhr

Also die Exe Deiner Anwendung. Hab ich vermutet - geht bei WCF nicht.
Grund: die Verbindung wird nicht durch deine Anwendung eröffenet, sondern durch einen Daemon.
Siehe WCF - Configuring HTTP and HTTPS

11.04.2024 - 17:10 Uhr

CS1941 sagt eigentlich aus, dass Du im equals versucht verschiedene Datentypen miteinander zu vergleichen.
Dein {Feld1,Feld2} ist streng genommen auch kein Tuple, sondern ein anonymer Typ.

Was mich stark irritiert: Du machst nen Join auf 2 Tabellen, selektierst aber nur aus der zweiten.
Des weiteren macht man das Muli-Field equals eigentlich bei left outer joins, aber da fehlt bei Dir das komplette outer (incl DefaultIfEmpty etc).

11.04.2024 - 15:12 Uhr

Was hast Du in der Firewall freigeschalten, den Prozess oder wie?

09.04.2024 - 21:24 Uhr

Gibt leider keine offizielle Unterstützung für F# und das einzige bekannte Paket ist veraltet, wie Du schon gemerkt hast.
F# Entwickler sind sehr rar, in der Desktop-Welt sogar noch rarer. F# spielt in dieser Welt leider kaum eine Rolle. Man muss aber auch sagen, dass F# halt einfach nicht als Werkzeug für die Desktop-Welt konzipiert ist.

Avalonia bietet aber mit FuncIU eine F# Lösung; auch mit dem moderneren MVU statt MVVM Pattern.
Das wars dann aber leider auch schon an modernen Möglichkeiten.

08.04.2024 - 10:49 Uhr

Das sind Felder:

 public byte val;
 public byte iFlag;
 public string nameStr;
 public byte regNr;

Aber...

  • Felder sind i.d.R. private, weil sie Datenhalden darstellen und nur in ganz gewissen Use Cases Public sein sollten
  • Schreibt man Public Felder wenn dann Groß
  • Im Endeffekt wendest Du C++ Namensgewohnheiten auf C# an

Als Eigenschaften mit C# Regeln wäre das

 public byte Value { get; set; }
 public byte Flag { get; set; }
 public string Name { get; set; }
 public byte RegNr { get; set; }

Felder sehen aus wie Eigenschaften, haben zur Runtime aber eine völlig andere Funktionsweise.

Der Name der Klasse suggeriert für mich jedoch ein Immutable, sodass ein record das richtige wäre, oder eben die Eigenschaften statt set auf ein init.


Im Endeffekt sind Dir die C# Funktionsweisen und Schreibweisen offenbar unklar, sonst würde womöglich das Thema gar nicht existieren. Haben wir alle lernen müssen.

Investier einfach mal ne Stunde in die ersten Seiten der Docs, und Du kennst 80% der wichtigsten Regeln und Funktionen.

07.04.2024 - 21:25 Uhr

a) Visual Studio ist überwiegend in C++ geschrieben b) nutzt VS hunderte von externen Libs c) Visual Studio als Microsoft IDE Produkt hat mit .NET nichts zutun

07.04.2024 - 20:01 Uhr

Leider gefällt mir dieses auch nicht so besonders und vor allem will ich eigentlich nicht von anderen Tools abhängig sein.

Das ist kein Tool, sondern eine Bibliothek. Die gesamte Software-Branche, auch .NET lebt von externen Abhängigkeiten.

Gibt es eine andere einfache Lösung? ohne das man ein Tool installieren muss?

Nein. Diese Funktionalität bringt Dir .NET nicht von Haus aus mit.

07.04.2024 - 20:00 Uhr

In dem Fall kann man RegisterEigenschaften als record definieren.

Dann hast Du a) die Primary Ctor Funktionalität, wie auch b) die Eigenschaften eines immutables.
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/record

PS: wie Du C# Code schreibst zeigt, dass Du allgemein mit den Konventionen und Funktionalitäten (zB Felder vs Eigenschaften) nicht ganz vertraut bist.
Common C# code conventions

04.04.2024 - 11:57 Uhr

Wenn ich eine WPF Anwendung mit .net 8.0 erstelle. gibt es eine Möglichkeit ein Setup für die Installation für die Software zu erstellen, die dann überprüft ob das .net 8.0 Framewort installiert ist. Wenn es nicht installiert ist, das es dann automatisch auf Windows installiert wird.

Das wäre ein Feature eines Installers und hat mit der Anwendung nichts zutun. Musst Dir halt ein Installer suchen, der das kann oder selbst scripten (viele Installer unterstützen quasi "custom rules").

Die Empfehlung seit .NET 5 ist jedoch die Runtime einzubetten ("self contained") und so das gar nicht erst zu benötigen.
.NET application publishing overview

PS: es ist .NET 8 und nicht .NET 8 Framework. Was Du meinst ist auch die Runtime und nicht "das Framework".
[FAQ] Das .NET Ökosystem - .NET, .NET Core, .NET Standard, NuGet und Co


Hab den Titel angepasst, sodass man auch ne Idee hat, worums in dem Thema hier geht.

04.04.2024 - 11:05 Uhr

Auf GitHub wirst Du viele verschiedene Docking-Projekte finden.

Ich möchte aber diese WPF-APP mit Framework 4.7.2 verwenden nur funktioniert das nicht.

.NET Framework ist seit Jahren End of Life. Daher wird das in den meisten Open Source Projekten auch schon seit Jahren nicht mehr unterstützt.

Womöglich musst Du also viel Glück haben was passendes zu finden oder zB Geld in die Hand nehmen, da einige kommerzielle Anbieter weiterhin .NET Framework für ihr Tooling noch unterstützen.