Laden...

Forenbeiträge von Unfug Ingesamt 133 Beiträge

30.01.2022 - 20:56 Uhr

Ok Danke.
Noch Ergänzend:

Dieses Video zeigt auch nochmal sehr genau wie was worum es geht. Kann ich jedem nur empfehlen, der sich damit auseinandersetzen möchte.
Introduction to Comet and MVU - YouTube

30.01.2022 - 16:34 Uhr

Hallo @Abt,

Danke. Im Grunde, glaub ich, kann ich alles nachvollziehen.
Aber eine Nachfrage habe ich doch noch:

MVU ist ja nur ein Pattern und MVVM ist ja auch kein Muss bei WPF. Wieso kann man nicht sagen, dass wenn ich ein Model habe, dass ich an ein eine WPF-View übergebe, dort nur One-Way Binding mache (nur anzeigen) und dann hinter jedem Button/Click eine Methode baue die mir


Model With { Property: NeuerWert }  //Syntax jetzt nur exemplarisch aus Records geklaut. 
RenderKompletteUINeu()

macht, dieses als MVU bezeichnen? Im Grunde ist es doch genau das.
Das kann ich auch auf ASP oder alle anderen Sprachen übertragen. Ich rendere einfach mein ViewModel und jede Änderung führt dazu, dass das Model geupdatet wird und dann wird die UI komplett neu gerendert (statt wie bei Blazor und MAUI MVU nur Teile neu gerendert werden).
In der Theorie ist doch genau das MVU. Oder liege ich hier falsch?.

29.01.2022 - 21:26 Uhr

Hallo myCSharp,

ich hatte die Suche verwendet aber noch kein Thema zum MVU Pattern gefunden.
Um ehrlich zu sein kenne ich die üblichen verdächtigen Seiten. Für mich am einfachsten war das Tutorial.
https://guide.elm-lang.org/architecture/

ELM nutzt ja MVU. Und das kommt jetzt so langsam in MAUI an. Blazor wirkt ebenfalls wie eine Art MVU.

Was ich aber absolut nicht verstehe ist: Wo ist denn die Neuheit? Das mein ich nicht auf eine arrogante Art und Weise, sondern ich verstehe es wirklich nicht.
Für mich liest sich MVU, dass man einfach die UI neu rendert nach jeder Anpassung des Models.
Diese Vorgehensweise gibt es doch schon ewig. Man konnte das auch bei WPF so machen oder Winforms oder ASP.
Und alles in einer Update Methode zu verarbeiten statt mehrere Code Behind EventHandler - ok..meinetwegen. Aber bringt das jetzt wirklich was?
Was Blazor macht ist, nur den Teil neu zu rendern, der sich geändert hat - was ja richtig richtig cool ist. Aber das kann damit ja nicht gemeint sein.

Die Tatsache, dass immer bewusst der Begriff ViewModel wegelassen wird bei den Erklärungen führt zu einer weiteren Frage.
Wenn ich zwei Models habe wie:

Person { Nummer, Alter, Name}
Arbeit {PersonNummer, Position}
und beide in der selben UI verwenden möchte, dann macht es doch einfach Sinn ein ViewModel zu erstellen
ViewModel { Nummer, Alter, Name, Position} und dieses bei MVU zu nutzen. Doch dann wären wir bei MVVMU .

Vielen Dank für eure Erfahrungen und Erklärungen

30.12.2021 - 12:31 Uhr

Klingt irgendwie unsinnig, die Daten, die übertragen werden, bekommt doch sowieso nur der Client zu Gesicht
Oder gehen die Daten an einen anderen Client? Dann ergäbe das mehr Sinn.

Ja. Erneut korrekt. Wir hätten auch alles verschlüsselt übertragen, um dann auf dem Client auszuwerten. Aber auch das war/ist nicht gewünscht. Es sind Vorgaben an denen man sich halten muss. Der technologische Blick hat hier überhaupt keinen Einfluß. Es ist einfach die politische Haltung.

Kein eigener Serializer, die können das doch alle ^^ Aber ja, zumindest so ungefähr, dein Beispiel sind ja ziemlich leicht analysierbar aus.
Der System.Text.Json.JsonSerializer kann auch zum **JsonNode serialisieren, daraus kannst Du dann entfernen, was Du willst **und vom Ergebnis den String erzeugen lassen.

Danke. Das probiere ich mal aus.

30.12.2021 - 12:00 Uhr

Aber kann der Client nicht selber definieren, welche Daten er zurück bekommt?
Dann kann es auch ein potentieller Angreifer machen und die Daten abgreifen.

Ja das ist korrekt.
Der Kunde soll mit Hilfe einer UI in seiner Client Software angeben welche Daten er benötigt.
Zum Beispiel


Mensch.Kind.Spielzeug.Hersteller.Name
Mensch.Kind.Spielzeug.Farbe

Als Filterkriterium gibt er an


Mensch.Kind.Spielzeug.Hersteller.Mitarbeiter > 10

Der Server soll dann die Anfrage auswerten und erzeugt und dann eine Liste mit den ausschließlich benötigten Daten.


List
 1. Hasbro, Blau
 2. Mattel, Grün
 3. Hasbro, Gelb
 4. Habba, Orange

Bevor die Daten den Server verlassen, muss Kunde 2 den Versand bestätigen.

Theoretisch ist es möglich, dass "versteckt" auch andere Daten abgegriffen werden vom Client, aber dafür gibt es entsprechend Verträge.

Und wie Du die Rückgabedaten aufgebaut werden, hängt davon ab, wie ihr Aufbau festgelegt werden soll.
Suchen und zusammensammeln genauso wie sonst auch und beim Zurückgeben lässt Du das JSON nicht automatisch erzeugen, sondern machst es per Reflection selber, aber mit deinen Regeln. Bei Newtonsoft.Json ist das einfach, wie es bei System.Text.Json geht, weiß ich aber nicht.
Vorausgesetzt Du verwendest ein System, was sowas erlaubt, mit ASP.NET Core ist das jedenfalls kein Problem.

Ja ist alles im C# ASP.NET Core Universum. Du meinst einen eigenen Serializer bauen? Der basierend auf einem Dictionary das korrekte Property raussucht und dann dem JObject hinzufügt?

30.12.2021 - 11:31 Uhr

JSON - bau das JSON selbst zusammen, dann hast Du maximale Freiheiten

Aber warum eigentlich? Warum muss das Ergebnis so genau spezifiziert werden?
Überleg dir, welche Daten üblicherweise zusammen gehören und liefere die immer als Ganzes zurück, die Client kann sich ja das raus picken, was er braucht.

Danke für deine Antwort. Um deine Fragen zu beantworten: Aus datenschutzrechtlichen Gründen. Jede Anfrage/Job die gestellt wird verlangt bestimmte Daten zurück, die vorerst genehmigt werden. Es ist also nicht erlaubt das komplette Datenmodell zurückzuliefern und dann auf dem Client zu filtern. Client und Server sind unterschiedliche Firmen.

Bzgl. JSON: Wie würdest Du denn beim Server die Daten zusammensuchen und dann setzen, falls man nur ein bestimmtes Property übertragen möchte alle anderen aber nicht?

30.12.2021 - 11:03 Uhr

Hallo zusammen,

ich hoffe Ihr hattet ein schönes Weihnachtsfest. Ich habe eine Frage die mich derzeit beschäftigt und ich auf keinen grünen Zweig komme. Vielleicht könnt ihr mir hier wieder ein paar Denkanstöße geben.

Gegeben ist eine feste Datenstruktur auf Serverseite, die mit dynamischen Anfragen (Rest?) abgefragt werden soll. Neben dem Filter soll auch mitgegeben werden, was zurückgeliefert werden soll.

Etwas technischer

Client - Server Architektur.

Der Server verwaltet eine Datenstruktur die relativ komplex ist.
Als Beispiel ein Datenmodel:


Mensch
  Kind
      Spielzeug
             Preis
             Farbe
             Hersteller
                     Name
                     Herkunftsort
                     Mitarbeiter

Die Tiefe der Propertys ist enorm. Es sind Listen dabei, einfache Arrays, String, Int etc etc.

Nun ist folgendes geplant:
Der Client sendet eine Anfrage an den Server wie z.B.
"Liefere mir nur den Preis und die Farbe von allen Daten bei denen der Herstellername: Hasbro und Mitarbeiter > 10 ist"
UPDATE: Vermutlich wird es einen Job geben, der abgerufen wird vom Server der diese Anfrage beinhalten soll. Die Jobs werden dann regelmäßig vom Client abgerufen

Ich möchte also als Rückgabewert:


Preis
Farbe

Zusätzlich kann es sein, dass diese Anfrage noch manuell über ein UI erweitert werden muss.


Preis
Farbe
Größe (muss manuell per UI Eingabe hinzugefügt werden)

Worin liegt nun mein Problem: Die Datenstruktur des komplexen Datenmodels bleibt immer gleich, aber die Anfrage muss dynamisch sein. Der Abfragefilter soll vom Endbenutzer angepasst werden aber auch die gewünschten Rückgabewerte
So könnte die Anfrage (siehe oben) die selbe sein, aber diesmal als Rückgabewert nur


Herkunft

sein.

Was ich bisher ausprobiert habe/gelesen habe:
Für die Anfrage:
OData
eigenen Query Parser
GraphQL

Für die Rückgabe:
GraphQL

Mit GraphQL habe ich mich nicht wirklich beschäftigt. Sieht für mich nach viel Hirnschmerz aus, wenn ich mir die Beispiel anschaue.
Doch sollte dies eine Lösung sein eurer Meinung, werde ich das natürlich tun. Was ich dann nur nicht verstehe ist: Wie muss ich meine Datenstruktur aufbauen, z.B. im Client, der die Antwort erhält.
Ein Dictionary?
Wie kann ich denn im Server die Anfrage verarbeiten? Automatisch, dass ich nur bestimmte Propertys dann zurückliefere.

Freu mich über jegliche Denkanstöße.

Allen noch ein guten Rutsch

27.06.2021 - 13:23 Uhr

Guter Tipp. Habe mit Reactive Extensions noch nicht gearbeitet. Kann das jetzt mal als Einstieg nutzen.

Das mit dem Thema State vs Business Objekte kann ich 100% nachvollziehen.
Hatte nämlich genau das Problem bei den Tests.

Aufjedenfall vielen Dank an alle. Es gab viele Anregungen, die ich jetzt testen werde. 👍

27.06.2021 - 11:10 Uhr

Danke. Ja natürlich..das mit der Referenz .. Kopf auf den Tisch hauen. Manchmal sollte man wirklich früher ins Bett.

T-Virus:
Die Idee dahinter ist Nutzung eines sehr einfachen Eventbus wie diesen hier:
https://github.com/mxjones/RedBus
Globale Events, sollen dazu führen, dass in den Objekten verschiedene Methoden ausgeführt werden.
Es sollen als Subscribe Object.Funktionen übergeben werden die aufgerufen werden sollen.
Wenn das Object zerstört wird, dass ein EventBus.Subscribe ausgeführt hat, soll das auch aus dem Dictionary gelöscht werden, damit kein Callback hier aufgerufen wird.

27.06.2021 - 10:23 Uhr

Hallo zusammen,

ich stehe derzeit auf dem Schlauch und hoffe, dass Ihr mir weiterhelfen könnt. Hab eine Denkblockade.

Ich füge als Value eines Dictionary ein Objekt der Klasse TestClass hinzu.
Im weiteren Verlauf setze ich dieses Objekt auf null.
Im Dictionary ist jedoch die Kopie?!/Referenz?! noch vorhanden. Ich dachte wegen Call by Referenz müsste das auch Null sein.
Geht das nicht beim Dictionary? Was wäre eine Alternative?


Dictionary<string, TestClass> list = new Dictionary<string, TestClass>();
TestClass? myclass = new();
list.Add("1", myclass);
myclass = null; //ab hier hätte ich gedacht, dass der Wert auch im Dictionary null ist.

list["1"].EineMethode(); // <<< wieso klappt das?

public class TestClass
{
	public string EineMethode()
	=> "Hello World";
}


Im echten Code übergebe ich keine TestClass, sondern Func<T,Task>.
Danke

21.04.2021 - 21:44 Uhr

Das liegt daran, dass das i nicht beim durchlaufen des for loops "ausgeschrieben wird".

application[1]
application[2]

sondern erst beim draufklicken ausgewertet wird.
Und das ist dann application.count ++;

Lösung 1:
eine lokale variable innerhalb der for


var lokal_i = i;
application[lokal_i].Name

Lösung 2:
foreach nutzen.

16.04.2021 - 09:57 Uhr

Ich bin nicht sicher, ob es das ist was Du suchst:
Aber ich habe vor ca 6 Jahren mal etwas umgesetzt, dass abhängig von der Auswahl anders dargestellt werden musste.
Dafür habe ich DataTrigger eingesetzt. Diese DataTrigger funktionieren wie If Anweisungen
Trigger, DataTrigger & EventTrigger - The complete WPF tutorial

Und das Zweite ist:
Um im Code die UI zu Aktualisieren habe ich diesen Code


   Dispatcher.Invoke(() =>
                {
                    
                    this.MeineTextBox.Text = "hello mycsharp";
                    UpdateLayout();
                });

verwendet.

11.04.2021 - 22:24 Uhr

Hallo zusammen,

ihr habt beide vollkommen recht und es ist auch genau wie ihr es beschrieben habt.
Es ist ein Monster Datenobjekt.

Ich hatte auch erst gedacht ein DataTransferObjekt zu bauen. Allerdings ist das wirklich unmöglich. Ich brauche nämlich so viel von dem Objekt, dass man dann direkt über ein neue (moderne) Architektur nachdenken sollte.
Der Aufwand wäre dann der gleiche.

Ich danke euch aber. Eure Gedanken werden mich dazu bringen nochmal grundsätzlich darüber nachzudenken (ggfs. auch mit dem Kunden).

Gute Nacht
Unfug

11.04.2021 - 14:16 Uhr

Hallo zusammen,

ich brauche Hilfe bei einem Problem. Und zwar folgendes:

Ich habe eine Library welche mir bereitgestellt wurde.
In der Library (äußerst komplex und alt, aber inzwischen auch netstandard) wird ein C# Objekt erzeugt, dass ich in einer entfernten Anwendung benutzen muss.

--SERVER A erzeugt dieses Datenobjekt aus der Library. Das Datenobjekt wird durch unzählige Datenbank Abfragen und Service Anbindungen gefüllt. Das Datenobjekt wird in der Library auch dafür benutzt, dass bei Änderungen diese zurück in die Datenbank / Services fließen.

--SERVER B benötigt das erzeugte Datenobjekt für die Weiterverarbeitung.

Im Grunde muss ich also das Datenobjekt von A nach B transportieren und ggfs. auch zurücksenden.

Was habe ich bereits getestet:

  1. Das Datenobjekt in JSON umwandeln, um es über REST zu senden
    Fehlgeschlagen, da interne Propertys wie Dictionarys nicht in JSON umgewandelt werden können.

  2. Das Datenobjekt mittels BinaryFormatter serialiseren, um es als STREAM zu senden
    Fehlgeschlagen, da nicht alles als serializeable markiert.

  3. Ich dachte erst gRPC wäre eine Möglichkeit. Allerdings muss man hier ja die Datentypen (Messages) noch selbst aufbauen und das Datenobjekt ist zu komplex dafür. Es hat unzählige Properties, die unzählige NestedProperties haben. Also ich sag mal .klassisch Objektorientierung.

Hat jemand eine Idee wie man sowas lösen könnte? Ich kann/darf die Library nicht verändern.

Danke
Unfug

14.09.2020 - 13:43 Uhr

Vielen Dank.

Das hat mir schon viele neue/alte Denkanstöße gegeben.

Werde schauen, dass ich es dann mal mit der Variante austeste, dass ich die Rohdaten und zusätzliche die weiteren Formate speichere.

Danke

13.09.2020 - 20:05 Uhr

TLDR: Unterschiedliche Datenquellen mit Millionen Datensätze in einem ViewModel, verschiedene Verarbeitungsklassen, verschiedene Exportformate. Parsen, Rohdatenspeicherung, Vorgehensweise gesucht.

Hallo zusammen,

ich habe heute folgendes Problem, worüber ich mir seit ein paar Tagen den Kopf zerbreche.

Das Problem ist wie folgt:
Ich erhalte aus verschiedenen Datenquelle komplexe Datenstrukturen ca. 10 Millionen pro Monat.

Mit Komplex ist insbesondere gemeint, dass diese Datenstrukturen aus unterschiedlichen Datenbanken abgeleitet wurden und eine Vielzahl unterschiedliche Datentypen beinhalten, die wiederum Propertys bis in die 5 Ebene haben. Doch diese unterschiedlichen Datentypen hängen auch wieder zusammen. Zu identifzieren an Property Werten.
Manchmal ändert sich nach einigen Tagen ein Property was bedeutet, dass ein Merge gemacht werden muss (kein ersetzen. Es muss klar sein, dass sich etwas verrändert hat).

Am Ende des Tages bilden alle jedoch das Selbe ab.

Man stelle sich exemplarisch (hat überhaupt nichts damit zu in Wirklichkeit zu tun) vor es gehe um Rechnungen.
Jede Quelle definiert eigene Typen für die Rechnung, eigene Enums, eigener Text, eigene Währungen ... trotzdem ist es am Ende ...eine Rechnung.

Nun geht die Geschichte auch weiter

Obwohl die Quellen unterschiedlich sind, die Datentypen komplett anders, gibt es Überschneidungen. Ich muss also aus den unterschiedlichen Quellen und Daten in der UI eine Ansicht machen.
Die dargestellten Daten müssen dann in fachlichen Methoden verarbeitet und ausgewertet werden.
Zum Schluss: Export. In verschiedene Datenformate. Auch in Formate, die ich aktuell noch nicht kenne.

Worauf ich also hinaus möchte : Wie wäre hier eine gute Strategie? Meine Überlegungen:

  1. Die Rohdaten speichern und dann nur im Speicher die benötigen Klassen berechnen für die Anzeige?
    pro: Schnell zu entwickeln. Rohdaten zu haben ist immer gut. Jede Änderung in den Rohdaten würde als neuer Rohdatensatz gespeichert.
    cons: Die Berechnung wird mehrere Minuten dauern, da jeden Monat mind. 10 Millionen Datensätze hinzukommen.

  2. Ein gemeinsames Datenformat definieren. Rohdaten beim Abrufen in dieses parsen und speichern.
    pro: Angepasst auf die derzeitigen Anforderungen
    cons: Nicht alle Felder werden übernommen und könnten für immer verloren gehen. Spätere Exportformate könnten ggfs. nicht umgesetzt werden

  3. Rohdaten speichern und ein gemeinsames Datenformat
    pro: Je nach Anwendungsfall liegen konkrete Daten in der Datenbank vor
    cons: Datenbank wächst enorm. (Manche würden sagen Redundanz wäre ein Cons)

Die Datenbankgröße macht mir eigentlich keine Sorgen, jedoch die Performance an sich aber auch die Klassenstruktur, dass man den Überblick verliert.
Vielleicht sehe ich den Wald vor lauter Bäumen nicht. Aber wie würdet ihr hierbei vorgehen? Wie verliere ich jetzt nicht den Überblick und behalte aber die Möglichkeit zukünftige Anforderungen sauber abzudecken, welche sich auf die Rohdatenstrukturen beziehen?

Danke

22.05.2020 - 17:08 Uhr

Hallo zusammen,

unsere Kunden wünschen sich immer wieder, dass unsere Produkte als OpenSource verkauft werden.
In der Regel wird die Software als Closed Source geliefert und der Kunde kann, je nach Vertrag, dann die Software verwenden (Resellern, OnPremise , Auf 10 Servern etc etc).

Jetzt haben wir aber auch Kunden, die gerne individuelle Lösungen sich wünschen bei denen dann aber unsere Basissoftware die Grundlage ist.

Die Gründe warum ein Kunde Opensource haben möchte sind vielfältig:
a) Sicherheit der IT (eigene Audits)
b) Sicherheit bei Insolvenz
c) Möglichkeit der Weiterentwicklungen von Drittanbietern oder durch eigene Mitarbeiter

Es spricht generell nichts dagegen OpenSource bereitzustellen. Das Problem ist jedoch, dass ein großer Teil unserer Arbeit auf unseren Bibliotheken basiert. Also im Grunde können wir unsere Mitarbeiter nur bezahlen, weil wir mit diesen Bibliotheken überhaupt die Wünsche der Kunden erfüllen können. Die Umsetzung der Bibliotheken war auch nicht gerade billig.

In unseren Verträgen könnte man einbringen, dass es verboten ist, die Bibliotheken öffentlich zugänglich zu machen.
Aber was ist, wenn die Firma gehackt wird? Was ist, wenn Mitarbeiter sich entscheiden den Code doch anders als vertraglich vereinbart zu verwenden? Auf große Prozesse haben wir wenig Lust. Man müsste ja selbständig alles nachweisen.

Hat jemand schon Erfahrung damit ? Wie geht ihr damit um?
Gibt es Empfehlungen?
Unfug

17.03.2020 - 10:44 Uhr

@Abt: Um Gotteswillen! Ich würde hier ja nicht nachfragen, wenn ich so ein Verhalten an den Tag legen würde. Es geht mir ja darum, Neulinge noch besser an die Hand zu nehmen und nicht nur durch Erfahrungen zu profitieren - daher ja die Nachfrage nach Best Practice.

@herbivore:

Sondern dass man ganz im Gegenteil alles daran setzen sollte, zu beweisen, dass in der Methode noch Fehler sind.

Schöner Gedanke. So habe ich es ehrlich gesagt noch nie gesehen. Die Tatsache, dass man den Blickwinkel auf einen UnitTests ändert, eröffnet durchaus neue Ideen.

16.03.2020 - 16:01 Uhr

Hallo zusammen,

Danke für die Antworten. Ich bin absolut nicht gegen UnitTests. Im Gegenteil.
Hätte nur gedacht hier gibt es Best Practice Erfahrungen, die einen noch besser helfen.

Oft sind die UnitTests ja sehr klein und granular gehalten, aber dann wiederum nicht immer ausreichend. Gerade wenn ich komplexe Objekte in komplexen Methoden teste...eieiei.

Ich finde die Aussage von ABT:

Testen ist genauso Programmieren wie produktiver Code.
Und dazu gehört genauso Erfahrung wie zu allen anderen Bereichen.

eigentlich perfekt. Es würde aber auch bedeuten, dass man dem Neuling nichts an die Hand geben kann außer: Lerne aus Erfahrungen.
Dachte hier gibt es ggfs. mehr Ansätze.

15.03.2020 - 19:26 Uhr

Hallo zusammen,

wir stellen uns die einfachste Variante vor:

Chef zu Neuling: Mach ein Registerformular, 2 Felder. Email und Passwort.

Neuling programmiert:

Register(string email, string passwort)

Tester:

Register("haha", " ")

Neuling: Ok...jetzt mit Prüfung

Register(string email, string passwort)
{
email muss @ und . haben
passwort darf nicht leer sein
}

Tester:

Register(" M ail+@harhar.de"," lere bi ich nicht°1")
...
...

Never Ending Story.

Meine Frage: Unittests wären hier nicht zielführend für den Neuling gewesen, denn der Code und die Tests würden irgendetwas übersehen. Bei 100 Abdeckung wären die Tests nur für die Email kilometerlang.
Alles mit Regex prüfen ? Was ist bei komplexen Datenobjekten?

Wie kann man derartige "Einschränkungen" direkt mitgeben und vor allendingen testen?
Im Web kennen wir Validierungen, wo die Regeln teilweise auch kilometerlang sind. Gibt es hier nicht elegantere Lösungen?
Gerade, wenn man mit Endanwendern arbeitet, die finden immer etwas - aber immer dann wenn etwas produktiv geht.

Danke

27.11.2019 - 15:23 Uhr

Habe mir Application Insights angeschaut...da brauch ich wohl nochmal ein Studium.
Das ist ja super umfangreich.

Das mit den Health API überprüfe ich als nächstes.
Falls ihr noch andere kennt..her damit.

26.11.2019 - 19:15 Uhr

Danke ..schaue ich mir aufjedenfall mal an.

26.11.2019 - 18:05 Uhr

Hallo zusammen,

ich habe eine kleine Frage und zwar haben wir mehrere Webseiten auf Basis von ASP.NET Core im Einsatz aber auch PHP oder irgendwelche Console Applicationen.

Verschiedene Hoster sind im Einsatz.

Was ich gerne aus Entwicklersicht sehen würde, wäre ob alles optimal läuft:
Funktioniert der Zugriff auf die Datenbank
Wie hoch ist die Auslastung (ggfs. auch Anzahl Zugriffe etc).
Gab es eine Exception etc.
Normales logging das ich manuell eingebaut habe wird angezeigt und gespeichert.

Nun...Eigentlich das übliche.

Gerne würde ich für eine derartige Überwachung ein Tool nutzen, welches ich über eine API anbinde. Ich würde dann eigene Background Tasks schreiben, die gegen die API regelmäßig sprechen.

Nagios ist so das allererste was man hört und liest.
Mein Wunsch wäre es jedoch: So einfach wie möglich. Nuget hinzufügen,--> IP, API Code eingeben und irgendeine Library haben, die es mir nun ermöglicht so etwas zu machen:

Tool.Log("juhu")
Tool.Status("Datenbank", "läuft")

Gibt es soetwas, habt ihr etwas im Einsatz und könnt ihr was empfehlen?
Kosten darf es auch was. Bin hier offen.

Danke

Unfug

21.07.2019 - 17:51 Uhr

Auf keinen Fall den Cache dafür missbrauchen! Absolutes No-Go!
Die Session könnte man dafür nehmen, aber viele Einträge in einer Session und viele Benutzer führt schnell zum Memory-Limit einer Webanwendungen.

Gibt es dazu eine einfache Erklärung warum?
Bei MS steht zwar auch, dass Apps nicht vom Cache abhängen sollten/dürfen, aber vielleicht hast Du ja eine weitere Aussage.
https://docs.microsoft.com/de-de/aspnet/core/performance/caching/memory?view=aspnetcore-2.2

21.07.2019 - 14:29 Uhr

Danke. Ja klingt gut.
Ich probier es mal aus

21.07.2019 - 11:44 Uhr

Danke,

also ich müsste dann irgendwie, z.B. durch Hidden Values, es hinbekommen, dass ich das Formular + Submit eindeutig identifzieren kann und einen Status setze
z.b. "abgesendet, fehler, abgeschlossen"

Also dies dann z.B. in einer Datenbank zwischenspeichern.

Soetwas?

21.07.2019 - 10:24 Uhr

Hallo zusammen,

ich habe schon die Suche genutzt, habe aber nichts passendes gefunden. Wahrscheinlich ist es zu einfach und ich sehe den Wald vor lauter Bäumen nicht.

Genutzt wird ASP.NET Core Razor Pages

Es geht darum, dass ich ein Formular auf einer Webseite haben, dass einige Daten als POST übergibt.
In dieser Methode wird ganz viel berechnet auf Basis der Eingaben. Die Post Methode selbst braucht fast 5-10 Sekunden um alles durchgerechnet zu bekommen. Wenn alles passt, wird gespeichert, ansonsten muss der Benutzer seine Eingaben korrigieren.

Das Problem ist, sobald der Submit Button im Formular gedrückt wird, kann ein Benutzer mehrfach auf Submit drücken. Simulieren kann man das, indem man z.B. einfach ein Task.Delay(10000) in die POST Methode einbaut.

Clientseitig kann ich den Submit Button "deaktivieren" per Javascript, jedoch gibt es für diese spezielle Seite Benutzergruppen, die Javascript nicht erlauben und auch per Internet Explorer surfen.
Ich muss aber auch serverseitig unterbinden, dass z.B. jemand über Tools versucht mehrfach Submits durchzuführen.

Meine Frage: Wie kann ich das machen bzw. habt ihr Erfahrung damit?

Schöne Grüße und Danke

18.02.2019 - 14:42 Uhr

Hallo,

Danke. Also im Prinzip wirklich die Datenstruktur erweitern um Felder, die dann dazu genutzt werden die Gruppen zu managen. Also das was aktuell noch im Vorfeld passiert entsprechend direkt auf Datenstruktur Ebene

ID|Wert1|Wert2|Mitarbeiter ID|ZugeteiltAm|AbgeschlossenAm|InArbeit(true/false)|StatusGeprüft|

Programmatisch müsste ich dann noch sicherstelen, dass die Abrufe nicht gleichzeitig stattfinden, sondern sequentiell, da ich ja erst ein SELECT WHERE InARbeit=false ist, dann ein UPDATE SET InArbeit=true mache.

Soweit korrekt?
Klingt eigentlich plausibel und einfacher als gedacht.

17.02.2019 - 23:46 Uhr

Hallo,

erstmal Dank.

Zur Automatisierung:
Es handelt sich in der Tat um einen bewussten manuellen Prozess. Die Daten benötigen teilweise menschliche Interpretationen, da einige Informationen unvollständig/fehlerhaft sind. Die Mitarbeiter haben aber die Möglichkeit in anderen (nicht IT zugreifbare) Quellen nachzuschauen.
Auch kann es sein, dass einige Daten fehlerhaft bleiben und trotzdem als geprüft/gültig angesehen werden.

Als ITler wünscht man sich natürlich mehr Automatisierung. Allerdings ist es schwer einen existierenden Prozess an denen 20 Mitarbeiter arbeiten derart zu ändern.

Zu den Daten:
Es handelt sich um eine sehr flache einfache Struktur.


|ID|Wert1|Wert2|Wert3|Wert4

Die Gruppierung ist eine rein programmatische Sache.
Nehme ID 0 bis 1000 => Gruppe 1
Nheme ID 1001 bis 2000 => Gruppe 2
Die Gruppen kommen dann in einen Cache und können so jedem Mitarbeiter zugeordnet werden. Nach Abschluß passiert dann einfach

foreach(datensatz in Gruppe)
{
Update in MSSQL(datensatz)
}

Leider kann ich nicht mit konkreten Datensätzen kommen. Ich hoffe es ist etwas klarer geworden.

Danke

17.02.2019 - 19:37 Uhr

verwendetes DatenbankHsystem: <mssql>

Hallo zusammen,

ich hänge derzeit bei einem Problem was mit konkurrierende Zugriffen zu tun hat.

Der Ablauf ist relativ einfach.

Daten werden aus einer MS SQL gelesen, diese werden geprüft und entsprechend mit einem aktualisierten Flag - geprüft - zurück in die SQL geschrieben.

Es handelt sich um Millionen von Datensätze, die manuell durch mehrere Mitarbeiter gleichzeitig geprüft werden.

Die derzeitige Vorgehensweise ist wie folgt:
Programmatisch aber auch in der UI werden die Datensätze in Gruppen aufgeteilt (1-1000). Jede Gruppe besitzt demnach tausende Datensätze.
Die Mitarbeiter untereinander sprechen sich ab, wer welche Gruppe nimmt und bearbeitet jene.
Hierfür werden bewusst programmatisch diese Gruppen erstellt und in einen Cache gespeichert.

Das ist alles sehr unschön, sowohl programmatisch als auch in der UI, als auch im Ablauf. Ohne Absprache geht hier nichts.
Ich suche nach einer eleganten Lösung ohne diese Gruppen.
Wichtig ist vielleicht noch zu sagen, dass die Reihenfolge der Datensätze idealerweise beibehalten wird. Also Random Pick aus der Datenbank ist nicht möglich. Auch werden aktuell die tausende Datensätze auf einer Seite angezeigt, da das Prüfung teilweise nur ein paar Sekunden pro Datensatz benötigt.

Mir fällt derzeit nichts schlaueres ein. Euch?

Danke

30.05.2018 - 18:27 Uhr

Ach sorry.

Ja genau ein Pass-Through.

Die Infrastruktur für Benutzerverwaltung läuft schon länger. Ist eine klassische Rest API.
Es gibt nur eine Schnittstelle die das Anmelden Name+Passwort erlaubt. Bei dem Rest muss immer der Token (bearer) mitgesendet werden.
Bei den Aufrufen wird dann entsprechend reagiert, ob der Benutzer das darf oder nicht.

Es gibt 2 UIs derzeit. Eine PHP Anwendung sowie eine .NET WPF. Bei der PHP kann ich nicht sagen wie, jedoch bei der .NET WPF wird der Token einfach in den Header vom HTTPClient hinzugefügt (auch mit "bearer {token}").

Die Razor Page Core soll sozusagen wieder nur eine UI darstellen.
In den Razor Pages Codebehind soll dann wieder per Rest Call abgefragt werden, ob der Benutzer überhaupt auf diese Seite zugreifen darf.

Danke

Update 31.05.18:
Inzwischen bin ich etwas weiter. Und zwar scheint es doch üblich zu sein den Token bei dieser Variante in ein Cookie zwischenzuspeichern.
Laut "Internet" macht es auch Stackoverflow so.
Ich habe es mal getestet und es scheint auch gut zu klappen.



  var cookieOptions = new CookieOptions
                {
                    Expires = DateTime.Now.AddMinutes(10),
                    //HttpOnly = true  // javascript zugriff auf das cookie wird blockiert
                };
  Response.Cookies.Append("meinToken", Token, cookieOptions);


In den Actions selbst habe ich dann Abfragen wie :


 var token = Request.Cookies["meinToken"];
 CheckAuthoriziation(token);

Das funktioniert auch alles soweit. Wenn ich die Berichte so durchlesen, dann gibt es aber nicht "die perfekte Lösung". Ob Cookie Session oder Storage (Local, WebStorage). Alle Varianten weisen theoretische Sicherheitslücken bedenken auf.

30.05.2018 - 16:54 Uhr

Hallo zusammen,

ich beschäftige mich gerade mit der Frage wie man einen Token bei Razor Pages Core im Header des Clients setzen kann.

Im Prinzip ist der Ablauf wie so oft: Benutzer meldet sich an und erhält einen Token. Dieser Token wird dann jedem Request vom Client übertragen.

Da der Token bei jedem Aufruf im Header mitgesendet werden muss, macht es natürlich Sinn diesen clientseitig zwischenzuspeichern.

Sind Cookies dafür weiterhin geeignet? Doch wie bekomme ich die dann in den Header?
Oder gibt es elegantere Wege?
Die Razor Pages sind übrigens nur eine weitere Ansicht. In de Desktop Anwendungen, welche auf die gleiche API später zugreifen wird einfach im HTTPClient der Token gesetzt.

Danke

22.04.2018 - 23:24 Uhr

Ach danke.
Das probiere ich gleich mal aus. Da hätte ich mir ja die ganze Arbeit sparen können.

22.04.2018 - 09:54 Uhr

Hallo zusammen,

mir fiel leider kein passender Threadtitel ein. Es geht darum, dass ich derzeit folgendes Szenario versuche:

  1. Laden eines Filestreams
  2. Daten verschlüsseln
  3. Daten übertragen

Was derzeit funktioniert ist, dass ich z.B. eine Datei lade, die Bytes auslese, verschlüssel und wieder speichere als Datei.

Jetzt könnte ich die verschlüsselte Datei wieder Laden und übertragen.

Mein Ziel ist es aber, dass dies on-the-fly geschieht.

Ich habe folgendes bisher (vereinfacht):


    using (var stream = new FileStream(@"c:\temp\test.pdf", FileMode.Open))
    using (var encryptedstream = new MemoryStream())
{
 Encrypt(stream, encryptedstream);
 Übertrage(encryptedstream);
}

Idee war, dass ich in Encrypt den Memorystream übergebe und der Memorystream solange gefüllt wird bis das Auslesen der Datei beendet ist. Parallel sollte dann in Übertrage() die bereits verschlüsselten Bytes übertragen werden.

Lasse ich die Verschlüsselung weg und übertrage nur den stream funktioniert auch alles.
Sobald ich aber den encryptedstream übertragen möchte, läuft der unendlich lang bzw. bis zum Timeout.

Innerhalb von Encrypt wird ausschließlich das hier gemacht


  var key="testkey";
  var iv = "testiv;
   byte[] buffer = new byte[1024];
            while (stream.Read(buffer, 0, buffer.Length)>0)
            {
               var encryptedbuffer = EncryptToAES(buffer, key, iv);
                encryptedStream.Write(encryptedbuffer, 0, encryptedbuffer.Length);

            }
            return encryptedStream;

Auf der anderen Seite kommt auch ein Stream an mit der korrekten Content.Length. Allerdings scheint die Übertragung nicht durchgeführt zu werden.

Ich sehe glaube ich den Wald vor läuter Bäumen nicht.

Danke

UPDATE:
Kleines Update am Rande. Das Problem, dass die verschlüsselten Daten generell nicht übertragen wurden lag daran, dass der Positionszeiger des encryptedstream bei encryptedStream.Write mit hochgezählt wird.

Sobald man:
encryptedStream.Position = 0;
setzt. Werden auch die Daten übertragen. Ich vermute, dass man jetzt einen temporären Counter für die Position benötigt.
Da eine Stelle in den Stream reinschreibt und die andere ausliest, benötigt man sozusagen 2 Positionen.

Ich werde das später nochmal genauer testen und hier Feedback geben.

23.12.2017 - 21:16 Uhr

Wir nutzen auch

  var pbkdf2 = new Rfc2898DeriveBytes(password, salt, HashInterations);
            return pbkdf2.GetBytes(OutputBytes);

.
aus System.Security.Cryptography

Weil es mal von NIST als Empfehlung gesetzt wurde. Ebenfalls mit 10.000 Iterationen.
Ob der BSI auch solche Angaben macht, weiß ich grad nicht.

11.12.2017 - 09:53 Uhr

Morgen,

ich habe mal für ein Addin folgende Library genutzt. Das hat super funktioniert.

https://github.com/NetOfficeFw/NetOffice

Es gibt von Microsoft auch die eigene Erweiterung mittels vsto:
https://msdn.microsoft.com/de-de/library/cc668191.aspx

Ich hatte persönlich aber schlechte Erfahrungen, weil es sehr stark Versionsabhängig war.

Gruß

p.s: hier die Doku.
http://netoffice.codeplex.com/wikipage?title=Outlook_Examples_EN

10.12.2017 - 22:45 Uhr

Dann lag ich wohl nicht ganz falsch mit meinen Äußerungen und bisherigen Erfahrungen.
Gerade was BusinessLogik anging hatte ich auch immer ein etwas mulmiges Gefühl.
Das Buch selbst z.B. spricht auch gar nicht mehr von Architekturen und Entwürfen. Man müsse quasi sich alles wegdenken und rein auf Funktionen denken, die miteinander kombiniert werden.

Das fand ich interessant - aber irgendwie auch schwierig umzusetzen.

Ich denke ich schaue mir jetzt einmal F# an anstatt C# mit externen Libraries umzubauen. Und dann versuche ich, wie ihr beschrieben habt F# mal in C# zu nutzen, wenn es möglich ist und Sinn macht (z.B bei Daten).
Ich denke damit habe ich einen guten Anfang und erstmal was zu tun.

Schönen Dank

10.12.2017 - 19:34 Uhr

Danke für eure Antworten.

Ich meinte natürlich überwiegend statische Klassen in denen dann die statischen Funktionen aufgelistet sind. Objekte werden als States benutzt. Wobei das ja auch nur Objektinstanzen sind. Ändert man ein Property wird davon aber ein neues Objekt zurückgeliefert statt das Objekt selbst.

@Abt, so ähnlich sehe ich es auch. Aktuell, wird bei uns einfach (erneut) wieder diskutiert mehr FP mit c# zu nutzen, weil es ja so toll ist.

Um ehrlich zu sein, weiß ich nur nicht was ich davon halten soll, dass ich statische Funktionen habe. Da die Funktionen keinen direkten Objekt Bezug mehr haben, könnte man eine einzelne .cs Datei erstellen in der dann Funktionen sind wie

int macheDies(Type1 typ)
string machedas (Type2 typ)
IEnumerable<T> unddas (type3 typ)

Ist das wirklich schön? Gerade bei einer Anwendung, die dann ggfs. 100 oder gar 1000 tausende Methoden hat? Das kann doch nicht richtig sein oder? Ich muss da doch etwas übersehen haben.

F# gucke ich mir aber aufjedenfall auch nochmal an. Vielleicht ist das die Besserung Lösung. Jeder der will kann f# nutzen, die anderen c# und dann kombiniert man das anstatt C# "aufzumotzen" wofür es ggfs nicht entwickelt wurde.

Danke

10.12.2017 - 11:27 Uhr

Guten Morgen zusammen,

Ich habe eine Frage an die Experten hier bzgl. Funktionaler Programmierung. Ich habe schon gesehen, dass einige hier sehr interessante Aussagen gemacht haben. FP ist ja eigentlich nichts neues, doch scheint es aktuell wieder in meinen Kreisen zu neuen Leben gefunden zu haben.

Ich habe mir auch ein paar Informationen und Bücher geholt.
Ich verlinke einfach mal das Buch: https://www.manning.com/books/functional-programming-in-c-sharp
(Bitte löschen von Mod, falls Hinweis nicht erwünscht).
Zu diesem Buch gibt es auch eine 1:1 Library. Die Language-Ext.
Und genau damit beschäftige ich mich derzeit.

Die grundlegenden Prinzipen von FP:

  • Jede Funktion liefert einen Wert zu zurück (kein Void).
  • Funktionen nutzen keine globalen Objekte oder verrändern Daten außerhalb der Funktion
  • Versuchen so viel wie möglich mit Immutable zu realisieren.
  • Definieren von allgemeingültigen Funktionen und BusinessLogik durch Delegates hinzufügen. (Beispiel wie bei : Linq.Where)

habe ich auch soweit verstanden und setze ich eigentlich auch seit Ewigkeiten um. Delegates und Linq gibt es ja schon seit Ewigkeiten.

Nun geht der Author noch einen Schritt weiter.

  1. Es werden statische Funktionen und Klassen genutzt für jeden und alles
  2. Funktionen werden aneinander gekettet F1().F2().F3(), wobei der Output der vorherigen zum Input der nächsten wird und am Ende dann das gewünschte Ergebnis zurückgeliefert wird.
  3. Jede Änderung an einem Objekt führt dazu, dass das Objekt mit den neuen Eigenschaften neu erstellt wird und zurückgeliefert wird.

Ich habe persönlich das Gefühl, dass ich irgendwas noch nicht verstanden habe, da FP eigentlich den Code und Architektur ja schöner machen soll. Allein bei den 3 Punkten (und der Author geht noch wesentlich weiter) empfinde ich das Programmieren allerdings als sehr "anstrengend".

Meine statischen Klassen werden größer und größer und größer und dieses aneinander Ketten von Funktionen kommt mir irgendwie wie klassisches C oder Javascript vor. Dieses datenflussorientierte Denken das Output zum neuen Input wird, kenne ich aus Labview. Und hier habe ich ehrlich gesagt keine super gute Erfahrung in Projekten die ein gewisse Größe haben. Man muss hinterher immer den kompletten Datenfluss sich anschauen, wenn irgendwas nicht funktionierte.

So nach soviel Text zu meiner eigentlichen Frage: Wer von euch nutzt z.B. FP in C# und kann wirklich bestätigen, dass es sich lohnt auch weiter als die grundlegenden Prinzipien von FP in C# zu gehen. Ausschließliche Nutzung von expression bodies, nur immutables, nur Verkettung von Methoden und alles statische Klassen.

Danke und schönen Advent noch.

01.07.2017 - 13:15 Uhr

Danke nochmal an alle.
Ich habe jetzt auch nochmal alles bisschen refactored und bin bei den Methoden geblieben. Inzwischen hat sich das auch bewährt. Einige Methoden hatten Bugs und so habe ich diese sofort finden können.

Das mit einer eigenen Engine hatte ich auch schon überlegt. Ggfs. sogar soweit, dass ich das auslagere in einer Scriptsprache.

Danke

25.06.2017 - 14:35 Uhr

Hallo FZelle,

ja du hast schon recht mit der Aussage bzgl. privater Methode. Ich hatte das Wort "vollmüllen" nur benutzt, weil die Methode ausschließlich von dieser einen Methode genutzt wird und dabei in der Regel nur einmal durch die RefactoredMethode benutzt wird. Mir kam das irgendwie nicht sauber vor.

Hier liegt doch schon die Antwort.
Jede Funktion wird anhand ihrer Aufgabe benannt.

Aber ist es wirklich nötig das alles an einer Stelle und auch komplett durchzuführen?

Die Methoden habe ich auch alles soweit korrekt benannt.

Leider muss alles durchgeführt werden. Man kann sich das ganze als eine Art Business Objekt vorstellen, dass mit unterschiedlichen Werten gefüllt wird. Jetzt wird es quasi durch die 28 unterschiedlichen Privaten Methoden gefüllt und an die weiter oben liegende Logik und UI weitergeben.
Es müssen auch immer alle 28 Methoden durchlaufen. Jede einzelne Methode ist wichtig.

Ich bin mir nur nicht sicher, ob man es so wirklich machen sollte oder es nicht eine schönere Variante gibt, welche ich derzeit nicht sehe.

@Witte: Dein Beitrag jetzt gerade gesehen. Danke ich guck mir die mal an.

25.06.2017 - 11:15 Uhr

Hallo mycsharp,

ich habe heute eine Frage in Richtung Refactoring.
Und zwar folgende Situation:

Ich habe eine Methode die mir ein komplexes Objekt zurückliefert. Hierfür holt die Methode Daten aus der Datenbank und macht eine Menge Fallunterscheidungen (If Anweisungen).

Die IF Anweisungen sind zum teil stark verschachtelt


If(..)
{
    If(...)
   {
        If(...)
         {
            obj.ListA(new A());
        }
    }
}

Bei einem True in der letzten IF Anweisung füge ich dem Objekt z.B. etwas in einer Objekt.List hinzu.
Soweit nichts besonderes. Meine Methode ist allerdings 2000 Code Zeilen lang. Ich habe Sie zunächst runterprogrammiert. Die IF Anweisungen habe ich in unterschiedliche Regionen unterteilt, da sie im Prinzip jeweils eigenständig sind. In der Methode selbst nutze ich auch noch 4 lokale Funktionen.

Jetzt wollte ich das Ganze ein wenig sauberer machen, um es auch wartbarer zu machen. Mein Problem ist: Was ist die Beste Denk- und Vorgehensweise eine derart komplexe Methode richtig zu refactoren.

Mein erster Ansatz war, alle Regionen auslagern in eine eigene private Methode.

Somit hätte ich in etwa sowas


RefactoredMethod()
{
   var obj = new komplex();
   AddToObjektRegionA(obj);
   AddToObjektRegionB(obj);
   AddToObjektRegionC(obj);
   AddToObjektRegionD(obj);
   AddToObjektRegionE(obj);
....
}

Ich komme hierbei auf 28 Methoden, die ausgelagert sind.
Jetzt habe ich die Klasse mit privaten Methoden zugemüllt, die nur von dieser eine RefactoredMethod genutzt werden.

Normalerweise halte ich mich an das Prinzip: Methode = 1 Aufgabe und nicht zu lang. Was allerdings hier wirklich schwer ist.
Das komplexeObjekt wird später Teil eines ViewModels sein und muß als Ganzes abgerufen werden.
Ich kann also nicht die einzelnen Methoden public machen und diese nutzen.

Wie geht ihr mit so langen Methoden um, die euch ein Objekt aufbauen? Einfach so lassen? Mit privaten Methoden?
Übrigens.: Die IF Anweisungen sind alle schon optimiert. Hier kann ich nicht viel machen. Es handelt sich hierbei um individuelle Abfragen. Die eine verwendet das aktuelle Datum, die andere noch eine andere Quelle, um Daten zu vergleichen, die andere ein anderen Wert aus der Datenbank und und und.

Danke für die Ratschläge.

17.06.2017 - 11:59 Uhr

Hi,

wollte nur einmal "DANKE" sagen.
Ich bin gerade wieder dabei eine kleine WPF App umzusetzen. Und dieser Thread hat mir enorm geholfen mich nochmal an alles zu erinnern.

Perfekt! 👍 👍 👍 👍 👍 👍

22.03.2017 - 23:38 Uhr

Habt alle vielen Dank.
Das bringt mich aufjedenfall weiter. Ich werde versuchen mich an den Tipps zu orientieren.
Berichte dann wie erfolgreich ich damit war.

22.03.2017 - 12:24 Uhr

Genau solche Antworten hatte ich noch gesucht. Deine Variante hatte ich z.B. noch gar nicht im Blick. Alles zu kopieren und Namespace erweitern auf V2.

Gibts weitere Umsetzungsideen?

22.03.2017 - 12:20 Uhr

Hallo Coffeebean,

doch das finde ich auch gut so. Die Variante würde ich auch für die API bevorzugen.

Frage wäre nur noch. Wie unterscheide ich die Klassen.
Nutze ich ein Datenmodell mit Nullable Propertys oder baue ich eine UserV2.cs und UserV3.cs.
Ich möchte die alten Daten aus UserV1.cs nicht verlieren.


[ApiVersion( "1.0" )]
[Route( "api/v{version:apiVersion}/[controller]" )]
public class UserController : Controller {
    public string Get() => UserList<UserV1>();
}

[ApiVersion( "2.0" )]
[ApiVersion( "3.0" )]
[Route( "api/v{version:apiVersion}/helloworld" )]
public class User2Controller : Controller {
    [HttpGet]
    public string Get() => UserListV2<UserV2>();

    [HttpGet, MapToApiVersion( "3.0" )]
    public string GetV3() => UserListV3<UserV3>()
}

Also Best-Practice auf Datenmodell/Datenbankschema Ebene.
Es geht auch nicht um Richtig oder Falsch (so wie ich das ja aus den Links gelernt habe), sondern um eure Erfahrung 😁

22.03.2017 - 12:09 Uhr

Habe die Beiträge durchgelesen. Finde die API Variante url/api/v1 und url/api/v2 auch am einfachsten. Ich kenne es so auch von anderen Projekten.

Was ist aber wenn das Datenmodell komplexer wird?

Ich habe ein sehr einfaches Datenmodell in V1.
In der neuen Version dagegen ist es so komplex, dass man es nicht mehr vergleichen kann mit V1.
Im Prinzip sind es wirklich unterschiedliche Datenmodelle, die aber den gleichen Zweck eigentlich in der Anwendung erfüllen. Nehmen wir den User.
Während in V1 ein Name ausgereicht hat, ist der User in V2 so ersetzt worden, dass nichtmal mehr Name drin vorkommt, dafür aber viele andere Propertys.


User
{
 string Hash;
 string ComplexProperty;
}

  1. Würdet ihr dann dem DatenmodellV2 eine neue Rest-Ressource zuordnen? (Geht in Richtung von Sir Rufos Antwort)
  2. Per Skript die V1 Modelle in V2 überführen?
  3. Neue Propertys Nullable machen(siehe Pinkis Antwort)?
  4. Eure Vorgehensweise?

Bei 1. sehe ich das Problem, dass die Daten V1 und V2 getrennt sind und parallel betrieben wird. Ich muss also auch unterschiedliche Businesslogiken haben. Was ist, wenn alle User auf Version 2 umgestiegen sind? Oder ich Sie dazu zwinge ? Was passiert mit den Daten aus Version 1, die noch gespeichert sind? Die Daten könnten ja noch interessant sein für eine Auswertung.

Bei 2.: Jede Aktualisierung würde ein Skript benötigen. Viel Arbeitsaufwand, erneute Fehlerquelle

Bei 3.: Möglich sehe ich aber als unschön an. Ich hätte nach einem Jahr ein riesen Datenmodell, in dem viele Objekte ggfs Nullable sind. Im Code müsste ich auf


if (User.Property ==null)

testen. Ein Graus.

Liege ich da richtig? Oder bin ich auf dem Holzweg?

Danke

Nachtrag:
Gerade den Beitrag von Dir Abt gelesen. Wie machen das denn dann kleinere Unternehmen? Millionen von Apps und Dienstanbieter, die ihre Software upgraden. Da muss es doch auch für die Datenbankebene ein Best-Practice geben oder?

22.03.2017 - 11:38 Uhr

Danke.
Ich lese mir die gerade alle durch.

Was sind denn eure Best-Practice Erfahrungen?

Das eine ist die Versionierung der API (url/api/v1). Das andere die Datenmodelle, welche schon gespeichert wurden.
Wenn ich ein produktives System gemäß Saas und Continues Integration/Delivery immer aktualisiere, dann muss ich doch auch die "Alt" Daten in das neue Datenmodell migrieren.

Wenn ich z.B. den User oben erweitere, lese ich oft so eine Variante


User
{
String Name;
[Default(0)]
int Age;
}

Doch das widerspricht irgendwie meinem Bauchgefühl. Die Modelle in V1 hatten kein Age, also warum sollen sie jetzt 0 sein, wenn ich sie in V2 überführe.
Und was ist wenn Age entfernt wird? Für jede Datenbank gibt es "Workarounds". Aber ich glaube, dass vieles weit entfernt ist von der Realität. Die Datenmigration scheint mir das größte Probleme zu sein gegenüber Versionierung der API. Große Unternehmen ala Salesforce , Microsoft bekommen es aber ja auch mit ihren Online Anwendungen hin. Nur wie?

Danke

22.03.2017 - 10:26 Uhr

Hallo mycsharp,

Ich stoße derzeit auf eine neue Herausforderung. Versionierung.
In erster Linie geht es um die Datenmodelle selbst.

Beispiel: ich speichere simple Datenmodelle 1:1 in einer noSql Datenbank.


User {
String Name
}

Im Laufe der Zeit kommen aber neue Properties hinzu oder werden sogar entfernt, weil sie komplett überflüssig werden.

Von Coffebeans habe ich folgenden Link bekommen

https://blog.qmo.io/ultimate-guide-to-api-design/

Der Autor beschreibt dort, dass man die neue Version parallel betreiben soll. Ich finde das macht auch Sinn, jedoch frage ich mich: wie überführe ich die existierenden Daten in das Datenformat v2?
Wenn ich mir vorstellte ich habe 25 Datenformate und alle wurden angepasst, dann graust es mir dafür eine Upgraderoutine zu schreiben.
Mit den Problem bin ich sicherlich nicht der Erste. Vielleicht habt ihr ja Erfahrungen wie man es gerade in c# machen sollte. Gerade mit Blick auf Software as a Service, wo Software sich ja täglich ändern kann, frage ich mich wie die Firmen das so sauber umgesetzt bekommen.

Danke

Nachtrag: ich würde ungern alte Zöpfe mitnehmen. Wenn zb Name bei User rausfliegt, dann würde ich ungern das Property behalten und ein nullable oder Defaultvalue machen. Wenn das geht