Architektonische Gestaltung eines ASP. NET Core Application (Aufgeräumte Architektur) | Trevoir Williams | Skillshare

Playback-Geschwindigkeit


1.0x


  • 0.5x
  • 0.75x
  • 1x (normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Architektonische Gestaltung eines ASP. NET Core Application (Aufgeräumte Architektur)

teacher avatar Trevoir Williams, Jamaican Software Engineer

Schau dir diesen Kurs und Tausende anderer Kurse an

Erhalte unbegrenzten Zugang zu allen Kursen
Lerne von Branchenführern, Ikonen und erfahrenen Experten
Wähle aus einer Vielzahl von Themen, wie Illustration, Design, Fotografie, Animation und mehr

Schau dir diesen Kurs und Tausende anderer Kurse an

Erhalte unbegrenzten Zugang zu allen Kursen
Lerne von Branchenführern, Ikonen und erfahrenen Experten
Wähle aus einer Vielzahl von Themen, wie Illustration, Design, Fotografie, Animation und mehr

Einheiten dieses Kurses

    • 1.

      Einführung

      1:30

    • 2.

      Reine, Architektur verstehen

      7:03

    • 3.

      Was wir erstellen werden

      4:22

    • 4.

      Lösung einrichten

      2:55

    • 5.

      Das Domain

      6:08

    • 6.

      Das Application

      7:14

    • 7.

      Automapper

      12:19

    • 8.

      Abfragen mit MediatR erstellen

      16:18

    • 9.

      Abschlussqualitäten für MediatR

      7:42

    • 10.

      Befehlszeichen

      12:35

    • 11.

      Verfasse die Befehle mit MediatR

      21:39

    • 12.

      Validierung hinzufügen

      27:27

    • 13.

      Benutzerdefinierte Exceptions hinzufügen

      13:14

    • 14.

      Zusätzliche Überlegungen und Überlegungen

      9:39

    • 15.

      Sektion Übersicht

      1:46

    • 16.

      Entity Framework Kern hinzufügen

      5:37

    • 17.

      Durchdringung der Persistenzschicht

      15:27

    • 18.

      Infrastrukturprojekt (E-Mail-Service)

      15:59

    • 19.

      Application erstellen und konfigurieren

      11:44

    • 20.

      Thin API Controller

      14:56

    • 21.

      Fertigstellung

      4:29

    • 22.

      Seed

      4:47

    • 23.

      Swagger

      8:26

    • 24.

      Einteilung – Abschnitt Übersicht

      3:23

    • 25.

      Einheitstests für Anwendungscode

      28:25

    • 26.

      ASP.NET MVC Projekt

      2:14

    • 27.

      NSwag für for

      8:35

    • 28.

      Benutzerdefinierte Setup und Basiscode

      14:18

    • 29.

      Erleichterung der Type Management Service

      12:11

    • 30.

      UI der die Verwaltung von Type Type Type

      27:55

    • 31.

      Json Web Token (JWT) Authentication zur API

      36:55

    • 32.

      Authentizität im Webprojekt

      30:35

    • 33.

      Einrichten

      18:50

    • 34.

      Einweisung von angehenden Antrag

      20:53

    • 35.

      Einrichten

      24:29

    • 36.

      Einheit für Chargen.

      8:40

    • 37.

      Exception

      13:36

    • 38.

      Token Ablauf

      8:40

    • 39.

      Token Ablauf

      13:51

    • 40.

      Data

      5:54

    • 41.

      Schlussbemerkung

      1:03

  • --
  • Anfänger-Niveau
  • Fortgeschrittenes Niveau
  • Fortgeschrittenes Niveau
  • Jedes Niveau

Von der Community generiert

Das Niveau wird anhand der mehrheitlichen Meinung der Teilnehmer:innen bestimmt, die diesen Kurs bewertet haben. Bis das Feedback von mindestens 5 Teilnehmer:innen eingegangen ist, wird die Empfehlung der Kursleiter:innen angezeigt.

196

Teilnehmer:innen

--

Projekte

Über diesen Kurs

Übersicht

Eine modulare, testbare und maintainable Anwendung in . NET Einrichtung einer Anwendungsarchitektur erfordert Voraussicht und viel Betrachtung frühe Entscheidungen

Auf Dauer müssen jedoch die Anwendungen pflegen und in diesem Fall verlängert werden. Zwischen seinem Design und der Art der Code

Warum SOLIde Architektur?

Wenn wir über SOLID Architektur sprechen, ist es keine einfache Aufgabe. Entscheidungen früh in diesem Prozess können sich später einen Einfluss haben und die Wartbarkeit und Testfähigkeit spielen eine wichtige Rolle. Die Aufnahme dieser Praktiken kann auch dazu beitragen, code zu vermeiden, Code zum Nachschneiden von Dateien und eine effizientere agile Entwicklung zu vereinfachen.

SOLIde steht für:

  • S – Prinzip für die Einzelheit

  • O – offenes Prinzip

  • L – Liskov Prinzip

  • I – Interface

  • D – Dependency

In diesem Kurs erfährst du grundlegende Architekturprinzipien Als Next, erstellst du eine echte Anwendungsarchitektur mit ASP.NET Core. Dann lernst du, wie du verschiedene Blockaden wie E-Mail, Authentizität anziehen kannst

Wenn du mit diesem Kurs fertig bist, hast du die Fähigkeiten und Kenntnisse zur Erstellung einer prüfbaren und testable ASP.NET Core für den Architekt von Unternehmen erstellten Anwendung NET

Erstelle eine starke Basis NET 5 saubere Architektur:

  • saubere Architektur und bewährte Praktiken

  • Befähigung der verantwortungsvollen Segregation (CQRS)

  • Mediatr

  • E-Mail-Service mit SendGrid hinzufügen

  • Driven zur Softwarearchitektur

  • Effiziente Behandlung und Führung

  • Implementing

  • Globaler Umgang mit benutzerdefinierten Middleware und Exceptions

  • Validierung mit fließender Validierung hinzufügen

  • Erstelle ein NET und MVC

  • JWT(JSON

Inhalt und Übersicht

Um diesen Kurs take NET

Dies ist ein großer Kurs. Über 10 Stunden erwachsen, aber schlau content, um eine Reihe von verwandten Aktivitäten auf der Grundlage von jedem Modul der in der Anwendung zu machen, die er sein wird. Wir werden uns die Fehlersuche und Fehlersuche ansehen. es um bewährte Praktiken: es zu schreiben: es geschehen und Verständnis der Macht der Entwickler:innen Dinge wie sie tun Dein Wissen wird im Kurs wachsen

Wir machen Dinge zum ersten Zeit, das nicht die Realität des Programmieren wird. Wir machen Fehler und zeigen sie und und führen sie herum. Wir entwickeln Kenntnisse in der Verwendung von debugging und Techniken Wenn du den Kurs fertig gemacht hast, wirst du dich in Visual Studio bewegen und Logik- und Syntaxfehler so groß betrafen NET-Umgebung. Dies wird deine neuen Fähigkeiten in die praktische Anwendung bringen und deinen Chef und Kollegen überzeugen.

Der Kurs ist fertig, mit Arbeitsdateien auf GitHub zu machen, mit der Aufnahme einiger Dateien, um es dir zu machen, dass du den Code demonstriert hast. Du wirst mit dem Autor zusammen arbeiten und während des Kurses ein verifizierbares Zertifikat zur Fertigstellung

Triff deine:n Kursleiter:in

Teacher Profile Image

Trevoir Williams

Jamaican Software Engineer

Kursleiter:in

Skills dieses Kurses

Design Sonstiges Design Architektur
Level: Intermediate

Kursbewertung

Erwartungen erfüllt?
    Voll und ganz!
  • 0%
  • Ja
  • 0%
  • Teils teils
  • 0%
  • Eher nicht
  • 0%

Warum lohnt sich eine Mitgliedschaft bei Skillshare?

Nimm an prämierten Skillshare Original-Kursen teil

Jeder Kurs setzt sich aus kurzen Einheiten und praktischen Übungsprojekten zusammen

Mit deiner Mitgliedschaft unterstützt du die Kursleiter:innen auf Skillshare

Lerne von überall aus

Ob auf dem Weg zur Arbeit, zur Uni oder im Flieger - streame oder lade Kurse herunter mit der Skillshare-App und lerne, wo auch immer du möchtest.

Transkripte

1. Einführung: Hey Jungs, willkommen zu meinem brandneuen Kurs, ASP.Net Core, solide und saubere Architektur. Ich bin deine Instruktorin, Travolta Williams. Ich habe mehr als 10 Jahre Erfahrung als Software-Ingenieur und Dozent. In diesem Kurs werden wir uns ein paar Dinge ansehen. Wir werden uns mit der Implementierung solider Prinzipien und sauberen Architektur in einer ASP.Net Core-Anwendung beschäftigen. Auf dem Weg werden wir mit erweiterten Tools wie Mediator oder Bottom-up oder Fluent API für die Validierung arbeiten , wir werden globale Ausnahmebehandlung und Protokollierung erstellen. Ich werde mir das C QRS-Muster ansehen, das ein wunderbares Muster ist, das unseren Code getrennt hält und in Bitgröße für maximale Integration und Erweiterbarkeit sorgt. Am Ende dieses Kurses werden wir verstehen, wie Unit-Tests durchgeführt werden, wie Dienste von Drittanbietern in eine Anwendung integriert und wie wir sie für Produktionszwecke bereitstellen können. Allerdings umfassen die Anforderungen für diesen Kurs Visual Studio 2019 und dotnet five oder die neueste Version. Zu dem Zeitpunkt, an dem Sie diesen Kurs machen, ist alles, was wir tun werden, zukunftssicher und diese Prinzipien können problemlos auf die neuesten Versionen übertragen werden. Um das Beste aus diesem Kurs herauszuholen, empfehle ich Ihnen, etwas C Sharp und dotnet Programmierkenntnisse sowie Datenbank-Entwicklungswissen zu haben. So oder so, ich werde den Inhalt sehr anfängerfreundlich machen und Sie sollten absolut kein Problem haben , mitzuverfolgen und wissen, dass Sie alle Informationen haben, die Sie brauchen. Wir sehen uns bald im Kurs. 2. Reine, Architektur verstehen: In Ordnung, also haben wir uns die Prinzipien angesehen, die eine saubere Anwendungsarchitektur regeln. Nun schauen wir uns an, was genau wir mit sauberer Architektur meinen. Denn saubere Architektur bedeutet nicht unbedingt eine gute Software. Gut ist sehr relativ zu dem, wer es sieht. Zum Beispiel, wenn Sie mit der Entwicklung eines Lead-Management-Systems für die Personalabteilung beauftragt wurden und Sie es getan haben, und HR ist glücklich, dann ist es eine gute Software. Wenn Sie es jedoch nicht nach diesen Prinzipien getan haben, könnte es als schlechte Software angesehen werden, aber praktiziert Knosp-Software-Entwicklung im Allgemeinen, von Ihrem Team oder von wem auch immer Ihr Nachfolger ist, wenn sie versuchen pflegen Sie diese Anwendung. saubere Architektur ist also nicht unbedingt direkt proportional zu guter Software. Es hängt davon ab, wer der Empfänger ist und zu welchem Zeitpunkt. Lassen Sie uns also einfach alles diskutieren, was in die Software-Entwicklung und die verschiedenen Arten von Architektur geht , so dass wir voll zu schätzen wissen, wann wir brauchen, um unsere Designüberlegungen ein bisschen mehr zu verstärken und was die Vor- und Nachteile davon sind. Also der erste, den wir betrachten wollen, wäre alles in einer Architektur. Und ich werde alles in einer Architektur, es ist einfacher zu liefern. Es kann stabil sein und als langfristige Lösung angesehen werden. Alles in einer Architektur könnte leicht sein, wenn wir bei brandneuen ist dotnet Core-Anwendung abgewürfelt. Oder wenn Sie das erste Mal ASP.Net Core machen, sind Sie wahrscheinlich besser mit Ruby on Rails oder Larve oder Dschungel vertraut. Sobald Sie dieses allgemeine Projektlayout haben, könnte das leicht als All-in-One-Architektur angesehen werden. Sie haben alle Ordner und alles, was Sie tun müssen, ist Ihre Dateien zu erstellen, erstellen Sie Ihre volle tut, dass Trennung von Bedenken direkt dort und alles ist gut, die Software wird funktionieren. Es ist jedoch definitiv schwierig, solide Grundsätze durchzusetzen. Je mehr Sie in diese alles in einer Architektur einpacken müssen, desto mehr Codegerüche und schlechte Praktiken, die möglicherweise kompromittiert werden müssen. In Ordnung, so wie es wächst, wird es schwieriger zu halten und seine Testbarkeit. Und wenn wir diese Stabilität sitzen, meinen wir wie beim Debuggen und durch Erweiterungseinheitstests die Fähigkeit, zwei Einheiten davon in einer Architektur zu testen. Diese Fähigkeit verringert sich mit den Anwendungsrollen. Als Nächstes wollen wir uns die geschichtete Architektur ansehen. Und alle Layered Architecture ist vor allem ein Schritt in einem, wo statt unsere Module oder unsere Chunks von Code und Dateien, sorry, nach Ordnern zu trennen , beginnen wir, Projekte zu erstellen und diese Projekte zu referenzieren. In ESP dotnet Core und in seinen Verpflichtungen im Allgemeinen können Sie Klassenbibliotheken entwickeln, in denen Sie alle Ihre Klassen setzen und Sie nur darauf verweisen, wie Sie es benötigen. Und dann würden Sie mit verschiedenen Schichten enden. Sie haben eine Ebene, die sich mit dem UI-Zeug befasst. Sie haben einen Layer, der mit der Geschäftslogik benötigt wird. Und Sie haben eine Schicht, die die Entzündung zwischen Datenbank und oben Geschäftslogik steuert. Und dann landen Sie mit einer geschichteten unsere Anwendung. Jetzt ist es einfacher, auf jeden Fall solide Prinzipien durchzusetzen und es ist einfacher, größere Codebasen zu minton. Dies greift jedoch immer noch auf eine Anwendung da alle diese Layer noch etwas voneinander abhängig sind. Wir nutzen also immer noch nicht das gesamte Abhängigkeitsinversionsprinzip sowie das gesamte lose Kopplungsprinzip. Und jetzt endlich betrachten wir die einzige auf Architektur, die weitgehend als saubere Architektur gelehrt wird. Jetzt, wenn wir über nur über Architektur sprechen, sprechen wir über verschiedene Arten, Ebenen zu sehen. Und in diesem Stadium wollen wir jede Art von Anwendung unterstützen. Möchten Sie alles sehr modular haben, so dass wir in ein neues Modul setzen können , ohne den Rest der Codebasis zu stören. Wir können Auto-Modul nehmen und wir können Änderungen vornehmen und testen einfacher , ohne bestehende Teile der Anwendung zu stören. Wenn wir also über die Odeon-Architektur sprechen, sprechen wir vielleicht über eine Client-Anwendung für die Benutzeroberfläche. Dies könnte eine ASP.NET-Webanwendung sein. Dies könnte eine mobile Anwendung sein. Wir sprechen darüber, dass beide API-Dienste haben, die auf der Verpflichtung auf dem Kern sitzen werden . Und diese API-Dienste wären wieder Open Source. Es ist nicht wirklich egal, was der Kunde ist und Risiken ist das, was wir verwenden werden. Aber es ist egal, ob es ein mobiler Client ist, es ist egal, ob es ein Web-Client ist, ein Blazer-Client, und wütend einen Client. Es ist nur, Daten aus der Datenbank zu rollen, wer zuhört. Und Buck, Nein, das Testen wird viel einfacher, weil wir die verschiedenen Schichten unabhängig voneinander testen können und dann können wir testen, wie die Schichten miteinander interagieren. Wenn also irgendetwas eingeführt wird, um eine dieser bestehenden Interaktionen zu brechen, dann können wir es leichter erkennen. Und von Anfang an null für die Infrastruktur sprechen wir über das Modul. Wir sprechen also über die Protokollierung des Datenzugriffs. Wenn wir mehr als eine Datenbank haben, mit der wir zu tun haben, sollten wir in der Lage sein, eine brandneue Ebene zu setzen, um mit der Datenbank rückgängig zu machen, ohne etwas zu stören, was die bestehende Architektur mit der alten Datenbank getan hat. Wir können in der Protokollierung setzen, wir können in Mapping, Validierungen setzen. Alles kann hineingehen und unsere Kommode, ohne unsere Anwendung zu stören. Also Nachteile, jedoch gibt es eine Lernkurve, weil Sie wissen müssen, was seltsam war und es gibt verschiedene Interpretationen dieser Art von Architektur. So können Sie verschiedene Geschmacksrichtungen sehen. Wenn Sie zwei oder drei verschiedene Quellen lesen, werden Sie zwei oder drei verschiedene Implementierungen seines Feindes sehen. Frage dich, welche ist die, die ich verwenden sollte? Natürlich bestimmt der Kontext viel von dem, was Sie und andere Entwickler tun, die Entscheidungen, die Sie in Ihrer Architektur treffen. Und so, weißt du, du musst das nur verwenden, nur das Wissen bekommen und deinen Kontext als Leitfaden und andere con für diese Art von Architekturen verwenden , dass es sehr zeitaufwendig sein kann , weil es viele ihre Menge mehr Dateien, die beteiligt sein werden, wenn wir etwas mit zwei Dateien jetzt tun könnte, wird es wahrscheinlich fünf erfordern. Wieder einmal wäre der Vorteil, dass wir losen Teppichboden und mehr Testbarkeit haben . Also mit all dem gesagt, seien Sie vorsichtig. Nicht jede Anwendung braucht, zitieren Sie unquote, saubere Architektur. Gute Software erfüllt die geschäftlichen Anforderungen und wartbare Software erhöht die Lebensdauer der Software. Du musst also jederzeit ein Gleichgewicht finden. Sehen Sie nicht, dass jedes Projekt, das Sie tun müssen, eine saubere Architektur benötigt, klein beginnt und nach Bedarf erweitert wird. 3. Was wir erstellen werden: Willkommen zurück. In diesem Video werden wir einen Blick auf die Anwendung , die wir erstellen oder neu erstellen möchten. Also auf meinem Bildschirm habe ich ein Lead-Management-System, das mit einer Geschwindigkeit auf dem Kern 3.1 gebaut wurde. Und Sie sehen all die Dinge, die in dieser Lösung implementiert wurden. Nun, es sieht gut aus und es tut, wozu es entworfen wurde. Es lieferte der Personalabteilung Möglichkeiten zur Verwaltung von Urlauben. Sie können den Quellcode für diese Anwendung auf meinem GitHub-Konto finden und Sie können nach dem Repository verlassen dash management, dash dotnet core suchen . In der Tat ist dies die Anwendung, die in meinem Kurs erstellt wurde, vollständige ASP.Net Core und Entity Framework Development. Warum war es perfekt für Anfänger? Es stimmt mit vielen Codegerüchen und ineffizienten Möglichkeiten den Code zu schreiben, den ein Anfänger aufnehmen kann. Aber dann, wenn Sie mehr Zwischen- bis Fortgeschrittene bekommen, werden Sie anfangen zu erkennen, dass sie bessere Möglichkeiten sind, um diese Dinge zu tun. Und genau das werden wir in diesem Kurs besprechen. Jetzt werde ich mir einfach die Projektstruktur ansehen. Und noch einmal ist es völlig optional, es herunterzuladen. Sie können einfach folgen, aber ich werde Ihnen einige der Schwachstellen der Architektur und einige der Entscheidungen zeigen , die während der Entwicklung dieser Anwendung getroffen wurden. Erstens, Sie werden sehen, dass dies nur ein Projekt hat. Nun, wenn Sie sich früher erinnern, als wir uns die verschiedenen Arten von Projektarchitekturen angesehen haben , würde dies in einer Architektur hineinfallen , wo alles nur in einem Projekt ist, leicht zugänglich. Also noch einmal, für Anfänger, ist das in Ordnung, weil Sie Ansichten wollen, erhalten Sie zu den Ansichten, die Sie wollen, dass ich zu Daten gehen. Es ist alles, was ihre Trennung von Bedenken an dieser Stelle begrenzt ist und auf nur Ordner beschränkt ist. Im größeren Bild, und wenn Sie mehr Dinge hinzufügen möchten, kann dieses Projekt sehr fett werden, wenn Sie versuchen, es zu erweitern, so wird es gut sein, es auszubrechen. Eine andere Sache, die unser Code riecht, die wir ansprechen möchten, ist die Wiederholung von Code. Selbst beim Erstellen unserer Datenmodelle würden Sie sehen, dass wir einige der Eigenschaften wiederholen. Wir haben ID dort, wir haben ID hier wieder, diese kleinen Dinge in einigen der Controller, wir wiederholen Code, wenn wir nicht unbedingt brauchen. Und dann, während wir auf dem Thema der Controller sind, gibt es, was wir hier Fat Controller nennen werden. Also machen wir eine Menge Geschäftslogik, eine Menge Verarbeitung direkt hier im Controller, was es sehr schwer macht. Sie möchten also diese Geschäftslogikprozesse von Ihren Controllern abhalten . Nun, außerhalb der Entwicklungsgründe für die Neugestaltung und Neuarchitektur dieser Anwendung aus geschäftlicher oder geschäftlicher Sicht, möchte HR diese Anwendung so erweitern, wie sie gebaut wird, oder? Nein, es ist ziemlich schwierig, das zu tun, ohne den vorhandenen Code zu stören. Das ist 1, 2, es ist in seinem aktuellen Zustand nicht sehr testbar. Selbst wenn wir versuchen, es zu erweitern, werden wir mehr eigene Tests haben, weil wir mehr Regressionstests und manuelle Tests darauf durchführen müssen . Und dann drei, wenn wir es in einer sauberen Architekturwelle tun, haben wir tatsächlich die Möglichkeit, es auf verschiedene Arten von Client-Anwendungen zu erweitern und potenziell als Software als Service bereitgestellt bei dem die API alle Geschäftslogik und Interaktion mit der Datenbank und der Client-Anwendung ist völlig anonym, dass wir hatten. Diese Client-Anwendung hätte eine MVC-Anwendung sein können, er hätte eine Blazer-Anwendung sein können, es hätte eine mobile App sein können. Das ist also einer der Gründe, warum Schlüssel und Architektur implementiert werden können. also auf das zurückgehen, was wir vorhin gesagt haben, ist gute Software Software Software, die ihren Job macht, richtig? Nein, das ist eine gute Software. Die Personalabteilung ist ruhig, zufrieden mit ihr und wie es geht, was sie tun muss. Jedoch, wenn sie anfangen, nach mehr Dingen zu fragen, erkennen wir auf unserem technischen sagte, dass es ein bisschen schwieriger wird, es zu erweitern, zu modifizieren, um es zu testen. Also, wo wir es schützen, damit wir immer noch alle Funktionen bereitstellen können , die die Personalabteilung will, während wir die Fähigkeit behalten, sie auf eine sehr effiziente Art und Weise zu pflegen. In unserer nächsten Lektion beginnen wir mit der Einrichtung der Lösung für unsere neue Architektur. 4. Lösung einrichten: Willkommen zurück. In unserer ersten praktischen Lektion werden wir unsere Lösung aufstellen. Also habe ich Visual Studio 2019 geöffnet. Wenn Visual Studio 2019 noch nicht installiert ist, können Sie einfach zum Visual Studio dot Microsoft.com-Schrägstrich VS wechseln und die Community-Edition herunterladen. Die Community Edition ist kostenlos für den Unterricht und die individuelle Nutzung. Natürlich, wenn Sie ein Werbespot sind, als Sie erwartet werden, um die professionelle oder die Enterprise-Version zu erhalten . Sobald Sie es heruntergeladen haben, wird Ihnen ein Installationsprogramm angezeigt. Und was Sie wirklich von diesem Installer benötigen, ist zumindest die ASP.NET- und Web-Entwicklungsworkload. Indem Sie es ankreuzen, geben Sie an, dass Sie möchten, dass diese Arbeit durchläuft. Sie werden alle verfügbaren Arbeitslasten sehen. Sie können sie mitnehmen, wenn Sie möchten. Natürlich, je mehr Sie nehmen, desto mehr müssen Sie herunterladen. Aber für diesen Kurs brauchen Sie wirklich nur diesen, der Ihnen alle Tools gibt, die für jede ASP.net-Webanwendung sowie dotnet five benötigt werden. Also, sobald Sie das Setup abgeschlossen haben oder wenn Sie es bereits installiert hatten, und fahren Sie mit mir fort. Und wir werden gehen, um ein neues Projekt zu erstellen. Was wir also tun werden, ist eine leere Lösung zu erstellen. Ich habe in meinen letzten Projektvorlagen. Aber wenn Sie darüber hinaus tun, können Sie in diesem Bereich immer nach einer leeren Lösung suchen und dann erhalten Sie eine leere Lösung, die keine Projekte enthält. Also, das ist, was wir wollen und wir werden dieses Projekt nennen H sind Punkte verlassen Management. Jetzt gibt es keinen besonderen Grund für mich, es so zu nennen. Es ist eine Lead-Management-Anwendung, die für die Personalabteilung entwickelt wird. Wenn es für ein Unternehmen gebaut wurde, dann würden Sie wahrscheinlich sagen, dass Unternehmen Punkt der Art des Systems. Also, wenn Sie wollen, können Sie voran gehen und meinen Namen verwenden oder diesen Namen entsprechend ändern. Sobald Sie jedoch einen gültigen Namen eingegeben haben, können Sie fortfahren und auf Erstellen klicken. Jetzt werden wir keinen Code in dieser Lektion schreiben, aber wir werden Projektstruktur so einstellen , wie wir sie für die Dauer dieses Kurses oder dieses ganzen Projekts benötigen . Das erste, was ich tun werde, ist, einen Ordner hinzuzufügen und ich werde diesen einen SRC nennen, kurz für Quelle, und einen anderen Ordner, den wir Tests nennen werden. Jetzt unter SRC, werde ich ein paar weitere Ordner hinzufügen. Ich werde dies die API nennen, denn das wird mit unserer Client-Anwendung interagieren. Ich werde einen anderen haben, der Core genannt wird, eine mehr als Infra-Struktur, und schließlich eine für die Benutzeroberfläche. Das ist also alles, was wir für diese Lektion tun. Wir richten gerade die Projektstruktur ein. Wenn wir also zurückkommen, werden wir anfangen, die verschiedenen Projekte zu erstellen, die in jedem dieser Abschnitte gehen werden. 5. Das Domain: Na gut, Leute, willkommen zurück. In dieser Lektion werden wir unsere Domain-Projekte erstellen. So werden unsere Domain-Projekte unter unseren Kernordner innerhalb unserer Anwendung gehen, wir können weitergehen und ein neues Projekt hinzufügen. Und was wir tun werden, ist es als eine Klassenbibliothek hinzuzufügen, C-Sharp Docx-Bibliothek vom Typ dotnet Standard. Ordnung, also ist es nicht in einem Steuerbord erlaubt Codesharing über viele verschiedene Plattformen hinweg. Also werden wir diese einfach für alle unsere Klassenbibliotheken verwenden. Und wir nennen es HR dot leave Management-Domain, da es verwendet wird, um alle unsere Domain-Objekte oder Entitätsklassen zu speichern , die in unsere Datenbanktabellen übersetzt werden. Also kann ich weitermachen und Next drücken. Und das Ziel-Framework hier ist dotnet Standard 2.1. Gehen Sie weiter und klicken Sie auf Erstellen. Jetzt, wenn das erledigt ist, erhalten wir unsere Standardklasse eins, die wir tatsächlich löschen und dann mit unseren Klassen füllen können. also zu unserem Projekt auf GitHub zurückkehren, würden Sie schnell sehen, dass die Domain-Klassen innerhalb des Projekts in einem Ordner namens data gespeichert wurden . Also unsere Domain-Klassen enthalten verlassen Zuteilung, verlassen Anfragen, und verlassen Typ. Wenn du willst, kannst du sie abrufen, aber ich werde sie trotzdem durchmachen. Wenn Sie also nur einen kurzen Blick auf diese Klassen werfen, würden Sie sehen, dass jede eine ID hatte, und wir hatten auch eine Reihe von Eigenschaften in jedem. Also, wenn Eigenschaften diese Art von wiederholtem Datum zwischen dem Blatttyp und dem Blattzuordnungsdatensatz enthalten würde . Und dann ist es inkonsistent, weil verlassen Management oder sorry, verlassen Anfragen nicht wirklich haben, dass. Also werden wir einige dieser Inkonsistenzen beheben und die Wiederholungen zwischen ihnen reduzieren. Also werde ich mit Blatttypen beginnen. Also werde ich nur zu dem Projekt gehen klicken Sie auf Neue Klasse hinzufügen. Wir nennen es Blatttyp. Und ich mache dieses öffentliche Forum Nein, innerhalb Blatttyp, was wir unsere Felder für ID haben, Name, Standardtage, und sie jeweils erstellt. Jetzt habe ich angegeben, dass das Datumsfeld, wie das erstellte Datum wirklich ein Auditfeld ist, und dies muss über die verschiedenen Klassen hinweg telefonisch sein. Also werde ich nur weitermachen und alle Entitätsklassen hinzufügen , damit Sie pausieren und replizieren können. Für die Urlaubsanforderung werden wir ein ID-Feld, Startdaten und Enddaten, Blatttyp haben. Die angeforderten Daten, Anfragen, Kommentare, Datum, Axon und genehmigt in Form eines nullwertigen Boolean, und abgebrochen in Form eines booleschen. So können Sie fortfahren und das replizieren. Nein, wenn Sie dies mit dem vergleichen, was sich auf der GitHub-Referenz befindet, fehlen einige Felder, für die wir gerade noch nicht bereit sind, in Form des Mitarbeiters, was einige benutzerbezogene Daten wären. Das haben wir noch nicht, also priorisieren wir nicht, dass wir das später durch einige Migrationen einführen können. Kennen Sie die dritte Entität, die wir hinzufügen werden, ist die Allokation verlassen. Und für diesen haben wir die ID, die Anzahl der Tage, das Erstellungsdatum, den Austrittstyp, Blatttyp-ID und den Zeitraum. Wieder einmal habe ich auch die Mitarbeiterbezogenen Felder weggelassen. Diese Datenanmerkungen. Jetzt in Bezug auf die Wiederholungsfelder versus die Notwendigkeit Kohärenz mit mindestens das Visum zu haben müssen wiederholt werden, nämlich das Datum erstellt. Normalerweise, wenn wir über Auditing sprechen, wollen wir das Datum erstellt haben, wer es erstellt hat, das Änderungsdatum und wer es zuletzt geändert hat, richtig? Auf diese Weise können wir alles im Auge behalten, was über sie passiert, wie fast alle gefickt. Wir würden tatsächlich einige der Dinge mit der ganzen Bezugnahme auf den Mitarbeiter lösen und so weiter mit diesen Auditing fühlt. Was ich also tun werde, ist, einen anderen Ordner in diesem Domänenprojekt einzuführen. Und ich werde diesen Ordner als üblich bezeichnen. Und dann innerhalb der gemeinsamen, werde ich eine Klasse haben, die ich diese Domain-Entität nennen werde. Niemand weiß, dass meine Basisdomänenentität hat, na ja, es ist gut, alle Basisfelder zu haben, die ich kenne, jede Klasse oder jede Domänenentität, die benötigt wird. Ich werde dies zu einer abstrakten Klasse machen, so dass es nicht alleine instanziiert werden kann. Es kann jedoch von allen anderen vererbt werden. Dies wird also ID sein, weil jede Tabelle eine ID benötigt. Ich werde auch für andere Felder haben, eines für das Erstellungsdatum, dann erstellt bis eines für das Erstellungsdatum, dahin eine Datum-Zeit für die Last-Modified Daten und ein anderes für die zuletzt geändert von. Jetzt mit dieser Basisdomänenentität kann ich wissen, dass alle anderen erbt. Ich kann einfach zu meiner tatsächlichen Entitätsklasse zurückkehren und sie von der Basisdomänenentität erben lassen, einschließlich fehlender Referenzen mit Steuerpunkt. Und dort sehen Sie, dass diese Felder, die ich INSEAD verlassen Allokation, die die gleichen Namen wie die auf einer Entität basieren, aufleuchten. Das bedeutet, dass ich sie nicht wiederholen muss. Ordnung. Das sieht etwas sauberer aus. In Ordnung, also gehe ich und lasse Anfragen, als ich dasselbe tue. Gehen Sie weiter und erben Sie die fehlenden Referenzen und dann muss ich plötzlich auch die ID hier nicht sehen. Und dann mache ich im Blatttyp genau das Gleiche, einschließlich fehlender Referenzen. Und dann kann ich alle wiederholten Felder entfernen. So basieren auf einer Entität gibt uns Zugriff auf bestimmte Felder, die erwartet werden, dass sie über jede Entität wiederholen, wie wir alle wollen, dass sie diese haben. In Ordnung. Also, mit all diesen Änderungen, lassen Sie uns voran und drücken Control Shift und B, um einen Build zu machen, und wir haben einen erfolgreichen Build. So können wir mit der nächsten Aufgabe fortfahren. 6. Das Application: Hey, Leute, willkommen zurück. In dieser Lektion werden wir unsere Kernschicht der Anwendung diskutieren. Jetzt besteht der Zweck dieser Schicht darin, zwischen unserer Anwendung zu sitzen, wobei die Anwendung alles ist, was auf die Datenbank und die Datenbank zugreifen möchte. In dieser Schicht werden also alle diese Zugriffsparameter definiert, um zwischen der aufrufenden Anwendung und der Datenbank selbst zu vermitteln. Also wird dieses Projekt direkt in unserem Kernordner sitzen. Also lassen Sie uns voran und fügen Sie eine neue Klassenbibliothek hinzu. Und ich wollte diesen einen HR-Punkte nennen, Management-Punkt-Anwendung verlassen. Gehen Sie weiter und fügen Sie es noch einmal hinzu, wir verwenden dotnet knapp unter 2.1 und gehen Sie voran und erstellen. Jetzt, da wir unsere Klassenbibliothek haben, werde ich die Standardklasse entfernen, und dann werde ich diesem Projekt zwei neue Ordner hinzufügen. Also der erste wird Persistenz sein und dann Systeme verschlüsseln, wir werden einen anderen Ordner namens Verträge haben. In den Verträgen werden wir also alle Hindernisse für unsere Repositories definieren . Nun ist die Jury auf dem Weg, was sind die besten Möglichkeiten, dies umzusetzen. Wieder einmal gibt es ein paar Meinungen ist die vorgeschlagene Architektur, und es gibt ein paar Meinungen und einige Meinungen werden basierend auf Kontext umgesetzt. Aber ich werde nur erklären, warum wir das Repository-Muster verwenden. Also, in der, im Einklang mit den trockenen Prinzipien, wollen wir Abfragen nicht zu oft wiederholen. Möglicherweise verfügen Sie über spezielle Vorgänge, die Sie eines dieser Domänenobjekte ausführen müssen. Wenn Sie also ein Repository pro Domänenobjekt definieren, können Sie benutzerdefinierte Zitate oder benutzerdefinierte Methoden innerhalb dieses Repositorys für diese haben , richtig? Nein, wir implementieren das Projektarchiv nicht, wir definieren nur den Vertrag. Also der Vertrag hier, der erste wird eine Schnittstelle sein und ich werde es ij generisches Repository nennen. Ich sagte, Unterricht hier, eine Klasse zu machen. Aber selbst wenn Sie vorsichtig sind, dass Sie es einfach zu einer öffentlichen Schnittstelle machen können. Jetzt werden wir dieser Schnittstelle sagen, dass sie relativ zu einer Klasse namens T implementiert wird . Also verwenden wir nur Generika im Einklang mit dem Namen generischen Repository, so dass jedes unserer Domain-Objekte verwendet werden kann, um Zugriff auf datenbankbezogene Funktionen über diese Schnittstelle. Einige der Methoden, die wir in dieser Schnittstelle implementieren werden, enthalten eine GetMethod, also haben wir Aufgabe T Und dann können Sie einfach weitergehen und alle fehlenden Bibliotheken einschließen. Wir werden auch eine Aufgabe haben, bekommen alles, was dieser zurückkehrt. Ich lese nur Listen, weiß, ob es das erste Mal ist, dass Sie diesen Datentyp sehen. Normalerweise und persönlich benutze ich normalerweise eine Liste oder einen Nihilist oder einen dieser populäreren Sammlungsdatentypen, die ich auf einer Liste gelesen habe. ist der Vorteil, dass es in einem schreibgeschützten Zustand hält, so dass es nicht geändert werden kann, sobald es aus den übergesendeten Datenmesons gezogen wurde. So weniger Trucking und weniger datenbankbezogene Operationen nach dem Datenpool. Also werden wir es in ein paar betrachten, aber das ist der Datentyp, den ich verwende. Wieder einmal hätten Sie leicht einen anderen Sammlungstyp vom Typ T verwenden können. Könnte eine Liste gewesen sein, könnte eine Sammlung sein. Aber dann lese ich auf der Liste dient dem Zweck, den ich wollte. Wir werden die Aufgabe haben, hinzuzufügen, wo auch Linda Aufgaben zu aktualisieren und zu löschen haben. So sehen Sie, dass die generischen Repositories nicht nur generisch für t, sondern es ist auch ein generisches in Bezug auf die Funktionalität bietet, die die grundlegenden und Standard-crud-Funktionen sind. Es gibt auch eine Namenskonvention, bei der Leute das Wort async verwenden würden , weil Sie sehen können, wo alle Aufgaben hier verwenden. So einige Male würden Sie sehen, dann definieren Sie es als eine Spüle. Es ist also offensichtlich, dass dies eine asynchrone Funktion sein wird. Also konntest du dieser Namenskonvention nicht folgen, wenn du willst. Ich werde es nicht tun, also können wir vorwärts gehen. Jetzt ist die Sache mit dem generischen Repository, dass es wieder einmal nur die generischen Crud-Funktionen sind, die jede einzelne Datenbanktabelle jemals ausführen muss. Wenn Sie jedoch etwas Bestimmtes haben, um die Zuordnungsoperation oder einen Urlaub Request-Vorgang zu verlassen, können Sie das Salz nicht erstellen und der Code könnte missy wenn Sie versuchen, es in bestimmten Teilen der Anwendung zu erstellen. Was wir also tun werden, ist in Kommentaren spezifische Repositories basierend auf unserem generischen Repository oder um unsere generische Funktionalität zu erweitern, aber spezifisch für unsere jemand unserer Domain-Objekte. Also werde ich einfach zu den Verträgen zurückkehren und ich werde noch einmal ein neues Element in Form einer Klasse hinzufügen , aber es wird wirklich eine Schnittstelle sein und ich werde es anrufen, ich verlasse das Repository. Sobald das erstellt wurde, schaffen wir es in eine öffentliche Schnittstelle. Und dann lasse ich es wissen, dass es generisches Repository erweitert und es spezifisch für unsere Klassenart der Urlaubsanforderung ist. In Ordnung, also verlassen Anfrage ist unsere Domain. Denken Sie daran, dass dies relativ zum Typ t war. Das ist also das T, das wir übergeben, aber dann werden Sie hier sehen, dass es nichts über sagen 70 weiß. Also müssen wir einen Verweis auf HR-Management-Domäne hinzufügen. So können Sie sehen, dass in aller Ehrlichkeit das für mich nicht ganz funktioniert hat, wenn ich ihre Seite benutze, gehen Sie einfach zu Abhängigkeiten. Lassen Sie mich das noch einmal tun, Entschuldigung, Abhängigkeiten beim Projekt oder eines Freundes. Und dann nehme ich einfach den Verweis auf die Domänenobjekte. Klicken Sie auf OK. Und dann kann ich wissen, dass die Verwendung Anweisung hier einschließen. Ordnung, also innerhalb dieses Projektarchivs, dann, wenn wir spezielle Funktionen relativ zu verlassen Anfragen haben, dann können wir sie hier mit der Modellierung des generischen Repositories und ohne die anderen spezifischen Repositories definieren brauchen, um es zu sehen, wollen wir alles an einem Ort halten. Nach diesem Beispiel werde ich nur weitergehen und die anderen Repositories verteidigen. Ich verlasse die Zuweisung und ich werde Typ-Repositories verlassen. Sobald diese Aktivität abgeschlossen ist, enden wir mit zwei anderen Schnittstellen. Also haben wir unser generisches Repository. Wir haben oder ich verlasse Allokation-Repository, das implementiert oder erbt oder ein anderes ich generisches Repository relativ zu verlassen Allokation. Und dann haben wir das wieder für Blatttyp, mit dem ich das Typ-Repository verlasse , das generische relativ zum Verlassen des Typs erweitert. Also, das ist es wirklich für diese Lektion, in der sie die Verträge aufrechterhalten. Und diese Verträge sind in den Foren dieser Schnittstellen. Denn denken Sie daran, dass wir nicht direkt mit dem Code unterbrechen wollen , wenn wir aufrufen, was wir mit Abstraktionen zu tun haben, so können wir Codeänderungen vornehmen, ohne das Zitat vom Client zu stören - seitliche Anwendung. 7. Automapper: Hey Leute, willkommen zurück. In dieser Lektion werden wir sitzen Auto Mapper. Wissen Sie, wenn Sie nicht wissen, was Herbst-Obermaterial ist, das ist kein Problem. Es ist wirklich nur eine Bibliothek, die uns hilft, zwischen einem Datentyp in einen anderen zu konvertieren. Einfacher, richtig? Der Kontext dahinter, warum es nützlich sein wird , ist, dass wir das Mediatormuster in einem folgenden Video implementieren werden. Aber das vermittelt oder Muster wird als Nachrichtenmechanismus zwischen dem, was von der Anlage kommt und was in die Datenbank gehen muss handeln. Es ist im Allgemeinen eine schlechte Praxis, direkt mit den Domänenobjekten zu interagieren, zumindest bevor wir zum Projektarchiv gelangen. Das bedeutet, dass wir keine aufrufende Anwendung und den Client, jede Anwendung, die mit unserer Anwendung im Kern spricht, erlauben sollten , uns direkt zu senden oder Objekte vom Domain-Objekttyp zu leiten. Stattdessen schaffen wir Hindernisse. So erstellen wir Datenübertragungsobjekte oder Ansichtsmodelle. Sie können sie entweder eines nennen, aber sie sind wirklich nur Kreuze, die wie das Domänenobjekt aussehen, haben aber Einschränkungen basierend auf der Operation. So Editiervorgang hat verschiedene Anforderungen von vielleicht eine Erstellungsoperation. Und so würden Sie die ID 1 präsentieren und ID würde nicht in der anderen dargestellt. einmal, alles, was Sie haben, sind Hindernisse dafür. Sie können körnig werden oder Sie können es allgemein halten. Das liegt an dir. Der Punkt ist Alter Mapper hilft bei der Konvertierung zwischen der behinderten oder der clientfreundlichen Version dieses Objekts und der datenbankfreundlichen Version dieses Objekts. Dies wird die lose Kopplung in unserer gesamten Anwendung fördern. Also mit allem, was gesagt wird das Setup für dieses nicht sehr kompliziert sein, was ich innerhalb dieses Anwendungsprojekts tun werde, ist einen neuen Ordner zu erstellen und wir werden es nur Profile nennen. Profil ist im Grunde nur eine Konfigurationsdatei für Automobiltunnel , die es erlaubt ist, zwischen einem Datentyp in einen anderen zu konvertieren. Also werde ich ein neues Kleid in diesem Ordner erstellen. Und ich werde es Mapping-Profil nennen. Und dann muss ich mich vorstellen und ich werde das natürlich öffentlich machen, aber ich muss zu NuGet gehen und unsere Altarmapper Library holen. Also werde ich einfach mit der rechten Maustaste Geld. Kannst du eine Bibliothek bekommen? Und dann werde ich nach dem ultimativen Autor suchen. Und die, an der ich interessiert bin, sind ultimative Bardot-Erweiterungen für die Abhängigkeitsinjektion. Wir werden mit allen Abhängigkeiten einschließlich der ultimativen PR-Bibliothek und allem, was sonst benötigt wird, kommen der ultimativen PR-Bibliothek und allem, was sonst , damit es für die Abhängigkeitsinjektion entsprechend verwendet werden kann. Also werde ich einfach weitermachen und das installieren. Natürlich, akzeptieren und erlauben alle Probleme, die auf einmal auftreten, die installiert ist. Anstatt Profil zuzuordnen, werde ich es von einer Klasse namens Profil erben lassen. Und diese Klasse wird in der Auto-Mapper-Bibliothek angerufen. In Ordnung, also haben wir das Profil-Setup. Das ist gut. Nun, das nächste, was ich definieren werde, wären meine Datenübertragungsobjekte. Also habe ich einen neuen Ordner innerhalb dieses Anwendungsprojekts erstellt. Und in diesem Ordner habe ich ein paar Dateien. Erstens habe ich eine gemeinsame Datei oder einen anderen Ordner mit einer gemeinsamen Datei namens Basisdetail. So ähnlich wie haul und wir sitzen an Bord Domänenobjekte, haben wir eine gemeinsame und dann, wo die Basisdomänenentität, die einige Basiseigenschaften hatte, die über alle diese Domänenobjekte liegen sollten. Es ist die gleiche Art und Weise, wie ich gerade basierte Details gemacht habe. Und das gemeinsame Eigentum wäre ID. Ich brauche nicht das Datum erstellt und so weiter mit den DTLs, das ist nur für die Überwachung, also ist das im Hintergrund. Also, was ich wirklich über sie alle teilen muss, wäre die ID. Und dann innerhalb von jedem dieser, die ich noch nicht gemacht habe, werde ich dann andere Eigenschaften haben, die ich weiß, dass jeder von ihnen haben muss , um erfolgreich nützliche Informationen für mich zu taxi. Dieser Teil ist also so einfach, wie Sie den Typ verlassen und die Eigenschaften übernehmen, die Sie kennen, möchten Sie Ihrer Anwendung oder Ihren Benutzern erlauben, sie zu unterbrechen. Das würde also Anfragen hinterlassen. Dies sind alle erforderlichen Eigenschaften. Ich bin nur buchstäblich, wie Sie sehen, ich kopiere und füge den harten Teil wirklich nur das Basisdetail und ließ die Vererbung auf diese IDs und nicht Details setzen, sprechen Sie mit Details. So sehen Sie hier, dass Blatttyp beibehalten wird. Sie sehen, dass der Blatttyp beibehalten wird. Sie lassen die DTO nicht über die Domain wissen. Alles klar, so sollte dies Blatt Typ DTO sein, und dies sollte auch glauben, dass DTO, und als Faustregel, Details Geschwindigkeiten und DTLs. Herbst-Oberwissen ist, was die Konvertierung zwischen einem oder der DTO und der Domäne ermöglichen wird . Also, anstatt Profil zuzuordnen, werden wir einen Konstruktor haben. So können Sie einfach CTO Wanne speichern, Wanne, die unseren Konstruktor erzeugt. Und dann werde ich eine Linie haben, die „Karte erstellen“ sagt. Und create könnte sagen zwischen einer Quelle und einem Ziel. Also T-Quelle wäre, sagen wir einfach verlassen Anfrage wäre meine Quelle. Das ist das Domänenobjekt. lassen Sie Anfrage, DTO, und das wäre mein Datenübertragungsobjekt. In Ordnung, also erstellen wir eine Mapping-Konfiguration zwischen Leave Request und der Anfrage DTO und schließen einfach mit den Klammern. Und dann kann ich das noch einmal verlängern und ihm sagen, dass es MOP umkehren kann. Und ultimative PR ist variabel, denn ich habe Anwendungen gesehen, bei denen die Leute einige Menge an Geschäftslogik im Herbst oben selbst setzen , wenn sie mit komplexen und wahrscheinlich domänenübergreifenden Anwendungen arbeiten , wollen Sie wahrscheinlich eine Domäne oder ein Detail , um in eine Domänenobjekte auf einem Satz und ein Domänenobjekt auf einem anderen konvertieren zu können. Sie könnten also mehrere Mapping-Konfigurationen von einem Objekt zu einem anderen haben. Sie könnten auch benutzerdefinierte Konverter erstellen, um zu sehen dass dieses Mitglied direkt in dieses übereinstimmende Mitglied auf der anderen Seite geht. Es gibt eine Reihe von Dingen, die Sie damit tun können. Das könnte ein ganzer Kurs für sich sein. Aber heute halten wir es einfach mit unseren einfachen Konfigurationsanforderungen. Also haben wir einen Standort verlassen und dann haben wir die passende DTO. Und dann haben wir endlich Blatttyp. Jetzt möchte ich etwas darauf hinweisen, das früher tatsächlich darauf angespielt wurde, aber ich möchte es noch einmal erwähnen. Es gibt Zeiten, in denen Sie etwas granularer werden möchten oder Details für einen bestimmten Zweck haben möchten. Schauen wir uns also Urlaubsanfragen an. Leave Requests Detail hat einige Felder. Der Zweck eines DTO ist es, die Anzahl der Felder zu begrenzen. Reduzieren Sie also das Überschreiben und stellen Sie dem Benutzer zu viele Informationen zur Verfügung. Was ich also versuche zu sehen, ist, dass für den Fall, dass Sie eine Urlaubsanforderung sehen möchten, alle diese Daten relevant werden. Aber dann für den Fall, dass Sie wirklich nur brauchen, um es aufzulisten oder eine Liste aller Urlaubsanfragen anzuzeigen. Sie benötigen wahrscheinlich nicht all diese Daten, die der Benutzer nicht alle diese Daten sehen muss , wenn er nur die Liste anfordert. Sie werden definitiv nicht brauchen, um die Kommentare zu diesem Zeitpunkt zu sehen. Sie müssen wahrscheinlich nicht sehen, dass das Datum Aktion genehmigt oder storniert wird, wenn sie Angebote. Also in diesem Fall, was tendenziell passieren ist, dass Sie es wahrscheinlich ein bisschen mehr ausbrechen wollen. So manchmal würden Sie am Ende mit einem Ordner innerhalb der Details. Und dieser Ordner wäre spezifisch, um vielleicht Anfrage zu hinterlassen. Und dann innerhalb Urlaubsanfragen, haben Sie alle Details, die sich unterscheiden. Richtig. Also ja, lassen Sie die Anfrage Details. Das ist in Ordnung. Dieser wäre für die Details, was gut, vielleicht habe ich noch andere Details spezifisch für die Auflistung. Sie hätten also Anfragen Liste D2, was ja, es hätte auch die BSD TO. Aber dann hat es weit weniger Eigenschaften. Also müssen Sie wahrscheinlich nur das Datum eingeben, an dem es angefordert wurde und ob es nicht genehmigt wurde oder nicht. In Ordnung. Also noch einmal, das ist alles relativ zu dem, was Sie denken, dass Sie zur Verfügung stellen müssen. Aber ich sehe nur, dass Sie in dieser Situation wahrscheinlich nicht jedes einzelne Ding in ein Detail stellen und dieses Detail dann immer verwenden möchten , wenn eine Anfrage gestellt wird, egal wie winzig ihre Anfrage ist oder wie wenig Daten es in dieser Situation wirklich brauchen. Das ist also der Zweck des DTO. Also eigentlich mit diesen Änderungen, ich weiß nicht, habe ich Code gebrochen. Lassen Sie uns zunächst den Namespace für diese Urlaubsanfragen Detail aktualisieren. Also das ist es weiß, dass es neuer Standort ist und dann muss ich mein Mapping aktualisieren, um zu wissen, dass es Urlaubsanfragen hat, Liste, DTO, riss ein Boot auch. Also mach einfach voran und aktualisiere diese. Und dann lassen Sie uns einen Build machen oder ich baue eine erfolgreiche. Das letzte, was wir hier tun werden, ist die Einrichtung auf KI Service Collection Registrierungsmethode. Der Zweck ist also, naja, im Einklang mit der Abhängigkeitsinjektion wollen wir in der Lage sein, alle unsere Komponenten, alle unsere injizierbaren Komponenten anstelle der Anwendungsebene definiert zu haben . Aber dann kann jede Client-Anwendung voran gehen und einfach die Methode aufrufen und sie in sich selbst registrieren lassen. Wenn wir da sind, wirst du es sehen, aber ich mache das richtig? Und das wäre auch Anwendungen, Dienstleistungen, Registrierung. Dies wird also eine öffentliche statische Klasse sein und es wird eine Methode haben , die ich public static void Configure Application Services aufrufen werde, die einen Parameter der AI-Servicesammlung benötigt. So können wir einfach weitermachen und fehlende Referenzen einschließen. Und dann innerhalb dieser erhalten wir Dienste dot add, auto, mapper zu sehen. Oder ich würde sagen, wenn Sie mit dotnet Core und Dependency Injection vertraut sind, würden Sie sehen, dass dies nur ein Dienst namens action ist, den Sie in der Starterdatei für jede dotnet Core-Anwendung gesehen hätten . Die Sache ist also, dass wir es nur zu diesem Projekt abstrahieren , so dass wir, wenn wir diese dotnet Core-Anwendung haben, diese Methode einfach aufrufen können. Und dann würde es weitergehen und jeden Dienst registrieren , der innerhalb dieser Methode definiert ist. Also fügen wir Auto-Mapper hinzu und dann werde ich Assembly-Punkt sagen , bekomme die Ausführung der Assembly. Gehen Sie weiter und fügen Sie alle fehlenden Referenzen hinzu. Nun, wenn Sie mit Automatik vertraut sind oder Sie zuvor damit gearbeitet haben, aber Sie sind nicht unbedingt vertraut mit diesem. Sie wären wahrscheinlich besser vertraut mit etwas wie Typ eines dann würde das Mapping-Profil finden und dann würde das uns erlauben, dieses Profil zu registrieren , hat die Herbst-obere Konfiguration im Allgemeinen. Die Sache dabei ist, dass Sie für jedes Mapping-Profil, Sie haben, wahrscheinlich diese Zeile wiederholen müssen. Und Sie, basierend auf der Größe Ihrer Anwendung, können Sie mit mehreren Mapping-Profilen enden, weil ich gesehen habe, wo Sie Mapping-Profile pro Domänenobjekt und pr, pr Detaildomänenobjektpeering basierend auf die Anzahl der Datenbanken sind Domänen, die vorhanden sind, oder? Sie befinden sich also sogar auf Anwendungsebene, eine Anwendung oder eine Client-Anwendung kann andere Mapping-Anforderungen haben als eine andere, so dass Sie sie getrennt halten. Mein Punkt ist also, dass, indem Assemblydot die Ausführung der Assembly erhält, es nur für jedes Mapping-Profil durchläuft , das diese Vererbung hat, und es wird einfach funktionieren. Alles klar, kein leichterer Weg, es zu sehen. So registrieren wir unser Herbst-Obermaterial in unserer Abhängigkeitsinjektion. Und das ist die Einrichtung Herbst-Mapper im Allgemeinen. Also, wenn wir bauen und es erfolgreich ist, dann kommen wir als nächstes zurück und setzen unsere Anwendung Setup fort. 8. Abfragen mit MediatR erstellen: Willkommen zurück Jungs. In dieser Lektion werden wir zwei Muster implementieren, die uns helfen, die lose Kopplung durch unsere Anwendung zu fördern. Sie sind das Mediatormuster und das C-QRS-Muster. Wissen, dass das Mediatormuster als Verhaltensmuster angesehen wird, da es Ihnen erlaubt, genau zu definieren, wie eine Reihe von Objekten miteinander interagieren. In einfacheren Worten, Sie stellen eine Anfrage und Sie erhalten ein Ergebnis basierend auf Ihrer Anfrage. Jedes Mal, wenn Sie diese Anfrage stellen, können Sie diese Art von Ergebnis erwarten, das eine Art Konsistenz ist , die Ihnen hilft, zu implementieren. Es hilft Ihnen auch, all diese Logik, die dieser Anforderung zugeordnet ist, von der aufrufenden Anwendung zu behindern . Jetzt QRS-Muster zu sehen und QRS zu sehen, ist die Abkürzung für Befehl und Abfrage Verantwortlichkeit Segregation. Es hilft Ihnen, die Lese- und Schreiboperationen von jedem Datenspeicher zu trennen. Also im Name-Befehl und Abfragebefehl ist alles, was die Daten, jede Schreiboperation, jede Aktualisierungsoperation erweitern wird. Und eine Abfrage ist, dass ich die Daten lese. Sie können also immer wissen, dass es ein Befehl ist, wenn Sie etwas tun, das die Daten erweitern wird. Wenn Sie Daten einlesen, handelt es sich um eine Abfrage. Also lasst uns anfangen. Wir gehen zuerst zu neuen Get, und wir werden das Mediator-Paket packen, das interessanterweise genug ist, verfasst von der gleichen Person, die uns den ganzen Mapper gegeben hat. Und das ist Jimmy BullGuard. Also werden wir weitermachen und das installieren. Und sobald das erledigt ist, kommen wir zurück zu unserer Configure Application Services Methode und wir werden hier ein paar Änderungen vornehmen. Einige davon waren anfänglich Versäumnisse von meiner Seite, und ich entschuldige mich. Also ändern wir das von einer Stimme zu einem KI-Dienst namens Elektron, das ist einer. Und dann fügen wir diese beiden Zeilen hinzu. Wir sehen Dienste dot Mediator hinzufügen, Assembly, dot gif Ausführung Assembly, lassen Sie einfach den Auto-Mapper und wir geben Dienste zurück. Also für den sofortigen ADD-Begriff, gehen Sie einfach voran und fügen Sie die fehlenden Referenzen ein. Und da gehen wir. So sollte diese Dienstregistrierungs- oder AI-Servicesammlungsmethode aussehen. Nun, da wir diesen Teil getan haben, lassen Sie uns einfach zurückverfolgen und sammeln unsere Gedanken und denkbar, was wir tun müssen, müssen wir die PQRS-Muster implementieren. So sind die CQ Spots sind, und wieder trennt Befehle von Steinbrüchen. Mit anderen Worten, wir brauchen Ordner für Befehle, wir brauchen einen Ordner für unsere Abfragen. Entweder Befehl oder Abfrage wird von dem behandelt, was wir einen Handler nennen. Wenn Sie also eine Anfrage stellen, wird sie behandelt und der Handler wird entweder ein Befehl sein , um die Daten zu erweitern oder etwas, um Daten zurückzugeben. Sie sehen also, dass es an dieser Stelle einige bewegliche Teile gibt. Und deshalb kann dies so viele Meinungen darüber haben, wie es umgesetzt wird. Also noch einmal, ich verschreibe keine Implementierungsmethode oder Ordnerstruktur, aber ich helfe Ihnen nur, sie zu visualisieren. Sie können es je nach Bedarf ändern. Aber das ist die ganze Welt ging, um es so sehr zu nähern, dass es einen neuen Ordner innerhalb von oder Verpflichtung Projekt erstellt , ich nenne es Funktionen. Und dann innerhalb der Funktionen, werden wir Ordner pro Domain-Typ haben. Und der Grund, warum ich sage, Domain-Typ ist, dass die Funktion der Anwendung relativ zu dem ist , was Sie gegen unser Domain-Objekt gegen die Taten dieser tun werden , richtig? Also werde ich es in Blöcken tun, die auf der Tabelle oder den Tabellen spezifischen Funktionen basieren , die die Anwendung bietet. Beginnen wir also mit einem einfachen wie Urlaubstypen. Innerhalb der Funktionen werden wir verlassen Typ haben. Ich werde nur diese Blatttypen realisieren. Und dann innerhalb des Blatttypen-Ordners, werde ich ein paar andere Ordner haben. Ich werde Anfrage-Handler haben, dann innerhalb von Handlern, wenn Befehle und Abfragen haben. Und das ist die Ordnerstruktur, mit der ich arbeiten werde. Nun, wie ich schon sagte, unterscheiden sich die Meinungen in der Warteschleife. Eine polare Struktur könnte aussehen. Einige Implementierungen hätten tatsächlich die oberste Ebene für den Dummy im Feature-Namen. Und dann hätten sie Befehle und Abfragen. Und dann innerhalb von Befehlen oder Abfragen gibt es, wo sie alle Anfragen haben oder einen Ordner haben, sorry, pro Abfrage, sagen wir innerhalb der Abfrage, sie würden einen Ordner für die spezifische Abfrage haben, sagen wir, get leaf type -Liste, das wird die Abfrage sein. Im Inneren haben Sie also die gute Blattart-Anforderung, erhalten Sie Blatttyp RequestHandler und den BTO spezifisch dafür. einmal gibt es viele Möglichkeiten, wie Sie dies umgesetzt sehen können, aber die Konzepte bleiben gleich. Sie möchten nur sicherstellen, dass Sie Befehle anders als Ihre Abfragen identifizieren können und Sie wissen, wo sich Ihre Anfragen befinden. Anfragen sind relativ zu einem 100. Nun, da wir die Ordnerstruktur an Ort und Stelle haben, lassen Sie uns mit etwas Codierung beginnen. Also innerhalb der Anfragen ist die erste Anfrage, die ich möchte, die Blatttypliste zu erhalten. Also, wenn Sie Konvention klug benennen, möchten Sie immer implizieren, wofür die Anfrage ist oder welche Art von Anfragen im Nein, richtig? Also bekommen verlassen Typliste und ich werde Anfragen angeben. Ordnung. So erhalten Sie Blatttyp-Listenanforderung. Und das ist eine öffentliche Klasse und es wird von IO-Anfragen erben. Das ist also Höflichkeit des Mediators, und es wird dann fragen, was sollte diese Anfrage im Gegenzug erwarten? Wenn ich also die Verwendung dieses Datentyps beantrage, was sollte ich zurückbekommen? Nun, Sie sollten keinen Listenblatttyp DTO zurückbekommen, denn wieder werden Datenübertragungsobjekte R1 hereinkommen und was würde nie die Domänenobjekte. Das sind aber unsere Forderungen. Es kann Zeiten geben, in denen Sie Parameter haben, die sie in Anforderungen setzen können usw. Aber das ist ein sehr einfaches. Ich werde noch nicht in irgendeiner dieser Komplikationen geraten. Das ist also unsere erste Bitte. Als Nächstes brauchen wir etwas, um diese Art von Anfragen zu bearbeiten. Jetzt ist dies eine GET-Anfrage, die es Abfrage macht. Also innerhalb des Handler-Abschnitts gehe ich zum Abfrageordner und ich werde sagen, fügen Sie eine neue Klasse hinzu und ich werde diese die Anforderungs-Handler nennen. Das ist also meine Namenskonvention. Also habe ich eine Anfrage nach einem Namen und dann füge ich einfach Handler an. Also werden wir voran gehen und diese als öffentliche Klasse hinzufügen, die Request-Handler wieder erben wird, mit freundlicher Genehmigung des Mediators. Und dann sagt ich Request-Handler: Okay, was sie idealerweise Breite anfordert, also ist seine Anfrage die GET-Anfragen. Okay, also das ist die Namenskonvention, die ich gerne benutze. Und mehr als das, sehen Sie diese Namenskonvention viel, weil Sie dann unsere Anfrage spezifisch an einen Handler binden können , indem Sie ähnlich, eine ist die Anfrage, eine ist der Anfrage-Handler. So können Sie voran gehen und alle fehlenden Referenzen einschließen. So sagt es, was Anfragen, dass meine Handhabung und was sollte ich erwarten, zurückzukehren. Der Rückgabetyp der Anforderung sollte also der Rückgabetyp sein. Du warst hier. Es wird also erwartet, dass der Typ DTO zurückkehrt. Was ich von Blattdiabetes aufgezählt habe. In Ordnung, jetzt, da das fertig ist, haben wir immer noch unsere rote Linie. Diese rote Linie ist, weil wir die Schnittstelle implementieren müssen. Also fast automatisch, wir bekommen hier tatsächlich eine Methode, die besagt behandelt. Es erhält die Anforderung als Parameter. Und dann schreiben wir hier den ganzen Code, um zu handhaben, wann immer diese Anfrage hereinkommt. Bevor wir jetzt beginnen, eine Anfrage hier zu behandeln, haben wir ein paar Abhängigkeiten. Erstens, wir müssen in der Lage sein, mit der Datenbank zu reden. Jetzt haben wir nichts umgesetzt, aber wir haben unsere Persistenzverträge. Das sind also Verträge, die tatsächlich mit der Datenbank sprechen. Wir interagieren also immer noch nicht direkt mit der Domain hier. In Ordnung, also muss ich die fehlenden Referenzen injizieren. Also mit S3 oder Wanne, Wanne, werde ich Konstruktor bekommen und dann werde ich injizieren und ich verlasse das Typ-Repository. Also werde ich nur weitermachen und irgendwelche fehlenden Referenzen hinzufügen. Und dann, nachdem ich es in den Konstruktor eingegeben habe, kann ich wissen, sagen, erstellen und ein Feld zuweisen. Alles klar, da gehen wir. Und ich neige dazu, den Unterstrich zu verwenden, weil ich gerne den Unterstrich sehe. Also weiß ich, dass dies definitiv das private Feld in der Klasse ist, also ist das meine Namenskonvention. Sie haben nicht unbedingt Grund, dass Sie sehen der automatisch generierte Code Ihnen keinen Unterstrich gab, also ist das in Ordnung. Jetzt eine andere Sache, die ich injizieren möchte, ist ich Mapper, weil ich etwas Mapping durchführen muss, wenn ich die Daten aus der Datenbank bekomme, wenn dieses Repository die Domänenobjekte zurückgibt, muss ich sie in Details konvertieren, um die Bock. Also brauche ich auch Autohersteller, also bin ich oben, enthalten fehlende Referenzen gehen auch voran und injiziert oder erstellt NSA im Feld. Und da gehen wir. Also haben wir alles injiziert und bereit. Nun, um diesen Handler-Code zu implementieren, was ich tun werde, ist eine Abfrage gegen das Blatttyp-Repository auszuführen. Also werde ich sagen, var leaf fetch gleich 08 ist, lassen Therapie Repository dot bekommen alle. Das ist ein Warten. Das bedeutet also, dass diese Methode asynchron sein muss. Und dann werden Sie sehen, dass der eine Fehler mindestens verschwindet. Und dann müssen wir die Liste des Blatttyps ETL zurückgeben. Also werde ich sagen, Rückgabe-Mapper-Punktkarte. Und dann ist dies, wo dies in Blatttyp Detail nützlich ist, aber es ist eine Liste von Blatttyp D2 oder andere. Und was ich darauf zuordnen werde, wird die Liste der Domänenobjekte sein , die von der Abfrage kommen. Und da gehst du. Jeder ist glücklich. Also immer fragen, dass ich die Blatttyplisten will, dann haben wir den Handler, der sagt: Okay, ich kann diese Anfrage für Sie bearbeiten. Das ist also, was wir meinen, indem das Anwendungsverhalten definieren oder definieren, wie Objekte miteinander in Beziehung stehen. Diese Bitte bezieht sich immer auf diesen Jäger. Ich glaube, wenn Sie es ausprobieren, mehrere Handler für die gleichen Anfragen, würden Sie aufgrund einiger Mehrdeutigkeit tatsächlich Laufzeitfehler auftreten. So können wir klar definieren, dass Sie, wenn Sie diese Anfrage gestellt haben, immer das Verhalten erwarten können. Nun schauen wir uns eine andere Anfrage an und es wird immer noch eine Abfrage sein. Aber diesmal will ich einen Speer. Blatt-Typ. Also habe ich gesagt, dass Sie Anfragen sehen können oder Sie möglicherweise Felder oder Eigenschaften in ihren Anfragen haben, die benötigt werden, um die spezifische Operation zu behandeln. Was also, wenn wir Elif-Typ erhalten wollten, nicht die ganze Liste, sondern Blatttyp-Detail. Also werde ich eine andere Frage erstellen. Und dieser hier wird gut sein. Hinterlassen Sie Detailanfragen. noch einmal daran, es öffentlich zu machen. Jetzt in dieser Situation werde ich Eigentum addieren und ich werde sagen ID. Also bekommen wir das Detail, was bedeutet, dass wir einen bestimmten Datensatz wollen. Und der beste Weg, um einen Datensatz anzugeben, ist das Senden der ID. Also brauchen wir einen Handler für diese Anfrage. Also werde ich diesen Handler und die andere Klasse hinzufügen oder die Typdetailanfragen 100 erhalten. Da gehen wir, machen es öffentlich. Nein, einen Schritt, den ich innerhalb der Anfragen verpasst habe, die ich von Anfragen erben musste. Und es erwartet nur einen Blatttyp DTO eines dieses Mal, richtig? So viele Anfragen DTO, gehen Sie vor und treffen sich bei allen fehlenden Referenzen. Da gehen wir. Also wird der Handler jetzt von Ich fordere Handler erben und gehen Sie fort und fügen fehlende Referenzen hinzu. Es wird Anfragen für gute Leave Typ Detailanforderungen behandeln, und es wird erwartet, dass der Typ ETL zurückgegeben wird. Also, sobald alle diese fehlenden Referenzen etwas gegangen sind, machen Sie voran und implementieren Sie die Schnittstelle, und dann beginnen wir damit. Jetzt werden wir im Grunde die gleichen Injektionen brauchen, für die wir verwenden mussten. Ich werde das nur beschleunigen und diesen Code kopieren und einfügen und einfach den Namen des Konstruktors ändern und alle fehlenden Referenzen hinzufügen. Und sobald Sie all das getan haben, können Sie mit dem spezifischen Code beginnen. Also in dieser Situation würde ich sagen, var leave type ist gleich und wir sind mit dem Methodenaufruf. Also lassen Sie Repository-Punkt bekommen und erhält seine Erwartung eine ID. Also habe ich das Anforderungsobjekt hier innerhalb des Portals behandelte Methoden. Ich kann jetzt sagen, Anfrage Punkt i e Ordnung, wieder, wo unterrichten wir? Also dieser Abstand, aber ich zeige Ihnen nur, dass Sie so diese Felder in Ihrer Abfrage, in Ihrem generischen oder in der Nähe des Repositorys verwenden würden , sorry. Wenn Sie also bestimmte Methoden innerhalb des Leaf-Typ-Repositorys definiert haben, können Sie spezifischere Felder für Ihre Anforderungen haben, die benötigt werden, um diese Arten von Operationen zu behandeln. Sobald wir das bekommen, das nächste, was wir tun müssen, ist die Blatttyp-DTO-Objekte zurückzugeben. Also werde ich sagen, Mapper, in Blatttyp-Detail gemappt und wir mappen den Typ ab. Also noch einmal, nur Details. Nun ist eine Sache zu beachten, dass in Handlern, die eine klare Trennung zwischen den Befehlen und den Abfragen haben. Aber in Anfragen gibt es keine klare Trennung. Wenn also Anfragen für die Befehle erstellt werden, müssen wir uns auf unsere Augen verlassen. Wir haben zwei OK. Wir sind nicht müde, damit wir nicht verwirrt werden, welche Anfrage für Wasser ist. Und ich glaube nicht, dass das sehr effizient ist. Also werde ich Befehle in meinen Anfragen haben, und ich werde auch Abfragen haben. Also weiß ich, dass ich, wann immer ich Anfragen, Sorgen und Anfragen will , genau weiß, wohin ich gehen soll. Und das gleiche für Befehle. Wie ich schon sagte, sie unterscheiden sich Ordnerstruktur. Manche Leute hätten wieder einmal nur gesagt, Urlaubstypen. Und dann hätten sie die Befehle gehabt. Und dann anstelle der Befehle, die die verschiedenen Befehle mit allen Ressourcen hätten , die für diesen bestimmten Befehl benötigt werden, das Detail, der Handler, die Anfrage, alle in diesem Unterordner. So, wie Sie diese geruchlos brechen, dass Sie mehr Dateien benötigen, mehr Ordner, weil Sie eine klare Trennung so weit wie möglich sehen wollen. Wieder einmal gesagt, dies implementiert ist relativ zum Schöpfer. Also werde ich nur meine Abfragen, die ich bisher erstellt habe, in diesen bestimmten Ordner verschieben. Und natürlich, nach dem Update dieses Namespace. Und sobald ich das tue, werde ich meine Handler aktualisieren, um den neuen Standort ihrer entsprechenden Anfragen zu kennen . Also mit all dem, Morgendämmerung, werde ich einen Build machen und bauen war erfolgreich und du siehst, wie alles zusammenkommt. Wenn Sie möchten, können Sie die anderen Funktionen implementieren , die wir mit Blatttypen begonnen haben. Sie können zumindest die verschiedenen, diebeiden Lese- oder die beidenAbfrageoperationen relativ zu verlassen Allokation und relativ zu verlassen Anforderung implementieren beiden Lese- oder die beiden . 9. Abschlussqualitäten für MediatR: Willkommen zurück Jungs, die in der gleichen Richtung der Einrichtung unserer Anfragen für unsere zusätzlichen Funktionen fortsetzen . Also haben wir es bereits für Blatttypen durchgemacht. Und die Aufgabe war es, es für Urlaubsanträge zu tun und Zuteilungen zu verlassen. Also habe ich das schon getan und ich werde dich einfach durchführen. Also, wenn Sie es nicht abgeschlossen haben, werde ich langsam genug gehen und alles erklären, was ich tue, damit Sie es replizieren können. Und wenn nicht, dann können wir einfach Notizen vergleichen und mich wissen lassen , wenn Sie etwas anderes getan haben als ich es getan habe. Also der erste, Lassen Sie uns mit Urlaub Zuteilungen beginnen. Also habe ich die Abfragen und ich habe die, was ich die Handler und die Anfragen habe, und ich habe die Abfragen in beiden. Nun nach dem Standard bisher würden Sie sehen, dass oder Quests ziemlich ähnlich aussehen, wie sie für eine Blatttypen aussahen. Wir haben die get-leave Allokation detaillierte Anfrage, die die ID nimmt. Und ich habe auch eine für die Liste. Ordnung, also in der Abfrage ist, ich habe eine kleine Überraschung für Sie. Ich weiß nicht, ob du es so gemacht hast, aber ich führe dich genau durch, was anders gemacht wurde. Also natürlich enthalten wir das richtige Hallo, das verlassen Allokation-Repository eher im Gegensatz zu dem Leaf Type Repository, weil wir es mit Levi Standorten richtig zu tun haben. Jetzt in Bezug auf unsere Handhabung, würden Sie sehen, dass ich hier eine Methode habe, die wir nicht in unserem Repository-Setup durchgemacht haben . Ich habe bekommen's Urlaub Zuteilung mit Details. Kennen Sie den Zweck von mir, dies zu spezifizieren , ist, dass, wenn wir die Details der Blattzuweisung erhalten und wenn Sie eine Erinnerung benötigen oder verlassen Zuteilung tatsächlich eine Navigationseigenschaft des Blatttyps hat, was bedeutet, wenn ich zeigen Was Urlaub hat, welche Anzahl von b nach, zeigen Sie den Namen dieses Blattsymbols an, zeigen Sie die ID, die nutzlos ist, oder? Oder der Client oder andere steuern die ID, sie würden einige Details des Blatttyps auf ihrer Seite benötigen. Wenn ich also mit Details sage, besteht der Zweck dieser Methode darin, dieseNavigationseigenschaft und alles einzuschließen, so dass ich bis Navigationseigenschaft und alles einzuschließen, so zu der Zeit, die ich bekomme, aber diese verlassen Zuweisung, würde ich all diese Logik nicht sind bereit und alles, was ich tun muss, ist Karte und Rückkehr. Also an diesem Punkt werde ich nur pausieren und 0, dass Sie manchmal Designmuster sehen würden , wo sie tatsächlich all diese komplexe Logik hier im Handler tun. Also habe ich gesehen, wo sie sich tatsächlich direkt mit dem Kontext hier im Handler verbinden würden . Und dann machen Sie alle diese rohen Abfragen direkt hier im Handler und massieren Sie dann und geben Sie dann endlich zurück, was sie zurückgeben müssen. Das ist also ein Designmuster, das Sie vielleicht sehen können. Und das andere ist, wo wir all diese Logik und komplexe Abfragen und Geschäftslogik abstrahieren . Und dann Mythos für das Repository. Nein, ich sage nicht, dass eine besser ist als die andere, weil ich hatte, dass der Ansatz seine Vor- oder Nachteile in Bezug auf die Herstellung von Methoden hat , die sich speziell mit einem Szenario beschäftigen , wie die Blattzuweisung mit den Details. In diesem Sinne könnte es gut sein, das in unser Repository zu setzen, eine Methode, bei der Sie einen direkten Verweis darauf haben, wo diese Logikart zurück Art von Operation geschieht , weil Sie möglicherweise dieselbe Art von Logik in mehreren -Handler. Das würde also die Wiederholung der gleichen Arten von Abfragen und gleichen Arten von Einschlüssen und allem über mehrere Handler hinweg reduzieren . Wenn Sie es nur in einem Repository-Bereich haben. Der Nachteil von Repositories ist jedoch, dass, weil, wie spezifische Dinge werden können? Ja, wir haben das generische Zeug, aber offensichtlich ist dies kein generischer Befehl, jede einzelne Funktion unserer Domain Objekt mich die gleiche Weise verwenden. Wir müssen eine bestimmte Methode haben und dann werden wir wahrscheinlich ein Kaninchenloch mit vielen spezifischen Methoden in unserem Repository landen . Das ist also eine der Don't -Sites, das Repository-Muster weiß, wie ich sagte, wenn Sie alles hier im Handler tun, würde es funktionieren. Aber noch einmal, der Nachteil davon ist, dass Sie diese Art von Operation über mehrere Handler wiederholen müssen . Und dann wiederholen Sie Code an mehreren Stellen. Und dann könnte die Modifikation auf lange Sicht schwierig werden. Das ist also die Überraschung Alpha. Wenn Sie also einen Blick auf unsere Schnittstelle werfen, würden Sie hier sehen, dass es sowohl für die Liste als auch für das Individuum gibt. Jetzt ist die Jury draussen, ob du beides brauchst. Der Grund, warum ich die enthalten 14 und die Liste, natürlich, ist, dass in der Liste, die verlassen Zuteilungen, Ich möchte den verlassen Namen und die d, Der verlassen Name und der tote Blatt Typ Name und die dy. Also müsste ich hier die Details einbinden. Und dann, wenn Sie einen von ihnen betrachten, möchten Sie auch die Details sehen. Also habe ich das gerade gemacht und das Gleiche getan. Und wenn Sie mit vielen von uns arbeiten, müssen Sie schnell navigieren. Also werde ich nur diesen blauen Pfeil oben hier oben verwenden, um Speicher zu synchronisieren, ist dieses Dokument schnell und dann Anfragen hinterlassen. Sie sehen, dass ich ähnliche Methoden habe, weil wir in den Urlaubsersuchen wissen müssen, welche Art von Urlaub angefordert wird. Und wenn ich die Liste ansehe, möchten Sie sehen, dass dieser Blatttyp an diesem Datum angefordert wurde, et cetera. Ordnung. Nun, was unsere Urlaubsanträge betrifft, habe ich noch eine Slide-Überraschung und ich hoffe, dass ihr das schon gemacht habt. Aber die Abfragen sehen ziemlich gleich aus. Aber in Bezug auf die Anfragen eher, aber in Bezug auf den Rückgabetyp, würden Sie feststellen, dass ich Urlaub Anfrage Detailanforderung erhalten habe, die die Urlaub Anfragen DTO zeigt, jedoch für die Liste und wir diskutierten, warum wir die Details trennen würden früher. Wir haben verlassen Anfragen Liste Detail. Die Liste bestimmt also eine Liste der Details, die für die Liste spezialisiert sind. Und dann geben die Details das Detail mit viel mehr Details zurück. Für die Abfragen. Ähnliche Bedenken für die Liste der Urlaubsanfragen, Anforderungsbehandler. Natürlich gibt es die Liste der Urlaubsanfragen DTO zurück. Und der Handler sieht ziemlich ähnliche Wörter aus, die ein Löschanforderungs-Repository aufrufen und die get leave Anfragen mit Details Ähnlichkeit aufrufen. Wenn wir uns den Detail-Handler ansehen, ist es das Gleiche, außer dass wir nur das Blattanforderungsdetail zurückgeben, das Labor, das dies einrichtet haben Sie vielleicht bemerkt, dass Sie viele rote Linien erhalten , wenn Sie sind nicht übereinstimmende Typen. Und wenn Sie hier den falschen Datentyp hätten oder der falsche Anforderungstyp referenziert wird, würde alles brechen. Es ist also sehr, sehr streng. Wenn Sie mir gesagt haben, dass die Anforderung den Typ der Anforderung DTO verlassen erwartet, können Sie hier keinen anderen Datentyp in diesem Handler einfügen , den Sie mitteilen, dass sie mit dieser Anfrage umgehen sollte. In Ordnung, also kannst du einfach sehr, sehr vorsichtig sein. Und sobald Sie sich an das Muster gewöhnt haben, werden diese Dinge natürlicher kommen. Ich kann nur zuweisen, wenn es anfänglich etwas frustrierend ist. Aber wieder einmal haben Sie den Code, auf den Sie verweisen müssen, damit Sie immer anhalten können, wenn Sie es brauchen und diese Code-Bits in Ihrer Anwendung entsprechend replizieren können. In unserer nächsten Lektion werden wir uns nun mit dem Einrichten unseres ersten Befehls beschäftigen. Und der Befehl würde noch einmal die Daten in der Datenbank erweitern. Also werden wir uns ansehen, was es braucht, um Setup zu erstellen, Befehl für jedes unserer Domain-Objekte zu erstellen. 10. Befehlszeichen: Willkommen zurück Jungs. In dieser Lektion werden wir einen Blick auf das Einrichten von Befehlen werfen. Also Befehle noch einmal erweitern die Daten und wir werden anfangen mit oder erstellen Befehl. Wenn Sie sich jetzt meinen Projektmappen-Explorer ansehen, würden Sie feststellen, dass ich ein paar weitere Dateien habe und einen umstrukturierten D2L-Ordner habe. Lassen Sie mich einfach alles andere zusammenbrechen, damit Sie sich auf diesen Abschnitt konzentrieren können. In den frühen Phasen der Planung dieser Art von Architektur werden Sie immer Dinge ändern, weil es gut ist, es direkt von null zu bekommen , im Gegensatz zu später, wenn Sie viele verschiedene Dateien haben und mehr, für -Instanz aktualisieren, sind die Aktualisierungen beim Verschieben Eigentum dieser anderen Dateien. In den frühen Stadien der Einrichtung der Details hatte ich angegeben, dass Sie wahrscheinlich einen Ordner für die Details haben möchten und dann die verschiedenen Arten von Details darin haben würden. Also haben wir das mit den Anfragen gemacht, bei denen wir die Urlaubsanfragen D2 hatten und Anfragen Listendetails löschen stattdessen den Anforderungsordner verlassen. Also habe ich dieses Konzept gerade auf die anderen Details erweitert, wo ich einen Urlaub Allokation-Ordner und Elif Typ-Ordner habe und dieses eine Blatt so tief im Detail benenne. Lassen Sie mich das einfach korrigieren. In diesen Ordnern werden wir die verschiedenen Details haben. Und wieder einmal, es ist nicht unbedingt notwendig dass es mehrere Details oder Details zu einem Zweck hat. Aber ich werde Ihnen zeigen, warum es vorteilhaft ist, das manchmal zu tun. Bei Blatttyp ist das Risiko gering. Wir haben Blattdetails. Sie benötigen lediglich einen Namen und die Standardanzahl von Tagen. Das ist einfach genug für mich. Diese Daten laufen sehr wenig Risiko, über unsere Underbelichtung etwas für einen der Operationen, die wir leicht mit diesem Detail erstellen können, können wir einfach auflisten und wir können die Details betrachten. Es ist sehr einfach. Bei Urlaubsersuchen hatten wir jedoch besprochen, dass die DTO weitaus mehr Details enthält. In einer Listeneinstellung brauchen wir nicht so viele Details. Sie brauchen wirklich nur die Details des angeforderten Blatttyps, das Datum, an dem es angefordert wurde, und ob es genehmigt wurde. Jetzt müssen wir im Create nicht mehr darum bitten, dass der Verbraucher all diese Details zur Verfügung stellt. Denn wenn Sie vergleichen Zahnurlaubsanfragen erstellen, brauchen wir wirklich nicht die Datumsoption. Und wenn jemand einen Urlaubsantrag erstellt, wenn ich um einen Urlaub bitte, gibt es keine Datumsaktionen. Das muss also nicht zur Verfügung gestellt werden. Das angeforderte Datum, das von uns eingegeben werden kann, durch das System. Das brauchen wir nicht vom Benutzer oder vom Verbraucher zu bekommen. Das Start- und Enddatum kurz. Das sind essentiell. Wir müssen den Blatttyp kennen. Wir müssen nicht das gesamte Objekt des Blatttyps kennen. Wir brauchen nur die Kennung des angeforderten. Und zu diesem Zeitpunkt ist es weder genehmigt noch abgesagt. So kann ich ein bestimmtes Detail haben und wie ich spreche, sehe ich, dass ich zusätzliche Verschmelzungen habe, aber ich habe eine erstellen Urlaub Anfragen DTO, die das Startdatum haben wird, das Enddatum, die Kennung für den Blattsterben angefordert wird. Und noch einmal kann das System das angeforderte Datum sehen. Und ich muss das eigentlich zu einem NULL-Wert machen. Also werde ich diese Gelegenheit nutzen, um das anzupassen. Das muss also NULL-fähig sein, aber ich brauche den Absender im Creates nicht. Ich nehme alles zusammen, erstelle in der Urlaubsanfrage, ich werde es nullbar machen, weil Abzugsregel wirklich bedeuten, wann sie genehmigt oder abgebrochen wurde. Richtig? Und dann in ähnlicher Weise werde ich das nur bis zur Domain machen. Wieder einmal ist es gut, diese Dinge früh zu sehen und sie anzupassen, weil wir die Datenbank noch erstellt haben, also müssen wir uns keine Sorgen darüber machen, dass dies zu viel zerrissen wird. In Ordnung? Deshalb habe ich eine spezielle DTO zum Erstellen der Urlaubsanforderung, die von der Auflistung unterscheidet, die sich von den Details unterscheidet. In einem anderen, wenn wir die Urlaub Zuteilung und Aufhebung hat eine Reihe von diesen, die Details des Blatttyps, der damit zusammenhängt, Kennung und die Periode. Es ist ähnlich wie die Urlaubsanfrage. Ich brauche die Details des Blatttyps zum Zeitpunkt der Erstellung nicht. Wenn wir also über das Überschreiben sprechen, bedeutet dies, dass wir der Client-Anwendung die Möglichkeit geben , zu viele Daten zur Verfügung zu stellen. Und dann ist dies, wo Hacking und schlechte Daten und Leute Anomalien in Ihrer Datenbank einführen, so passiert das. Dies ist also ein guter Weg, um einzuschränken, was bei einer Operation passieren kann. Also wissen Sie das. Haben Sie ein gutes Verständnis dafür, warum wir mehr Details eingeführt haben. Lassen Sie uns einen Blick auf die Befehle werfen. Also werde ich mit der einfachsten beginnen, die die Blatttypen Befehle sind. Ich werde gehen, um zu beantragen und ich werde eine neue Klasse erstellen. Und dieser Gaumont wird sehr spezifisch sein, um Blatttyp Anfrage zu erstellen. Also, das ist die Anfrage, einen Blatttyp zu erstellen und ging voran und fügen Sie ihn hinzu und machen Sie es zu einer öffentlichen Klasse. Und dann erbt das hier, wie wir es von mir wissen. Und es wird zurückkehren, ich werde es eine ganze Zahl 0 zurückgeben. Diese ganze Zahl wird sein. Der Name oder sorry, die ID des Wertes oder des Datensatzes wurde erstellt. Okay, also erstellen Sie, wir sagen Ihnen nur die ID dessen, was Sie es erstellen. Wir wissen nicht, was der Kunde nach der Erstellung tun muss, aber wir geben ihnen nur die ID gespeichert, sie müssen danach auf die Detailseite gehen. Das liegt an ihnen, aber wir sagen Ihnen, dass es erfolgreich war. Hier ist die ID für den neuen Datensatz. Jetzt im Befehl, was wir haben werden, da wir wissen, dass mein null unser passender Handler für diese Anfrage ist. Also erben wir von mir Handler. Und ich Request Handler wird die Create Leaf Type Anfrage implementieren. Gehen Sie weiter und schließen Sie alles an, was fehlt. Und es wird sehen, dass es eine ganze Zahl zurückgibt. Jetzt, wenn wir die Schnittstelle implementieren, werden Sie sehen, dass wir diese Aufgabe erhalten, die eine ganze Zahl und unseren Handler zurückgibt. Jetzt springen wir zurück zu ihren Anfragen für ein bisschen. Und es gibt wenige Muster, die Sie möglicherweise in der Anforderung zur Erstellung sehen. Ein Muster besteht darin, dass Leute tatsächlich alle Felder schreiben würden , die, wenn Sie einen Datensatz für dieses Jahr erstellen möchten die Anforderungen zum Erstellen eines Datensatzes für diesen Typ senden. Sie würden die Felder in der tatsächlichen Anfrage eingeben, um zu sehen, dass dies die Gebühren sind, die Sie mit der Anfrage senden dürfen. Und in diesem Moment dient diese Anfrage im Grunde dem Zweck meiner Details, die ich gerade hier definiert habe. Nein, ich persönlich, ich mag es nicht zu mischen und zu passen. Ich mag keine Details hier, aber wenn ich es schaffe, habe ich die Felder hier. Und dann, weißt du, ich weiß nicht, wohin ich gehen soll, und ich muss ändern, was passiert, manchmal erinnere ich mich nicht. Stattdessen halte ich alles auf einer Detailebene und die Anfrage ist wirklich nur ein Mechanismus, um die Daten zu übertragen. Der DTO stellt also die Daten dar und die Anfrage ist nur dieser Transport. Mit allem, was gesagt, Ich werde unsere Eigenschaft in dieser Anfrage für Urlaub Typ DTO vorstellen . Also diese Eigenschaft ist, was der Verbraucher mit der Anfrage füllen und senden Sie es über. Also in unserem Befehl wissen wir, dass wir sagen, Punkt Blatt Diabetes, das ist, wo die Daten sind. Wenn wir also mit Blatttypen und Auto-Mapper interagieren, müssen wir unsere üblichen Verdächtigen in unserem Konstruktor injiziert werden. Und für die Geschwindigkeit wieder gehen diese zurück zu einem der vorhandenen Handler und kopieren und einfügen, ändern Sie den Konstruktornamen. Und dann fügen wir einfach alle fehlenden Referenzen ein. Alles klar, um klüger zu arbeiten, nicht härter. Nun, da wir alle Werkzeuge haben, die wir brauchen, wie richten wir unseren Handler ein, um diesen Datensatz zu erstellen? Aber bevor ich weitermache, werde ich eine leichte Anpassung vornehmen. Also ein weiteres Muster, das Sie sehen werden, und ich denke, ich werde es dieses Mal verwenden, nur weil es für mich ist, es ist sauberer anstelle von Anfragen. Also, wenn wir es mit Befehlen zu tun haben, nein, es wird nicht unsere Bitte sein, weil ich bitte ist, wenn du nach etwas fragst, dieser Befehl ist, wenn du etwas erzählst. Sie wollen einen Befehl. Also statt uns Anfrage im Namen hier zu verwenden, wo wir sagen, erstellen Blatttyp-Befehl. Also, indem ich die Quelle umbenenne, kann ich die IntelliSense laden, um sie auf der ganzen Platine umzubenennen, aber ich werde die Datei manuell umbenennen. Also haben wir Blatttypbefehle erstellen, so dass wir sicher wissen, dass dieser ein Befehl ist, und es ist offensichtlich, dass der Handler seinen ganzen Befehl tragen soll. Also Befehl Geben Sie ein, in Ordnung, und aktualisieren Sie alle anderen Referenzen sind auf der Stelle. Also denke ich, das ist eigentlich sauberer und einfacher für die Augen. Es ist eine Unterscheidung zwischen dem, was ich Klassen anfordere, was unsere Befehlsklassen für unsere Operation lösen. Was wir tun werden, ist, den Blatttyp zu definieren, um gleich zu sein. Und dann werden wir nur Auto-Mapper verwenden, um in Urlaubstypen zu kartieren. Also mappen wir von den Details auf das Domain-Objekt dieses Mal unser eigenes. So Mapper Dartmouth Blatt-Typ, verschachtelt tippen Sie unsere Suche auf Anfrage Punkt Blatt Typ BTO. Okay, also gehst du einfach vor und fügst alles, was fehlt. Da gehen wir. Also, jetzt sagen wir, verlassen Typ ist gleich , um mir die gewickelte Version davon in das Domänenobjekt zu bekommen. Dann führen wir unsere, dies wird sagen, verlassen Typ ist gleich und unsere Gewichte auf wir werden unser Blatt Typ Repository dot Add Methodenblöcke nennen , richtig? Denken Sie also daran, dass es tatsächlich das Objekt oder etwas vom gleichen Datentyp zurückgibt , richtig? So verlassen Typ wird jetzt aktualisiert werden, weil nach Entity Framework, das ist, was wir als unser RM verwenden werden. Nachdem es seine Operation ausgeführt wird, wird die ID zu aktualisieren. Also geben wir das Objekt mit aktualisierter ID zurück und wissen, dass wir diese ID haben. Wir können sagen zurück, verlassen Typ, Punkt-ID. Da gehen wir. Also wissen Sie, dass der Befehl behandelt wurde. Nolan, wir sehen es an, wir sehen, dass es wirklich nicht so kompliziert war. Es sind nur drei Zeilen, in denen die Anfrage mit den Daten abgerufen wird. Und dann werden wir es den Domänenobjekten zuordnen. Wir werden dann Bosse oder innerhalb eines Repositorys oder für die Operation stattfinden. Und dann geben wir nur die Idee zurück und das ist es für den Befehl create leaf type. Also können Sie hier einfach Pause machen und ihn bitten, es mit den anderen zu tun. Ich werde es tun und dann können wir Notizen vergleichen. Okay, also habe ich übersprungen und ich habe die Befehle implementiert , die Befehle für die anderen beiden Domänenobjekte erstellen. Wenn Sie es also genau betrachten, sehen Sie, dass es ziemlich dasselbe Zitat ist, abgesehen von den Namen und den beteiligten Repositories, es ist ziemlich der gleiche Code. Dies ist also der Leave Allocation Command Handler. Sie können pausieren, Sie können es bei Bedarf replizieren. Aber das ist unser Schaffen-Handler und unsere Karriere-Suche. Nur, dass erstellen lassen Anschuldigung Detail statt der Urlaub Anschuldigung Detail. In Ordnung. Ähnlich für die Urlaubsanfrage, gleiche Code, die gleiche Struktur, richtig? Und dann der Befehl, es nimmt nur die Urlaubsanfragen Details, um die Anforderung Detail zu erstellen. So sehen Sie, dass alle diese Art von sehen sehr ähnlich. So können Sie voran gehen und diese in Ihrem Code replizieren. Und wenn wir zurückkommen, werden wir uns die anderen Befehle ansehen , die aktualisieren und löschen würden. 11. Verfasse die Befehle mit MediatR: Na gut, Leute, willkommen zurück. Wie Sie bemerkt haben, ist mein Bildschirm leer. In dieser Lektion werden wir über das Hinzufügen der Update- und Löschhandler sowie aller Assets sprechen , die zu ihnen gehören. Also mein Bildschirm ist leer, weil ich einige Assets hinzugefügt habe und ich werde sie eins nach dem anderen mit Ihnen durchgehen und Sie können fortfahren und sie replizieren. Aber ich möchte, dass wir die Entscheidungen verstehen, die wir an diesem Punkt treffen, da es sich um kritische Entscheidungen handelt. Und diese Art von Architektur, die Dinge, die Sie da hineinlegen, alles entscheidungsbasiert. Wieder einmal sind sie relativ zu dem, woran Sie arbeiten, Ihrem Team und der allgemeinen Anwendung, was Sie erreichen wollen. Lassen Sie uns also beginnen, indem wir uns die Details ansehen. Wo sind sie? Ging durch die Details und wir Art von trennen sie Art durch Ordner, so dass wir alle Details relativ zu einem Domain-Typ ziemlich leicht sehen können. Aber an diesem Punkt hatten wir einen VT0 für Blatttyp, und wir hatten gesagt, dass, okay, das war ein geringes Risiko, weil es für viele verschiedene Operationen verwendet werden könnte. Seitdem habe ich es in zwei Teile zerbrochen. Und der Grund dafür ist, dass Sie Blatt tab2 erstellt haben , die sich von Blatttyp D2 und allen unterscheidet. Warum? Da Blatttyp Detail erbt von der Basis Detail und Basis D2, denken Sie daran, gibt uns die ID, kennen das Risiko dieser. Und noch einmal, Zweck des Details ist es, irgendwie zu reduzieren, was wir über Posting aufrufen werden. Wenn ich einen Blatttyp erstelle, benötige ich keine ID. Ich möchte dem Verbraucher nicht die Möglichkeit geben, eine ID bereitzustellen , weil das nur Probleme verursachen würde. Ich gebe ihnen genau das, was sie brauchen, um durch ihre Operation zu kommen. Also habe ich ein neues Detail für Blatttyp erstellt, wo sie nur Namen und Standardakte erhalten. Sie können kein ID-Feld angeben. Blatttyp Detail kann für alles andere verwendet werden, für die Bearbeitung, für die Anzeige, weil gut, es hat diese Felder sowie BCE, die die ID ist. Nun, da Sie am Ende mehr und mehr Details erhalten und Sie fühlen sich wiederholt über die verschiedenen Details, dann sollten Sie vielleicht überlegen, einen gemeinsamen Ordner innerhalb dieses Unterordners bereits zu haben , um diese Eigenschaft zu definieren dass dieses Detail sowieso haben muss. Also jedes Blatt tab2, das mit den meisten Hafnium kommen wird und es muss Standardtage haben. Sie könnten eine Basisklasse definieren, wenn Sie sie benötigen. Okay, jetzt können wir zu den Urlaubsanweisungen übergehen haben drei Details zur Urlaubszuweisung an dieser Stelle, und ich werde auf einen Fehler hinweisen, den ich in einem von ihnen gemacht habe. Dieser Fehler war zu haben erstellt verlassen Allokation Details erben von diesem Detail. In Ordnung, also musst du vorsichtig mit diesen Dingen sein, wenn wir versuchen, streng zu sein. Das war also ein Fehler meinerseits. Erstellen von Urlaubszuordnungsdetails sollte noch einmal absolut keinen Bezug auf einen Primärschlüssel haben. Aber dann brauchen wir die anderen Felder. Die Updates benötigen jedoch Zugang zum Basis-DTO für unsere Aktualisierungszwecke. Nun, es könnte sein, dass wir gesagt haben, okay, nun, noch einmal, erstellen Sie das Basisdetail, von dem jeder erbt. Oder wir könnten einfach die Kugel beißen und sagen, wir werden 14 erstellen oder aktualisieren wenn die ID bereitgestellt wird und wir wissen, dass es ein Update ist , wenn es nicht verhindert wird und wir annehmen, dass ich erstelle, könnte leicht Argumente sein, die ich nicht sehe, Nein, ich sehe ja nicht. Es hängt davon ab, wie detailliert Sie erhalten möchten, und dies sind Ihre Entscheidungen, die Sie basierend auf Ihrem Kontext treffen müssen. Ich verweise nur auf die Unterschiede und die Risiken entsprechend. Also werde ich sie so ausbrechen. Nein Für Urlaub Anfrage geht durch noch eine andere Ebene. Wir haben also die Angaben zur Urlaubsanforderung, wenn sie damit vertraut sind. Wir haben das Listendetail, das bereits festgestellt hat, warum das anders ist. Wir haben das Create, das wieder einmal falsch ist, zumindest in meinem Kontext, das von diesem erbt, was ich null charakterisieren werde. Und dann muss ich die Anforderungsdetails anders als geändert Urlaub Anfrage Genehmigung Detail aktualisiert haben ? Nein, du wirst fragen. Ok. Also, warum haben Sie beides? Weil beide davon reden, die Daten zu erweitern. In Ordnung. Nun, wieder einmal ist es eine Frage des Hosts, der Sie sein wollen also dient das Update dem Zweck, dem Benutzer oder dem Verbraucher zu erlauben, dem Endbenutzer zu erlauben, seine Anfragen zu aktualisieren. Sie wollten vielleicht die Startdaten oder das Ende ändern, vielleicht haben sie Urlaub gewählt, wenn dies krank sein sollte. Vielleicht wollen sie neue Kommentare eintragen oder sie wollen es einfach absagen. Also gebe ich ihnen genau, was sie mit diesem DTO tun können , wenn sie ihre Anfrage zur Aktualisierung senden. Dies sind die einzigen Dinge, die aktualisiert werden können. Ändern Sie jedoch die Genehmigung des Urlaubs. Anfrage, Entschuldigung, lassen Sie Anfrage Genehmigung Details, sorry, würde nur die Möglichkeit haben, zu ändern. Es ist genehmigt DSR null. Also sagt der Genehmiger wirklich nur Ja oder Nein. Ich meine, wenn Sie mehr Felder wie zusätzliche Befehle und irgendetwas hätten , könnten Sie sie in DTO hinzufügen. Natürlich müssten sie die Domain-Objekte präsentiert werden. Aber mein Punkt ist, dass ich das Detail hier verwende, um mir zu helfen, bestimmte Geschäftsregeln und bestimmte Verhaltensweisen durchzusetzen , die meine Anwendung in der Lage ist. Und, und noch einmal, Ich habe Situationen gesehen, in denen es eine flache D Teal und Entscheidungen werden in der 100 getroffen, die auf der Grundlage der vorliegenden Daten, vielleicht in der Anfrage sind im Detail. Dies ist die Art der Operation, die durchgeführt werden soll. Es hängt also davon ab, wie viel Sie ETL brechen möchten, um diese Granularität zu haben. Also wissen Sie, wenn es eine Genehmigung beantragt ist, wissen Sie genau, zu welchem Handler Sie gehen sollen. Oder Sie können einen großen Befehlshandler haben, der die Daten und eine Reihe von if-Anweisungen nimmt, um zu sehen, ob es ist, wenn die ID vorhanden ist, dann, wenn sie nicht vorhanden ist, dann ist es, Aber wenn es vorhanden ist und dieses Flag nicht null, dann nehmen Sie an, dass es sich um eine Genehmigung handelt. Du könntest es so machen, aber ich mache es nicht so. Ich bevorzuge es zu wissen, dass ich, wenn es eine Genehmigungsanforderung ist, diesen Änderungsgenehmigungsbefehl habe. Wenn es sich um ein Update handelt, handelt es sich um einen Update-Befehl und weiß genau, wohin Sie gehen müssen, um was zu tun. Also, jetzt, wo wir diese detaillierte Erklärung aus dem Weg haben, werde ich zu den Features, Ordnern in Futures, in Urlaubsanlagen und lassen Typen zumindest ich habe bereits die neuen Handler und ihre Befehle definiert. Werfen wir einen Blick auf das einfachere. Also haben wir den update leave type Befehl. Und dieser Befehl für den Blatttyp nimmt nur unsere Anfragen, die von Eric Quest erben, wie wir wissen, aber dann gibt es zurück, was wir eine Einheit nennen werden. Wenn Sie also nur den Mauszeiger über, müssen Sie sehen, dass es ein Vermittler bereitgestelltes Konstrukt ist, das nichts wie Leere darstellt, oder? Kein Inhalt also im API-Design Wenn Siealso im API-Designein Update durchführen, würden Sie normalerweise bei 202 zurückkehren, wenn ich mich nicht irre, was für keinen Inhalt kurz ist. Es bedeutet also, dass es erfolgreich war, aber ich habe Ihnen nichts zu zeigen. Das ist im Grunde das, was Einheit ist. Und dann nehmen wir diesen Blatttyp DTO als Eigenschaft. Ich habe die Befehle noch nicht in den Handlern implementiert, also können wir das zusammen tun. Ich zeige nur, dass wir das gleiche Konstrukt für den Update leave allokation-Befehl haben , wo wir die Aktualisierungsurlaubszuweisungsdetails nehmen und diese Einheit zurückgeben. Und wir haben diesen Befehl entsprechend definiert, auch leer. Also werden wir diese beiden zusammen machen, weil die ziemlich einfach sind. Und dann werden wir einige Zeit damit verbringen die Urlaubsanträge und die Geschäftsregeln dort zu erkunden. Jetzt der Workflow für unseren Handler, und ich werde mit dem Leaf Type Command Handler beginnen. Alles klar, der Workflow hier ist, dass wir den ursprünglichen Datensatz abrufen müssen , um diesen Ursprung zu aktualisieren erforderlich sind, und dann drei, senden Sie alles an die Datenbank und dann die Einheit zurück, oder zumindest etwas zu sagen, es war erfolgreich. Also zwei Ansätze. einen können Sie das Repository verwenden, um diese spezifische Methode zu haben , da es dann im Fall der Urlaubsanforderungen bestimmte Methoden geben kann. Und dann wieder, du gehst das Kaninchenspielzeug runter. Mit sehr, sehr spezifischen Methoden in jedem einzelnen Repository entlang der Linie. Oder Sie können einfach die meiste Arbeit in einem Handler erledigen, was ohnehin dafür ist. Ordnung. Also werde ich nur sagen, var leave type ist gleich dem Typ Repository, Git, zu verlassen. Und dann schauen wir in die Anfrage, suchen in das Blatt, um die ID zu betrachten. Nun, ein anderes Designmuster, das ich gesehen habe, ist, wenn es sich um einen Update-Blatt-Typ handelt, würden sie den regulären Blatttyp verwenden sagen wir, der nicht die ID hat, aber dann die ID-Eigenschaft in die Anfrage oder den Befehl Objekt, so dass wir, wenn Sie die aktualisierte machen, um die ID innerhalb dieses Objekts enthalten. Und dann ist das Detail nur sich selbst. Es gibt so viele Möglichkeiten, dies zu tun. Und wieder einmal, diejenigen, die Sie verstehen, was Sie tun, können Sie mir die beste Implementierung basierend auf Ihrem Kontext tun. Hier. Der Leave-Typ wird basierend auf der ID aus der Nutzlast abgerufen, die mit der Anfrage eingeht. Und dann können wir Mapper nicht MOP sehen. Und dann ist Mapper-Punktkarte ziemlich einfach, in dieser Situation, erhalten Sie die Anforderung Gedankenblatt Typ D2. Und beachten Sie, dass ich nicht angeben, ich muss dieses Mal tippen. Ich verwende Klammern, Mapper-Punktkarte, offene Klammern. Und dann sehe ich, dass das die Quelle der Daten ist. Und ich möchte, dass Blatttyp, der gerade aus der Datenbank gewonnen wurde , das Ziel der Daten ist. Und ich bekomme die grüne Linie, weil ich es auf der Leitung versäumt habe. Ich entschuldige mich. Also gehen wir hin. Also mapper dot map und dann es sieht bitte nur aktualisiert, was auf der rechten Seite ist, mit was auch immer auf der linken Seite ist, das könnte anders sein, ob es anders ist oder nicht, dies, bitte aktualisieren Sie es, weil das Update wird über senden. Und deshalb muss unser Detail so viele Felder haben, wie viel die Daten, das Domänenobjekt selbst wie möglich. Es ist gut. Dava Name wird Standardtage haben. Wir wissen nicht, was sich geändert hat, deshalb sehen wir Herbst oben, aktualisieren Sie einfach alle Werte. Wenn das Blanco den Namen, dann werden wir es auf einen leeren Namen aktualisieren. Hoffentlich haben sie es nicht getan. Wenn sie den Namen jedoch nicht geändert haben, dann ist die Erwartung, dass der gleiche Name zurückkommen wird. Also noch einmal, wir können nicht erklären, was Kinn gewesen sein könnte. Wir sehen also nur, bitte aktualisieren Sie den Blatttyp mit den entsprechenden Werten, die vom Objekt auf der linken Seite kommen. Und dann werden wir unser Neve-Repository-Update belasten. Und dann senden wir hier unsere Blatttyp Post Mapping oder senden sie an das Update. Und dann geben wir einfach den Punktwert der Einheit zurück. Und das war's. Das ist unser Update-Vorgang. Nun, ich habe diese rote Linie hier oben, weil ich int und nicht Einheit habe. Also nach mir diese Veränderung, ist alles in Ordnung. Also, das ist es für Fettleibigkeit im Blatttyp oder was? Der Blatttyp. Also werde ich das eigentlich nur kopieren. Ich werde mir nicht zu viel Arbeit geben. Ich werde überspringen, um die Urlaubszuweisung zu aktualisieren. Und das einzige, was wir hier anders machen werden , ist, dass ich anstelle des Blatttyp-Repositorys das Leave-Allokation-Repository verwenden werde. Anstatt Blatttyp DTO zu sehen, sehe ich Urlaub Allokation BTO. Und anstatt den Objektblatttyp aufzurufen, nenne ich es verlassen Allokation, alles andere ist ziemlich Standard und ziemlich gleich. Und das wird unsere Update-Anfrage bearbeiten. In Ordnung, also habe ich vorangegangen und die Befehle für die Leave Request für die Aktualisierung von LaCo abgeschlossen, wir sehen nein, dass es nicht so kompliziert ist oder so habe ich den Update leave request Befehl und den entsprechenden Handler gemacht . Also unser Urlaub Anfragen Command Handler von der Befehl Rückgabeeinheit genommen. Und es ist nur, den Unterschied noch einmal zu kennen, ist das Repository, das verwendet wird, aber es ist ziemlich die gleiche Operation. Nun eine Sache, die Sie vielleicht in Betracht ziehen möchten, ist die spezifischen Geschäftsregeln, unsere eigenen diese Art von Operation. Also ja, der Code, es sieht gleich aus, aber wenn Sie eine Urlaubsanforderung aktualisieren, könnte es andere Dinge geben, die passieren müssen. Richtig. Also im Falle der Änderung, Anfrage, Änderung und lassen Antrag Genehmigung, wo wir nur genehmigt oder nicht. Wir müssen auch die Maßnahmen festlegen, die wir wahrscheinlich auch einige andere Dinge aktualisieren müssen. Ich denke, Sie werden gut sein, wenn wir eine bestimmte Funktion in unserem Repository haben , um die Änderungsanfrage zu bearbeiten. Jetzt ist die coole Sache an Anfragen, dass wir nicht unbedingt unsere Anfrage pro Stunde Anfragen pro ganze Zeit haben müssen. Ich könnte tatsächlich die gleiche Anfrage und den gleichen Handler wiederverwenden, um diese Art von Operation zu behandeln. Schauen wir uns diese Situation an. Also innerhalb des Updates, verlassen, nicht verlassen Zuweisung, Entschuldigung, innerhalb verlassen Anfrage Befehl, wir könnten die verlassen Anfragen DTO haben, aber ich könnte auch eine Eigenschaft der Typänderung verlassen Anfrage Genehmigung DTO. Diese Anfrage ist also in der Lage, eines dieser Objekte zu haben. Jetzt im Handler kann ich eine Entscheidung treffen und die entsprechende Methode basierend darauf aufrufen , weil es immer noch ein Update-Befehl ist, richtig? Also innerhalb dieses Update-Befehlshandlers kann ich etwas mehr Logik einfügen. Ich kann sehen, ob Anfrage Punkt verlassen Anfrage Detail nicht gleich null ist, dann ist dies die Route, die ich nehmen möchte. Ich kann das andere sehen. Und ich werde es sehr explizit mit diesem anderen beschleunigen, weil ich nicht weiß, ob ich vielleicht in der Zukunft einige andere Geschäftsregeln haben könnte. Also werde ich mich nur mit diesen beiden expliziten Situationen begnügen, in denen es entweder so ist, dass dies anders sein sollte, wenn sonst, wenn Anforderungspunktänderung, beantragen Sie Genehmigung D2 nicht gleich null ist, dann tun Sie Das, richtig? Und dann wollte Überstunden versuchen und Routine man zurückkehrt. Also werde ich all das nehmen und sagen, dass Sie diese Operation ausführen , wenn die Urlaubsanforderungsdetails nicht gleich null sind. Das bedeutet also, wer auch immer verbraucht, wer mit diesem Handler unterbricht , der seine Anfrage sendet, muss sicherstellen, dass die Füllung. Die entsprechenden Felder entsprechend dem, was sie wollen. Einige zeigen nur einen anderen Geschmack, weil er das RequestHandler für jede einzelne Situation, jedes einzelne Szenario Peeringgehen könnte das RequestHandler für jede einzelne Situation, jedes einzelne Szenario Peering , aber dann können Sie sie irgendwie zusammen, wie ich sagte, den Handler. Einige Leute setzen viel Geschäftslogik in diesem Abschnitt. Also noch einmal, das liegt an dir. Also, wenn die Änderung verlassen Antrag Genehmigung DTO ist nicht gleich null, wir haben eine Entscheidung zu treffen. Was genau werden wir tun? Wir wissen, dass wir Anfragen auf die eine oder andere Weise abgerufen haben und hinterlassen. Wir werden nicht die umfassende Kartierung machen, die unsere wirklich tun wollen ist schließlich als die Updates Boote mit anderen Dingen passiert. Also werde ich warten rufen, Anfragen verlassen, Repository, Genehmigungsstatus ändern. Nein. Was machen wir? Ich könnte ihm den Ausweis geben. Ich könnte ihm das Urlaubsanforderungsobjekt sowie den Status geben, in den es geändert werden sollte. Es gibt eine Reihe von Ansätzen, die wir annehmen können. Nein. Wir reden immer über das Wiederholen von Code, oder? Also sagen wir, ich mache das, ich gehe und hole die Urlaubsanträge. Und dann wäre dies relativ zur Änderung, der Anforderungsgenehmigungsdetails ID. Und dann kann ich sagen, geben Sie dieser Operation die Urlaubsanfragen, die ebenfalls abgerufen wurden. Der Wert aus dem Detailfeld für die Genehmigung, unabhängig davon, ob sie genehmigt ist oder nicht. In Ordnung. Nein, ich wiederhole diesen Anruf, um eine Urlaubsanfrage zu bekommen. Nein, ich kann diesen Aufruf nur relativ zu machen, wenn es die Anfrage war, die der TOR geändert hat , die Details der Urlaubsanfragen eintrug, denn wenn dies bekannt ist , kann ich diese ID nicht bekommen. Und wenn dies null ist, also nach einer Entscheidung treffen. Also siehst du all diese anderen Dinge? Nein. Okay, lassen Sie uns umgestalten. Um unser Leben leichter zu machen, gehen wir zum Befehl zurück. Und dann ging ich zu sagen, naja, nein, ich sehe einen guten Grund, bis der Verbraucher den Ausweis einschließt. Die ID muss auf diese beiden Arten vorhanden sein, aber die ID hier enthalten. Wenn Sie also die ID dort einfügen, kann ich leicht sagen, Anforderungspunkt-ID von außerhalb des if-Blocks. Und dann weiß ich, dass ich die Urlaubsanträge habe, die geändert werden müssen. Nun, wenn es das ganze Detail GameOver ist, dann gut. Ich weiß genau, was zu tun ist, wenn es nur die Änderungsanfrage ist. Ich muss es nicht speziell finden, aber dann habe ich es schon und ich kann einfach den Genehmigungsstatus übergeben. So kann diese Methode in unserem Ich werde Repository implementieren. Und ich werde es einfach nichtig machen. Es ist also nur diese Aufgabe. Und die Parameter wären DV, Anfrage und ein boolescher Wert. Nun, es muss NULL-fähiger Boolean des Genehmigungsstatus sein. In Ordnung, wenn wir das nennen, geben wir diese beiden Befehle entsprechend weiter. Dies ist also eine Möglichkeit, den Code zu schreiben. Ich bin sicher, du sitzt wahrscheinlich da und sagst, okay, wir hätten es wahrscheinlich so machen können, oder ich muss es so machen, für meine Situation, das ist in Ordnung. Aber solange wir die Flexibilität verstehen, die wir haben, wenn es um diese gesamte Request-Handler-Pipeline geht und wie wir verschiedene Szenarien umgehen können. Wir können den einen Handler verwenden, um die verschiedenen potenziellen Szenarien basierend auf der Anfrage zu behandeln , basierend auf den Daten in der Anfrage bereitgestellt. Und wissen Sie, Sie müssen nicht für jedes einzelne Szenario Peering haben , das Sie möglicherweise haben, aber Sie können einen Handler haben, der mehrere Szenarien abdeckt. In Ordnung, jetzt, wo Sie den Dreh haben, möchte ich, dass Sie voran gehen und die Delete Commons und Handler implementieren. Also habe ich weitergemacht und das getan. Und wir haben den Befehl Leaf Type löschen , der von IO-Anfragen erbt. Also beachten Sie, dass ich nicht habe ich anfordern und Datentyp das letzte Mal, wenn wir die Einheiten verwenden. Dies ist also nur die 0, die Sie nicht unbedingt auf diesen Datentyp setzen müssen, wenn er nichts zurückgeben soll. Dieser Löschbefehl hat also einen Parameter für die ID. Und dann innerhalb des Handlers, alles, was wir tun, ist, das entsprechend basierend auf der ID abzurufen, und dann senden wir es zum Löschen und dann geben wir nur die Einheit zurück. Und an diesem Punkt ist das allgemeine Thema für die Mall. Also ist es das Gleiche für die Urlaubsanfrage. Wissen Sie, ob Sie tatsächlich Funktionen zum Löschen einer Urlaubsanforderung bereitstellen möchten oder nicht. Das liegt ganz an Ihren Geschäftsregeln, denn es könnte sein, dass es kein hartes Löschen gibt, es ist nur ein weiches Löschen oder Löschen bedeutet wirklich Abbrechen, oder? Also, das würde es nur markieren, dass es abgesagt wurde, ignoriert, aber halten Sie die Aufzeichnung. Also zeige ich Ihnen nur, wie man die Funktionalität einsetzt. Aber dann noch einmal, die Geschäftsregeln und deren Anwendung sind relativ zu Ihrer Situation. Das ist es zum Einrichten der Lösch- und Update-Handler für unsere Domain-Objekte. Und so ziemlich das ist der Kern des gesamten Mediator-Musters gekoppelt mit dem C QR ist sputtered. Also, während wir weitermachen, was wir untersuchen werden, ist, dass es ein bisschen kugelsicherer wird, weil nicht wahr? Wissen Sie, dass alles passieren kann, jeder kann kommen und alles erschaffen, und es gibt keine wirklichen Regeln, um zu regeln, was gültig ist gegen das, was ungültig ist. Also werden wir versuchen, uns das Ganze anzusehen, das wir mit ungültigen Daten umgehen , und wie wir es ein bisschen universell und narrensicher machen können. 12. Validierung hinzufügen: Na gut, Leute, willkommen zurück. In dieser Aktivität werden wir eine Validierung für unsere Details und unsere Befehle einrichten. Nun, bevor wir weitermachen, gibt es eine schnelle Karren auf uns, die ich für den Code machen wollte , den ich im Update leave requests Befehl geschrieben habe. Ich hatte versehentlich die Details der Urlaubsanfragen verwendet. Also, wenn es in der Aktualisierung ist, dann sollten Sie Blatt Request Detail angenommen werden. Also, wenn Sie diesen Fehler erwischt und Sie Wagen es sich selbst getan haben, dann Lob an Sie. Wenn nicht, dann können Sie voran gehen und sich treffen. Das verändert mich. Kein Problem. Nun, worüber wir sprechen, wenn wir, zum Thema Validierung ist die Fähigkeit, sicherzustellen, dass die Daten, die wir erhalten, bevor sie in die Datenbank gehen, gut gültig sind, denn wie es steht, gibt es hier nichts, was uns von begehen, eine Spielzeugdatenbank ungültig machen. Und eine Sache, die sehr, sehr wichtig ist, ist die Datenintegrität. Sie möchten also nicht zwei Datensätze erstellen, bei denen wichtige Daten fehlen. Wir wissen nicht, welche Art von Urlaub. Es ist immer noch flach, also werden Sie es validieren wollen und dann natürlich abgelehnt, wenn es nicht den Standards entspricht. Nun, wenn Sie sind, wenn Sie MVC gewöhnt sind und denken Sie, TBL-Validierung und Sie sehen, dass wir auf die Modelle leicht unsere Datenannotationen setzen könnten , was sehr wahr ist. Ich habe festgestellt, dass dies nützlich ist. Aber wenn Sie dann über die Standardwerte hinausgehen möchten, müssen Sie anfangen, alte Erweiterungen und Salz zu bauen , was auch sehr gut ist. Aber dann werden wir in diesem speziellen Programm flüssige Validierungen verwenden, die eine Bibliothek ist, die es uns erlaubt, die fließende Syntax zu verwenden und sehr, sehr mächtige Regeln und Validierungsstrukturen sind unsere Eigenschaften in unserem Klassen. Also, um loszulegen, werden wir zum neuen Git springen und ich nehme an, ziemlich nach fließend gesucht. Und Sie sehen, dass all diese wunderbaren Suchergebnisse auftauchen. Keine Information. Die Dokumentation für diese Bibliothek ist sehr gut und Sie können es auf der Website für Invalidität Dotnet finden, und Sie werden sehen, wie wir dies erweitern und massieren und es zu seiner vollen Kapazität verwenden , um mit ihren Validierungsbedürfnissen zu helfen. Also werde ich diese Bibliothek für die Abhängigkeitsinjektionserweiterungen installieren . Und sobald das erledigt ist, können wir NuGet schließen und dann zu unserem Setup kommen. Aber eine Sache zu beachten, ich glaube nicht, dass ich das vorher erwähnt habe. Wenn Sie auf diese CSB-Datei klicken, sehen Sie tatsächlich, welche Pakete auf ihrer Version installiert sind. Wenn Sie also den genauen Paketnamen und die gewünschte Version kennen, können Sie tatsächlich so ausgerichtet in Ihren CSV-Datei-Blob-Build einfügen und es wird automatisch dieses Paket von NuGet für Sie erhalten. So können Sie diese Pakete auch installieren und lösen. Beginnen wir also mit unseren Validatoren. Ich frage mich, wo ich diese Validatoren hinstellen soll, ich werde einfach alles zusammenbrechen. Also können wir alle unsere Ordner irgendwie komprimiert sehen, okay? Und dann haben wir natürlich die Details. Die Details sind, wo unsere Validierungen passieren müssen, weil sie diejenigen sind, die die Entzündung in unserem Namen sehen. Wir müssen nicht diejenigen validieren, die für die Abfragen verwendet werden. Das ist irgendwie nutzlos, oder? Da die Lesevorgänge keine Validierungen benötigen. Die richtigen Operationen oder die Augmentierungsoperationen tun jedoch. Also werde ich, in einem der Ordner, lassen Sie mich mit dem einfacheren beginnen. Ich werde hinzufügen und neuen Ordner. Und ich werde es nur Validatoren nennen. Und dann werde ich eine neue Klasse hinzufügen. Und dann wird dieser ein Blatt Typ D2 Validator erstellen. Natürlich, um es öffentlich zu machen. Und dann werde ich es von einem abstrakten Validator erben lassen. Und dann werde ich den Namen der genauen Klasse übergeben, zu der es relativ ist. Also werde ich einfach voran gehen und alle fehlenden Referenzen einschließen. Und dann fügt es hinzu, dass mit fließenden Validierungsbibliothek und dann sind wir bereit zu gehen. Was wir also haben, ist ein Konstruktor. Also CTR Badewanne, Badewanne und wir bekommen diesen Konstruktor und dann können wir anfangen, Regeln zu definieren. Also lassen Sie mich nur einen kurzen Blick auf den erstellen Blatt Typ D2 werfen. Was würden wir dazu validieren wollen? Nun, würde sicherstellen, dass die Namenswerte richtig zur Verfügung gestellt. Wir können wahrscheinlich auch die Anzahl der Zeichen begrenzen, die diese Namenseigenschaft haben kann. Weißt du, die meisten von ihnen wussten es nicht, und es muss eine maximale Länge haben. Und es würde wahrscheinlich benutzerdefinierte Nachrichten für die Situation für die Standardanzahl von Tagen wollen, wir können wahrscheinlich sehen, dass es feindlich ist, mehr als ein, es muss größer als 0 sein, zumindest für die Standardanzahl von Tagen. Es gibt also eine Reihe von Dingen, die wir validieren könnten. Also, was wir sehen werden, ist Regel vier. Und dann werden Sie feststellen, dass dies aussieht, nur die gleichen Lambda-Ausdrücke lassen , die wir gewohnt sind. Und wenn Sie nicht ganz daran gewöhnt sind, ist das in Ordnung. Wir werden uns irgendwann an sie gewöhnen. Also ist es Regel für und dann können wir Namen sehen. Und das Coolste an der Flint-Validierung ist, dass man Dinge mitketten kann. Also kannst du sie verketten und sagen: Okay, diese Regel und diese Regel und diese Regel und diese Regel. Also die Regel für P Punktnamen. Ist, sagen wir, nicht leer. Das bedeutet also, dass es einen Wert haben muss. Und dann kann ich mit Nachricht sagen, also wenn es über m2 kommt, dann wollen wir, dass diese Nachricht gedruckt wird. Also kann ich so etwas wie diesen Eigenschaftsnamen tun, damit wir nicht mit reden wollen. Typname muss sein, Ihr Name ist erforderlich, oder? Weil ich dann dynamisch mache. Wenn wir den Namen in der Klasse selbst ändern, können wir vergessen, die Nachricht entsprechend zu aktualisieren. Indem Sie dies einfach tun, wird es automatisch erben, welchen Namen oder was auch immer der Name von der Eigenschaft ist, dass es wirklich auch ist. Richtig. Also werden wir sagen, Eigenschaftsname ist erforderlich. Das ist unsere Validierungsbotschaft. Eine andere Validierung, die wir setzen könnten, ist nicht null. Also lassen wir Sie wissen, dass dies nicht null sein sollte. Und ich habe mein Semikolon vorzeitig, so schrecklich, dass es also auch nicht null sein sollte. Mal sehen, was wir haben können. Wir können auch sagen, dass die maximale Länge der Namenseigenschaft vielleicht 50. Es sollte keinen Urlaubstyp mit einem Namen geben, der 50 überschreitet, oder? Und dann können wir eine weitere mit Nachricht hinzufügen, dass mit der Nachricht. In Ordnung, also gebe ich Ihnen nur Ideen. Ich meine, Sie haben vielleicht andere Anforderungen für Ihre Validierung als ich, aber das sind allgemeine Richtlinien, denen sie folgen können. Also schauen wir uns die an, der p-Punkt-Standard ist. Standardmäßig würden Sie feststellen, dass einige Validierungen möglicherweise nicht unbedingt zutreffen, da der Datentyp anders ist . Also kann ich nicht über maximale Länge sprechen mit der Standardeinstellung ist, dass nichts mit einer Ganzzahl zu tun hat, richtig? Sie sehen, dass die Pfeile weg sind, also sehe ich, dass es vorhanden sein muss, aber dann ist es Ganzzahl, also wird es immer, ziemlich es wird immer vorhanden sein, aber wir können das in Ruhe lassen. Aber es sollte nicht leer sein. Dann kann es nie null sein. Wirklich intuitiv, da ganze Zahlen Standardwerte 0 und Nullwerte sind. Aber dann haben wir gesehen, dass es immer größer als 0 sein muss. Und dann bin ich sicher, dass es eine weniger als. Nehmen wir also an, wir wollen in dem System sehen, es sollte kein Blatttyp sein, der Putin ist , die eine beliebige Anzahl von diesen Greta als eine 100 oder bis zu einem 100 hat. Und es muss mindestens eins sein. So können die verschiedenen Datentypen unterschiedliche Regeln erhalten und wir können sie bei Bedarf alleine verketten. Wir können unsere Botschaften entsprechend setzen, damit ich hier meine Botschaft mit Botschaft setzen kann. Also mit diesen Validierungen an Ort und Stelle auf dem Blatttyp DTO, lassen Sie uns sehen, wie wir gehen können, um sicherzustellen, dass diese Validierungen unsere eigenen. In dem Befehl, der den Blatttyp erzeugt, bekommen wir das Blatt, das BTO von unserem Befehlsobjekt, richtig? Was ich tun werde, bevor ich das Mapping überhaupt mache, weil ich keine Ressourcen für eine Operation mit ungültigen Daten verschwenden möchte. Also werde ich zuerst die Validierung durchführen. Also werde ich sagen, var validator ist gleich New Leaf Typ DTO Validator. Also, während es immer noch ein Detail ist, bevor ich versuchte, es dem Domänentyp zuzuordnen, werde ich diesen Validator aufrufen, dem ich sagen werde, dass das var Validierungsergebnis gleich ist. Und ich erwarte, dass mein Validator den Anruf zur Validierung macht. Und wir haben die asynchrone Option, daher die await verwenden. Und dann übergeben wir das zu validierende Objekt, das ein Request Dots Typ DTO sein wird. An diesem Punkt wird das Validierungsergebnis entweder Pfeile nicht haben. Also werde ich sehen, ob Validierungsergebnisse Punkt gültig ist, also bekommen wir, dass es entweder gültig ist oder nicht auf den Regeln basiert. Es wird gültig sein oder nicht. Wenn es so ist. Nehmen wir an, wenn es nicht gültig ist. Und dann für die Lesbarkeit wollte ich sagen, ob gültig ist gleich falsch, richtig? Denn manchmal in aller Fairness, wenn wir nur Ausrufezeichen verwenden, manchmal, wenn Sie müde sind, emittieren Sie es sogar verpassen, wenn Sie den Code überprüfen und so weiter. Also werde ich nur eine sehr explizite sein, wenn gültig ist, ist äquivalent zu false, dann werde ich einfach eine neue Ausnahme werfen. Wenn Sie also an die Ausnahmebehandlung gewöhnt sind, wird eine Ausnahme ausgelöst, das ist es, stürzt im Grunde ab. Das Programm wird später wissen, dass wir uns eine bessere Ausnahmebehandlung ansehen werden und all das kann uns tatsächlich helfen, ein bisschen sauberer Code zu schreiben. Anstatt einer Reihe von if-Anweisungen zu helfen, eine Reihe von Dingen zu überprüfen, haben wir nur Ausnahmen. Das ist unser Durchleben und strategisch, um den Ablauf der Anwendung zu unterstützen. Also in dieser Situation, wenn es nicht gültig ist, dann werden wir nur eine Ausnahme werfen. Wir werden uns ansehen, wie wir benutzerdefinierte Ausnahmen machen können, die anders als tatsächliche fetale Ausnahmen behandelt werden können. Das ist also so ziemlich es. Wir fügen hier eine Validierung hinzu, um sicherzustellen, dass sie nicht weiter geht. Es geht nirgendwo in der Nähe der Datenbank. Wir möchten nicht, dass es zu einem Domänenobjekt wird, wenn es ungültig ist. Lassen Sie uns jetzt versuchen, wahrscheinlich die komplizierteste. Also werde ich Sie herausfordern, Validatoren für die Urlaubsanweisung zu begleichen, was wirklich nicht so anders ist. Sie müssen nur sicherstellen, dass die Anzahl der Tage auf Es ist mehr als 0 vorhanden ist. Die Blatttyp-ID darf nicht null sein, sie muss auch größer als 0 sein. Und dann könnten Sie erweitert werden, um sicherzustellen, dass die Blatttyp-ID im System vorhanden ist. Denn wenn jemand versucht, und Central Valley Typ-ID zu täuschen, die in unserer Tabelle nicht existiert, dann ist das auch ein Validierungspfeil, den wir tatsächlich fangen können , bevor wir versucht haben, die Datenbank zu übernehmen. in die Datenbank kommen, können wir das für den Zeitraum tun. Also werde ich Sie auffordern, das zu tun, aber wir werden gemeinsam an den Urlaubsanfragen arbeiten weil dieser hier noch ein paar Dinge drin haben wird. Also noch einmal, ich werde einen neuen Ordner Validatoren hinzufügen, und dann lassen Sie uns beginnen mit der Erstellt verlassen Anfragen, DTO Validierung. Was brauchen wir, um zu validieren? Nun, unsere Daten müssen gültige Daten sein. Wir müssen immer noch die Blatttyp-ID bekommen, also werden wir das zusammen tun. Und das ist optional, also ist das in Ordnung. Also lasst uns in das gehen. So beginnt es mit unserer Klasse erstellt Urlaub Anfragen Detail Validator. Ich mache es öffentlich. Und dann erbe ich vom abstrakten Validator relativ zu unserem Create Leave Requests Detail. Ordnung, also habe ich schon ein paar Zitate für dich geschrieben und wir werden es durchmachen. Es ist nicht abgeschlossen, weil ich möchte, dass wir bestimmte Teile zusammen machen, aber Regel für Anfang muss weniger als das Ende sein. Jetzt haben wir gesehen, dass wir auch den Skalarwert hier verwenden können. Also hätte ich eine ganze Zahl setzen können, aber dann wäre eine Ganzzahl ein inkompatibler Vergleich mit der Zeit. Also hätte ich Datumszeit angeben können, nein. Richtig. Stellen Sie nur sicher, dass das Startdatum nicht vor heute sind meist vor heute, was nicht unbedingt der Fall ist, oder? Basierend auf der Geschäftsregel möchten Sie daher möglicherweise entsprechend vergleichen, aber diese Geschäftsregel besagt, dass die Anfangstermine immer kleiner als das Enddatum sein müssen. Und dann wird die Nachricht, die ich sagen kann, Eigenschaftsname muss vor Vergleichswert sein. Also in unserem erstellen Blatttyp Detail hatten wir die 50 hartcodiert, wir haben hart codiert die, die eine und die 0 hier, aber wir konnten sie leicht ersetzen und er sprach auf Parson richtig. Wir könnten diese Bereiche leicht durch einen Vergleich ersetzen. Ich lasse das fest codiert für null, aber ich zeige Ihnen nur Ihre Optionen, richtig? Also sehe ich, dass Startdatum vor NDI es Ähnlichkeit für Indien sein muss, muss es größer sein als der Anfang ordentlich und Eigenschaftsname und Vergleichswert. Ordnung? Nein, relativ zur Blatttyp-ID habe ich gesagt, dass unsere Validierung eine Reihe von Formen annehmen könnte. Erstens, Sie möchten sicherstellen, dass es größer als 0 ist, okay, gut. Und umso wichtiger wäre, dass Sie sicherstellen wollen, dass es existiert. Wenn wir nun nur überprüfen, ob es existiert, selbst wenn sie über 0 gesendet haben, würde 0 nie als Blatttyp-ID in der Datenbank existieren. Also könnten wir es verketten, denn dann könnten wir die Datenbank verschwenden, die aufgerufen wird, indem wir das einfach tun. Also könnte ich sagen, größer als. Und dann werde ich 0 sehen. Und dann werde ich auch sehen, dass es existieren muss. Also verwende ich, was Sie hier einen Delegaten nennen, und ich werde das alles löschen und es von Grund auf neu eingeben damit Sie genau sehen können, was sie die meisten asynchronen, offenen und geschlossenen Klammern sagen werden, es ist ein Sehen, also werden wir warten, aber dann werden wir einen Delegaten definieren. Entschuldigung, wir sind nicht so, dass wir verwenden, wir lassen es wissen, dass es ein asynchroner Delegat ist, der einige Parameter übernimmt. In diesem Fall benötigen wir die ID, die der Wert ist. Also nehmen wir diesen Wert als Parameternummer 1. Und dann ist Tolkien ein Abbruch-Token als Parameter-Tool. Und dann verwende ich einen Lambda-Pfeil, um dann einen Objektblock oder Methodenblock zu definieren. Also dieser Methodenblock ist, wo wir diese Überprüfung durchführen, um zu sehen, ob es existiert. Jetzt fragen Sie sich wahrscheinlich, okay, das bedeutet, dass wir eine Datenbank brauchen, die heißt, wie genau rufe ich die Datenbank nur von einem Validator aus auf? Das coole daran ist, dass es uns erlaubt, direkt oder Abhängigkeiten zu injizieren. Okay, damit wir fortfahren können, indem wir unser Repository injizieren , damit wir wissen, wie man es injiziert, wird es in den Konstruktor setzen. Wir können Steuerpunkt verwenden, um das Feld zu initialisieren. Ich habe bereits auf meine Unterstriche gewechselt, was natürlich optional ist. Aber mit dem können wir diese meisten acing Delegate Funktion überprüfen, ob das Blatt I Repository existiert. Also zwei Dinge, die hier zu beachten sind, sind drei Dinge. Erstens, wir injizieren den Validator ermöglicht es uns, andere Abhängigkeiten wie unsere Repositories zu injizieren. Das ist ein Werkzeug. Wir können tatsächlich eine benutzerdefinierte Funktion haben, die benutzerdefinierte Validierung für jemanden durchführt, um diese IN für sie von Grund auf einzugeben. Also hier sehen wir einen Punkt. Die meisten würde ich Musselin die asynchrone haben. Das ist in Ordnung. Also die meisten asynchronen. Und dann, weil wir async verwenden, müssen wir das Delegate-Modell lassen, es wird gelöscht. Der Delegat ist also, wann zwei Parameter verwendet werden sollen. ID, die genau die ID darstellt, die wir validieren, oder den Wert, den wir validieren. Und tolkien wäre repräsentativ für das Stornierungs-Token , das wir verwenden, sind Lambda R0 und öffnen und schließen Sie dann geschweifte Klammern. Dann innerhalb dieser geschweiften Klammern haben wir unsere Logik. Die erste Zeile unserer Logik besteht also darin, zu überprüfen oder zu speichern, ob der Blatttyp existiert und dann zurückzugeben, der nicht existiert. Ordnung, nein, diese Funktion, die ich gerade erstellt habe, habe ich gerade unser generisches Repository erweitert, um eine Methode zu haben, die einen Booleschen Wert zurückgibt. Es heißt existiert und es braucht int id. So können Sie das zum generischen Repository hinzufügen und Sie können es für jeden von ihnen verwenden. Aber der Punkt ist, dass wir wissen können, verwenden, um zu überprüfen, ob etwas in einer bestimmten Tabelle existiert. Und in dieser Situation ist es ein schöner Schuh, um zu überprüfen, ob oder elif Typ-ID existiert. Also wissen Sie, dass Sie mit Halten ausgestattet sind, um diese Blatttyp-ID zu behandeln. Ich werde Sie herausfordern, zu gehen und Validatoren für die Urlaubsanweisung einzurichten. Hit Pause, nehmen Sie sich ein paar Augenblicke, richten Sie die Validatoren Ford verlassen Zuteilung und alle anderen Details, die wir gerade noch nicht gesehen haben. Und dann, wenn Sie ein mehr zurückkommen, zeigen Sie Ihnen einfach einen anderen Weg, wie wir unseren Code umgestalten können , um die Wiederholung irgendwie zu reduzieren. Okay, also hoffe ich, dass Sie tatsächlich den Rat genommen haben, den Sie losgegangen sind, Sie versuchten, sich selbst zu tun und dass Sie etwas Erfolg hatten. Das ist gut. Aber dann möchte ich Ihnen nur noch eine andere Ebene zeigen, dass wir das tun können. Also, als wir die Details aufstellten, erkannten wir irgendwie, dass es sein würde, unsere Eigenschaften über mehrere Details hinweg zu wiederholen. Zum Beispiel, die erstellen Blatt Typ D2 und die Blatttyp Detail, sie haben tatsächlich die gleichen Eigenschaften Bar die Schriftart. Keiner verlässt sich auf die ID, die wir durch das Basisdetail dienen. Die Validierungsregeln für beide sind also tatsächlich die gleichen außer vielleicht derjenige, der die ID1 zum Hub der Validierung dafür sagt. Da man also eine ID hat, hat man nicht, und der Validator bisher sehr stark typisiert wurde , weil, wenn wir das Blatttyp-Detail erstellen, es nur vier sind, um Blatttyp-Details und Aktualisierungen zu erstellen, D2 hätte , um einen eigenen Validator zu haben. Also, was ich getan habe, ist, es ein bisschen zu erweitern. Und das ist es, was sie Pin-gesteuerte Entwicklung nennen. Es bedeutet, tun, was Sie können, bis es nicht mehr praktisch ist, dann refactorieren Sie, richtig? Wenn Sie also diese soliden Prinzipien anwenden, sehen Sie es manchmal nicht direkt vom Fledermaus. Aber dann merkt man an einem bestimmten Punkt, dass dies mühsam wird oder das nicht praktisch ist, das entspricht nicht dem Prinzip. Und so umgestalten Sie Ihren Code, um an diesem Punkt das Beste aus dem Prinzipal herauszuholen. An diesem Punkt analysieren wir, dass die gleichen Validierungsregeln auf mehrere Dateien aufgeteilt sind , was in Ordnung ist. Oder zumindest mehrere Dateien für Validierungen zu haben, ist in Ordnung. Aber die gleichen Regeln zu wiederholen kann gefährlich sein, denn wenn dann die Regel in einer geändert werden muss, könnten wir sie in einer ändern, die ich vermisse die andere. Wir kennen dieses Risiko. Was ich also getan habe, ist eine Schnittstelle zu haben, die eine Behinderung unserer Felder ist. In Ordnung, also wie Leave Type Detail, das ich erstellt habe, lasse ich dieses Detail und das hat die Felder, von denen wir wissen, dass das Blatt tab2 haben muss. Also im Blatttyp DTO habe ich in Beziehung geerbt. Ich überlasse das Detail. Diese beiden Felder sind also nur die Implementierungen dessen, was in der Schnittstelle definiert wurde. Genauso wie in Lift IB2, während es vom Basisdetail erbt, erbt es auch vom elif-Typdetail. Lassen Sie also, dass BTO die ID sowie die Eigenschaften haben würde , die von unserer Schnittstelle kommen. Jetzt. Okay, also, der nächste Schritt ist, dass wir einen I leave type detail validator erstellen können, was bedeutet, dass ich gegen die Schnittstelle validiere. Meine Regeln werden also nicht mehr direkt auf den Blatttyp DTO angewendet. Das könnten sie sein, das ist in Ordnung. Aber dann, wie wir gesehen haben, müssen wir mehrere haben, weil wir ein vollständiges Blatt Tab2 auf 14 haben müssten, das Erstellen. Stattdessen kann ich Validierungen gegen die Behinderung einrichten. Beide Details erben tatsächlich von der Obstruktion. Diese Regeln werden also für beide gelten. Und dann, wenn ich angefertigt werden muss, habe ich mein Blatt, das Detail Validator, in dem ich sage erstellen Blatt. Von Detail Validator und alles, was wir bereits wissen. Aber dann rufe ich im Konstruktor einfach eine Include-Methode auf. Das ist also fließend API ist, dass wir uns verfolgen, um Validatoren zu haben, die für andere Dinge gelten, gelten für eine andere Klasse. Das gilt also wirklich für die Schnittstelle, was ich sehe, wenn ich diesen Blatttyp-Detail-Validator mache, schließen Sie die Regeln aus dem I leave type detail validator ein. Und dann kann ich auch meine Kostümmethoden haben. Also im Update-Detail könnte ich die gleiche Art von Syntax haben, aber dann sind es die Updates, was bedeutet, dass ich auch unsere Regel für brauche. Und dann kann ich sagen, dass ich eine Regel für die ID-Felder brauche. Ich kann p dot sagen. Und dann sehen Sie, dass es mir alle Eigenschaften gibt, einschließlich ID, weil es gegen diesen Typ ist. Meine Validierung für die ID ist, dass sie nicht null sein sollte und es sollte mit einem Nachrichteneigenschaftsnamen kommen muss vorhanden sein, da Sie beim Aktualisieren natürlich die ID des Datensatzes senden müssen, den Sie aktualisieren, Deshalb brauchen wir diese Validierungsregel für das Update und deshalb müsste ich die separate Datei für das Update haben. Aber das ist viel sauberer, weil wir zumindest die Regeln für den Namen und den Typ oder den Namen nicht wiederholen müssen . Und der Standard ist, Entschuldigung, wir müssen das nicht über beide durch die Daten wiederholen. So werden Sie sehen, dass das tatsächlich bereits für die Urlaubsanfrage und für die Blattzuweisunggetan hat die Urlaubsanfrage und für die Blattzuweisung , noch einmal, für die Urlaubsanfrage, ich habe Anfragen DTO verlassen, und es ist der gleiche Code, den wir gerade angesehen haben, wenn wir haben die Urlaubsanfragen Detail gültige Daten mit Injektion. Und in diesem Fall müssen wir es initialisieren und dann machen wir die Regeln. Aber wenn wir in der Erstellt lassen Anfrage Detail Validator schauen, sehen wir, dass wir die Injektion tun müssen. Also müssen wir noch unsere Injektion machen und wir müssen sie initialisieren. Und dann übergeben wir diese Injektion in die Include-Methode, weil natürlich der IO-Anforderungsdetail-Validator diese Injektion haben muss. Also Kant nennt es, wir müssen diesen Wert für den Konstruktor bereitstellen. Es ist also nur diese Gänseblümchenkette, aber ich denke, dass das in beiden Fällen viel sauberer ist. Und wir müssen nicht am Ende all diese Regeln wiederholen. Sie werden also feststellen, dass sowohl das Erstellen als auch das Update sehr ähnlich aussehen, mit Ausnahme der Tatsache, dass das Update diese zusätzliche Regel für die ID hat. Und nur zur Fertigstellung, wir haben die Augen Zuteilung Details. Ich habe die ID-Kassen, die Schnittstellen haben das nicht gezeigt. Also alles, was für alle üblich ist, habe ich das einfach in die Schnittstelle und dann kann alles andere direkt ins Detail gebracht und entsprechend validiert werden. Aber dann, um ein Update zu erstellen, sind das alles, was wir wirklich brauchen. Wir müssen nicht unbedingt Wochenende Sinn der Validierungsregel Art von Anforderungskommentaren vielleicht die Länge begrenzen. Wir müssen nicht unbedingt irgendetwas tun, um abgesagt zu werden. Noch einmal, ich gebe Ihnen nur die Richtlinien. Ihre Geschäftsregeln und -anforderungen können unterschiedlich sein, aber Sie richten Ihre Validierungen nach Bedarf ein. Also unsere Update-Anfragen Details erbt von der Basis, und ich lasse Anfragen Details. Wir müssen das nicht für die Liste tun, weil wir die Liste nicht validieren. Wir validieren auch nicht das Detail Detail, aber das schafft definitiv zu erben. Und dann die Änderungsanfrage Genehmigung, die von diesem Detail nimmt, aber wir sind nicht ganz irgendwann können wir dies validieren. Ich werde es nicht priorisieren. Aber dann über Update und erstellen, wir müssen auf jeden Fall bereits haben, in Ordnung, nein, Für unsere erstellen Sie einen Standort, also verlasse ich Zuteilung und dann erstellt beide ein Update erben von ich Allokation. Also werde ich nur zum Ich lasse Zuteilungsvalidator springen , wo wir Regeln für die Anzahl dieser haben. Diese ist also einfach und wenn die Anwendung wächst, ändern sich Geschäftsregeln. Wir können unsere Validierung einfach hier einfügen, ohne die benutzerdefinierten Abfragen und andere Kundenoperationen um die genannten Geschäftsregeln zu ändern . Also Regel für eine Reihe von Tagen gerade jetzt habe ich es muss größer als 0 sein. Und meine Validierungsnachrichten waren Opfer von Kopieren und Einfügen. Also sehe ich nur, dass der Eigenschaftsname größer als der Vergleichswert für die Größer-als-Regel für den Zeitraum sein muss . Also sollte der Zeitraum wirklich das Jahr sein, oder? Also für den Zeitraum des Jahres 2020, das waren die Anzahl von ihnen, die Sie bekommen. Das sind die Polpunkte der Blattzuordnungstabelle für den Fall, dass das früher nicht erklärt wurde. Die Regel für einen Zeitraum ist also, dass er größer oder gleich dem Zeitpunkt 10 Punkt Jahr sein muss . Und wir können das noch ein bisschen mehr unterstützen, wir werden das einfach benutzen. So werden wir sehen Nachricht Eigenschaftsname muss nach diesem Jahr sein. Und dann sahen und schrieben wir alle die Validierungsregel für die Blatttyp-ID und nein für die Create leave Allocation Detail gültige Daten, wo einfach das Leaf die Repository injiziert und das Leaf die Repository injiziert undinitialisiert und übergibt es in unserer Include-Methode. Und für die Updates waren das gleiche, außer wir haben auch diese Regel für die ID. Also, das ist wirklich es zur Validierung. Ja, es hat eine Weile gedauert, um dorthin zu gelangen. Es gab einige Reflektoren auf dem Weg, aber ich bin mir sicher, dass Sie sehen können, wie alles zusammenkommt, um eine Wiederholung über mehrere Dateien hinweg zu reduzieren und um eine Art von Hilfe zu helfen, alles strukturiert zu halten. Eine Konsequenz des folgenden, die soliden Prinzipien natürlich, ist, dass Sie am Ende mit vielen weiteren Dateien, die wir bereits besprochen haben. Aber es kommt gut zusammen und hilft uns zu reduzieren, wie oft wir dasselbe an mehreren Orten platzieren. 13. Benutzerdefinierte Exceptions hinzufügen: Hey Leute, willkommen zurück. Das letzte Mal, als wir hier waren, setzten wir unsere Validierungen für Handler und für unsere verschiedenen Details auf. Und kurz gesagt, wir erkannten, dass wir einige Regeln einfügen mussten, so dass, wenn wir den Befehl create leaf type mit dem create leaf type D2 oder was auch immer Detail bekommen . Wir können es gegen den Validator ausführen und dann würden wir eine Ausnahme zurückgeben, wenn es ungültig ist. Also hätten wir das über alle Handler für die Aktualisierung tun sollen und alles erstellen sollen, was eine Validierung benötigt, sollte mindestens diese Zeilen haben. Also klicke ich einfach durch und du kannst einfach weitergehen und kopieren, falls du das nicht fertig hast. Das ist also für das Update. Wir haben uns gerade die Create for the Leaf Type Update vollständig Anfragen angesehen , so ziemlich alle von ihnen sehen wie die gleiche Sache aus. Alles klar, sie bestätigen alle und geben eine Ausnahme ein. Jetzt möchte ich über benutzerdefinierte Ausnahmen und MRD-Antworten sprechen, richtig? Denn am Ende des Tages im Moment, alles, was wir tun, ist eine Ausnahme zu werfen. Eine Ausnahme kann basierend auf unserem manuellen Werfen ausgelöst werden. Es multi kann auch wegen etwas anderem geworfen werden. Er könnte ein Datenbankumleitungsproblem sein, es könnte etwas anderes sein, oder? Es ist also immer gut, dass die verbrauchende Anwendung oder was auch immer den Handler aufruft, eine gute Vorstellung davon hat, was durch diese Ausnahme passiert. Die coole Sache an Ausnahmen ist, dass Sie sie erweitern können. Der Basisdatentyp für eine Ausnahme ist also die Ausnahme, die wir hier einwerfen werden , was wir für die spezifischen Zwecke unsere eigenen erstellen werden. Also werden wir beginnen, indem wir einen neuen Ordner in unserem Projekt erstellen. Wir werden es Ausnahmen nennen. Und darin werden wir schlechte Anforderungsausnahmen haben, nicht gefundene Ausnahme und Validierungsausnahme. So können Sie fortfahren und diesen Ordner erstellen. Und diese drei Akten, erinnern Sie sich an mich öffentlich, natürlich. Und was wir tun werden, ist, dass jeder von ihnen von Anwendungsausnahmen erbt. So Ausnahme ist der Basistyp einer Anwendungsausnahme wird als Basistyp für anwendungsdefinierte Ausnahmen Kunst verwendet. Also gehen wir einfach voran und lassen jede unserer Klassen von dieser Butter angeforderten Ausnahme erben wird später, wenn wir definieren wollen, dass die Anfragen, die zentral gegen schlecht waren , in Ordnung, aber jetzt werden wir initialisieren oder den Code lesen, um es zu verdrahten. Also alle von ihnen werden einen Konstruktor haben. Und für diesen wird der Konstruktor eine String-Nachricht nehmen und dann muss unsere Basis die gleiche Nachricht erben, die die Basis als unsere Verpflichtungserweiterung übergeben wird. So sieht diese Ausnahme aus. Anwendungsausnahme eher. Tut mir leid. Nein, weitermachen. Wir können dasselbe für unser NAACP-Telefon tun, aber dann können wir mit bestimmten Dingen etwas expliziter sein. Zum Beispiel, wenn wir sehen, nicht gefunden werden, werden wir wahrscheinlich wollen, um den Namen dessen, was gesucht wurde, und vielleicht den Schlüsselwert zu sehen . In Ordnung, also übergeben wir Name auf der Tastatur, dann benötigt die Basis eine Zeichenfolge, also hat sie drei Überladungen. Möchten Sie hier eine Zeichenfolge übergeben. So können wir einfach unsere Botschaft mitteilen, dass wir wissen, dass wir drucken wollen. Und meine Botschaft wird sagen, dass der Name, was auch immer er ist und sein Schlüssel nicht gefunden wurde. In Ordnung, also wenn die Suche nach etwas, es wird nicht durch nicht gefundene Ausnahme gebildet, für die Validierungsausnahme. Wir werden ein bisschen schicker werden. Also wird die Validierungsausnahme zu R wollen, wir werden wollen, dass sie die Liste aller Dinge zurückgibt, die mit der Anfrage oder den Daten falsch waren, die in ihrer Quest gesendet werden, richtig? Also werde ich eine Liste von Strings haben und ich werde es Fehler nennen, richtig? Und dann im Konstruktor werden wir die Validierungsergebnisse haben, wobei die Daten übergeben werden. Validierungsergebnisse des Validierungsergebnisses kommen also aus fließender Validierung. Also werden wir einfach das ganze Objekt dort übergeben, es verwendet fließende Validierungsergebnisse. In Ordnung, und dann können wir sehen, dass wir initialisieren oder Fehler. Ich meine, initialisieren Sie das hier. Und dann können wir für jeden Validierungsfehler in den Fehlern sehen. Oder ich kann es einfach verkürzen und für jeden Fehler in Validierungsergebnispunktfehlern sagen, wir möchten diesen Fehler hinzufügen. Also werde ich nur urls.py sagen. Und dann haben wir nur Fehler Punkt und wir haben eine Fehlermeldung. Da gehen wir. Diese Fehlermeldung wäre also das, was wir in unseren Validatoren eingerichtet hatten , als die Nachricht, die zurückgegeben werden soll, wenn sie ungültig ist. Also jetzt haben wir unsere benutzerdefinierten Ausnahmen. Wir werden uns wirklich auf die Validierungsausnahme konzentrieren, rechten Knoten. Und so können wir in unseren Handlern dies tatsächlich von einer neuen Ausnahme aktualisieren , um eine neue Validierungsausnahme zu werfen. Wenn das Validierungsergebnis also ungültig ist, werfen wir diese neue Ausnahme aus und wir übergeben unsere Validierungsergebnisse und Sie möchten alle fehlenden Referenzen einschließen. Sie sehen hier also, dass es nach diesen Büchern fragt. Wir wissen, dass wir es definiert haben. In unseren benutzerdefinierten Ausnahmen. Alles klar, Sie können also jede Zeile aktualisieren, die zuvor nur eine neue Ausnahme ausgelöst hat, um diese Validierungsausnahme zu werfen. Und bitte denken Sie jedes Mal daran, dass wir unsere benutzerdefinierte Ausnahme einschließen und nicht die Fluidvalidierung oder die Datenvalidierung auf Kunst. Also gehen Sie weiter und aktualisieren Sie sie alle und stellen Sie sicher, dass Sie die Warenkorb-Bibliothek enthalten. Jetzt kann ich mir vorstellen, dass du dich fragst, okay, also wie kann ich die anderen Ausnahmen verwenden? Nun, schauen wir uns die nicht gefundene Ausnahme an. Also in C, dem Löschvorgang, müssen wir den Datensatz finden, dann löschen und dann gut zurückgeben, die Einheiten, richtig, aber was ist, wenn wir diesen Datensatz nicht finden? Nun, dann ist das eine perfekte Gelegenheit, wo wir sagen wenn das Objekt, nach dem wir suchen, null zurückgibt oder wenn die Operation null zurückgibt, dann werfen wir die nicht gefundene Ausnahme. Und was würden wir in die nicht gefundene Ausnahme hineingehen? Denken Sie daran, dass es zwei Parameter braucht. Es braucht den Namen und den Schlüssel, so dass wir leicht sagen, Name off. Und dann ist dies eine schöne Möglichkeit, es stark typisiert zu halten. Also suchen wir nach einem Blatttyp. Also benennen Sie Blatttypen oder sagen Sie im Blatttyp mit der ID, die übergeben wurde, war nicht Telefon oder andere Anfragen. Punkt-ID, rechts. Da gehen wir. Alles klar, dann können Sie beginnen, Ihre Delete-Handler mit dieser eine Zeile zu dekorieren. Im Fall der Urlaubsanfragen wird das dasselbe sein, außer wir überprüfen, ob die Urlaubsanforderung null ist, und dann wäre dies eine Urlaubsanforderung, die nicht angerufen wird. Gehen Sie weiter und aktualisieren Sie. So können Sie das auch mit Urlaub Zuteilung tun. Alles klar, sobald Sie damit fertig sind, haben Sie zumindest einige nette Ausnahmebehandlung oder benutzerdefinierte Ausnahmebehandlung in Ihrem Handless abgewickelt . Eine andere Sache, die wir uns ansehen wollten, sind Kundenantworten. Was passiert also, wenn es ein positives Ergebnis gibt? Und selbst wenn es negative Ergebnisse gibt, richtig? Dies ist also, wo Ihre, Ihre architektonischen Bedürfnisse können von mir in Bezug auf das, was Sie tun wollen, abweichen. Aber hier ist ein Konzept. Wir können benutzerdefinierte Antworttypen definieren oder Basisantworten haben, wo wir Daten basierend auf der Situation zurückgeben können. Wenn es also fehlschlägt, könnten wir die Ausnahme sicher auslösen. Oder wir könnten eine Kundenantwort haben, die ein falsches Flag für Erfolg hat, es enthält die Validierungsfehler. Und so wird der Kunde immer wissen, dass ich eine Antwort dieses Datentyps erwarte, dass wir immer diese Daten haben sollten. Wenn das Flag falsch ist, dass ich IT-Feld kenne, wenn es wahr ist, dass ich weiß, dass es passieren. Also werden wir uns so etwas ansehen. Also eine Alternative, um nur eine Ausnahme zu werfen oder nur die ID zurückzugeben, was wir tun könnten, ist einen neuen Ordner zu definieren. Also haben wir hier einen neuen Ordner namens Antworten und Inits haben wir eine dateibasierte Befehlsantwort. Und es wird drei Eigenschaften haben. Erfolg, die eine boolesche Nachricht ist, die eine Zeichenfolge ist, und eine Liste von Fehlern, sollten wir die Fehler zurücksenden müssen, richtig, also nachdem wir diese Basisbefehlsantwort haben, können wir sie erweitern, um die spezifische Operationen. Zum Beispiel wird ein Ergebnis wahrscheinlich dies erweitern wollen, ist, dass wir jedes Mal, wenn ein Blatttyp erstellt oder aktualisiert wird, Sicherheit zurückgeben möchten, richtig? Daher reicht die Basisantwort möglicherweise nicht aus. So können wir eine benutzerdefinierte Antwort erstellen, die mit Blatttypen verknüpft ist. Also haben wir bereits diese Web-Anfragen. Dann könnten Sie einen anderen Ordner namens Antworten erstellen, und dann könnten wir das erweitern. Ich werde nicht so kompliziert werden. Was ich jedoch tun werde, ist, hier eine weitere Eigenschaft hinzuzufügen und ich nenne sie ID, richtig? Oder wir können es Record ID nennen. Das bedeutet, wenn etwas passiert, erstellen wir, anstatt nur die ID zurückzugeben, was ich tun könnte, und das ist eine große Änderung. Also lasst uns Zeile für Zeile durchgehen und ich werde die roten Linien ansprechen, wenn wir dort sind. Also zunächst haben wir nur gesagt, holen Sie mir die Validierungsergebnisse, werfen Sie eine Ausnahme, sonst fahren Sie fort und geben Sie dann den Hebel zurück. Verlassen Sie. Lassen Sie in diesem Fall die Anforderungs-ID. Ordnung? Wissen Sie, was ich tue, ist, dass ich zuerst sehe, die Antwort initialisiere, also haben wir eine Basisantwort, das ist in Ordnung. Dann sehe ich, ob das Validierungsergebnis falsch ist, setze diese Spawns, die Erfolg denken, auf fällt. Die Nachricht, die Sie in eine benutzerdefinierte Nachricht einfügen können, wenn Sie möchten. Und dann die Fehler, die wir mit den gleichen Validierungsfehlern füllen möchten. Also wähle ich sie nur aus der Liste der Fehler aus dieser Sammlung von Fehlern aus. Diese Auswahl hat also eine rote Linie, weil ich eine zusätzliche Bibliothek brauche, die System.Out Links ist. Also stellen Sie sicher, dass wir das zusammen sehen können. Und dann bekommt es nur die Fehlermeldungen, setzt sie in eine Liste, und dann geht das hinein. Also, das ist ein netter ein Liner selbst die für jede Schleife richtig? Dann später bekannt, wir sehen, ob die Anzeige erfolgreich war und Seele, was passiert, ist, dass, wenn dies sich unaußergewöhnlich anfühlt, durch ein automatisch von Entity Framework sowieso gewesen wäre . Wenn dies also nicht passiert, dann erhalten wir eine Ausnahme. Es würde also nie so weit kommen, wenn dies nicht erfolgreich wäre. Dann ist der Erfolg wahr. Unsere Antwort ist die Erstellung erfolgreich, und dann setzen wir die ID. Das ist es, was ich dich in dem ganzen Brett sehen werde, wir geben nur Ausweise zurück, oder? Wir haben nur die ID für den neu erstellten Datensatz zurückgegeben. Sie können eine Anforderung haben, bei der Sie den gesamten Datensatz zurückgeben müssen. An diesem Punkt könnten Sie einfach erweitern Basisbefehlsantwort erstellt eine neue Klasse namens es erstellt verlassen Anforderungsantwort. Und dass es davon nicht weh tat und ihm den DTO-Parameter für eine Urlaubsanforderung DTO gab, machen Sie Ihre Zuordnung, Sie geben es zurück. Wie ich schon sagte, ich werde nicht so kompliziert werden, oder? Nein, wir können uns das nicht in unseren zukünftigen Überlegungen oder zusätzlichen Überlegungen ansehen , aber ich wollte nur dieses Konzept einer Kundenantwort durchsetzen. Also dann geben wir die Antwort zurück. Jetzt hat dies unsere rote Linie, weil wir unseren Befehl definiert hatten, int zurückzugeben. Okay, damit wir zu unserem Kommando gehen können. Lassen Sie es wissen, dass ich bitte soll die Beast Command Antwort zurückgeben. Alles klar, und dann wird unser Fehler erscheinen und wir springen Buck und waren bucking oder Handler, wir sehen, dass wir Antwort zurückgeben können, sobald wir auch den Handler aktualisieren, richtig? Also denken Sie daran, dass wir diesen Befehl haben und Typ Peer-to-Peer zurückgeben. Lassen Sie mich das einfach aktualisieren. Und dann schließlich der Typ auf der Aufgabe für das Handle. Okay, also da, wenn Sie also ändern möchten, ändern Sie Ihre Rückgabe-Divs, das ist alles, was Sie brauchen, um alle diese Änderungen noch einmal vorzunehmen, oder? Keine bs-Befehlsantwort. Wenn Sie also körnig werden wollen, sage ich weiter, dass Sie nicht als granulares Buch basierend auf Ihren Anforderungen erhalten müssen, müssen Sie es möglicherweise nicht brauchen. Ich mache es nicht zu einer Anforderung, zu Gold und Befehlsantworten für jeden einzelnen Einzelhandler oder Befehlshandler zu erstellen , den ich habe. Im Moment werde ich nur die Basisantwort verwenden. Und ich werde auch diese Änderung an der Urlaubsanforderung für jetzt zumindest vornehmen , damit Sie die Idee sehen können, wie Sie benutzerdefinierte Ausnahmen haben können und oder wie Sie diese oben auf Ihren benutzerdefinierten Antworten verbessern können. 14. Zusätzliche Überlegungen und Überlegungen: Hey Leute, willkommen zurück. Dies ist eher eine Überprüfungssitzung als eine Codiersitzung und nur einige zusätzliche Überlegungen. So können Kehlen oder Aktivitäten erwähnt haben , dass Sie Alternativen haben und Sie immer Alternativen haben. ob diese Alternativen gut oder schlecht sind oder unzitiert zitieren, Best Practice ist manchmal relativ zu dem, was Sie tun und was Sie erreichen müssen. Davon abgesehen gibt es natürlich Grundprinzipien, an die Sie sich ungeachtet halten wollen und diejenigen, die diese als Führer haben werden, dann werden Sie mehr als wahrscheinlich bessere Entscheidungen treffen. Also eine Sache, die wir uns ansehen wollen, ist die Trennung von Bedenken, richtig? Trennung von Bedenken führte uns dazu, mehrere Projekte und weit mehr Dateien zu haben , als wir wahrscheinlich in anderen Projekten hatten, da ich Ensemble Tatsache bin, ich denke, dass wir bereits mehr Dateien in diesem einen Projekt haben als wir in der gesamten Anwendung dass wir beide wieder aufbauen sollen, oder? Allein in diesem Projekt hatten wir mehrere DTLs. Warum hatten wir mehrere Details? Nun, eine, die wir diese Art von Trennung wollten, weil es Geschäftsregeln geben könnte , die regeln, was bei jeder Art von Operation passieren kann. Also schauen wir uns an mich lassen Anfragen Details. Hinterlassen Sie Details zu Anfragen. Wir hatten eine für die Auflistung, die nur die Daten enthielt, die absolut notwendig waren , wenn wir die Liste der Urlaubsanträge aufstellen müssen. Wir haben einen DTO, der alle Felder hat, die mit dem übereinstimmen, was in der Tabelle ist. Und das könnte als detailliertes DTO gesehen werden. Wir hatten auch das Update, das nur ein paar Felder für einen Aktualisierungsvorgang benötigt hatte. Wir hatten die Erstellt, wo wir wenige Felder für eine erstellen Operation hatten, et cetera. Also teilen wir sie in mehrere Dateien auf. Das ist also eine der Konsequenzen , die ich sagen wollte sich an diese Grundsätze der Trennung von Anliegen hält. Aber du wirst am Ende mit viel unscharfem enden, als du es wahrscheinlich gewohnt bist. Und du wirst sie so trennen müssen, dass du sie immer finden kannst. Also begann ich mit Details dann im Detail, ich habe sie durch den Typ getrennt. Und dann dann beginnen Sie, die Dateien zu sehen, werden auch die Validatoren einrichten. Und dann wegen der verschiedenen Validierungsregeln , die für die verschiedenen DTUs erforderlich sein könnten, haben wir mehrere Validierungen, ein Boden für Create, wir haben 14 Update. Aber zur gleichen Zeit sahen wir, wo wir irgendwie konsolidieren mussten weil es irgendwie überwältigend war und wir begannen uns zu wiederholen. So haben Sie das DRY-Prinzip. Aufgrund des DRY-Prinzips haben wir eine Schnittstelle erstellt, die die Basisfelder hatte. Also lassen Sie mich schauen, vielleicht verlassen Zuteilung wird ein besseres Beispiel dafür sein. Also haben wir, Ich werde Allokation verlassen, die alle Felder hat, die für Jahresurlaub Zuteilung notwendig sind. Dann haben wir unsere Details, die von dieser Schnittstelle geerbt werden, oder? Also ja, Sie sehen die Implementierung wieder oder Sie sehen die Felder hier oben. Und wieder, was sie wirklich von dieser Anforderung der Vererbung von der Schnittstelle getrieben werden. Und dann könnten wir einen Validator gegen die Schnittstelle einrichten. Also werden alle gemeinsamen Felder, richtig, durch die Schnittstelle abgewickelt werden, validiert. Und dann schließen die anderen Validatoren nur die Validierungen ein und implementieren dann ihre benutzerdefinierten Validierungen nach Bedarf. Das hilft uns, die Wiederholung von Code zu reduzieren. Und wieder einmal, wenn Ihr Projekt wächst, laufen Sie Gefahr, zu vergessen, einen Teil Ihres Projekts zu aktualisieren , wenn Sie irgendwo eine Änderung vornehmen. Kennen Sie eine andere Sache, die Sie in unserem Validator anfangs Initialisierungen in unseren Handlern beachten sollten, und ich glaube nicht, dass ich früher darauf hingewiesen habe, dass jemand, der sicherstellt, dass ich weiß, dass, wenn wir diese Validatoren initialisieren, wir müssen ein Objekt des Typs übergeben, den es erwartet, oder? Denn denken Sie daran, dass dieser Validator das Ich verlasse Type-Repository benötigt und dann haben wir den Konstruktor, der sieht, dass ich das elif-Typ-Repository brauche. Es gibt also keine Möglichkeit, dies zu instanziieren, ohne es zu übergeben. Ich mag es, dass wir hier gemacht haben. Also, wenn Sie Leitung und die ganze Zeit gerichtet hatten, entschuldige ich mich, ich übersehe das, aber Sie können voran gehen und das tun, weil das, was Sie tun müssen, in den Handler injiziert und dann in die a 100 injiziert und Sie geben es einfach weiter ähnlich wie, wenn wir es brauchen, um den Basis-Validator einzuschließen, wir das Gleiche tun mussten. Alles klar, das ist das gleiche Prinzip, Abhängigkeitsinjektion. In Ordnung, also hoffe ich, dass ein Fehler behoben wurde, und wenn du diesen Fehler nicht hattest, dann lobt er an dich. Nun eine andere Sache, die wir vernachlässigt und wir können wissen, ist die Einbeziehung aller Details, die für jede Mapping-Operation erforderlich sind, um erfolgreich zu sein. Im Moment haben wir nur Mappings für dergleichen, für wie Anfrage die Teal zur Liste sind diese die einzige Domäne zum Detail. Also natürlich werden wir brauchen, sobald wir Mapping machen, wie in diesem Handler, wir sind Mapping von der Leave Allocation Detail erstellt Allokationen zu verlassen. Das bedeutet also, dass wir eine Darstellung innerhalb unseres Mapping-Profils haben müssen. Hier habe ich die zusätzlichen Mappings hinzugefügt, all jene für Urlaubsanfragen, die ich gerne gruppieren , damit sie nicht überall verwechselt werden. Und die ganze Idee der Gruppierung ist eine kann wahrscheinlich nur unseren Grund erstellen, unsere eigenen die Abschnitte, so dass Sie genau wissen, wo welche sind, welche Set beginnt oder Stadt Sie eine solche Anwendung aufrufen können wächst. Vielleicht möchten Sie so etwas tun. Okay, das ist eine andere Sache, die wir unbedingt ansprechen müssen, bevor wir weitermachen. Eines der Dinge, über die ich 0 Sterne sprechen möchte, ist unsere Ordnerstruktur. Also hatte ich mehrmals erwähnt, dass sich Ihre Ordnerstruktur basierend auf Ihrem Temperament oder Ihrem Outlook oder Ihrem visuellen unterscheiden kann . Und vier halten diese Akten müssen arrangiert werden, oder? Also denke ich gerne an QRS oder die Implementierung des Seepferdchens, unsere eigenen Szenarien. Und dann alle Szenarien, wir haben bestimmte Vermögenswerte, die erforderlich sind. Also, wenn ich sage, ist ein Szenario, ich meine, Erstellen einer Urlaub Allokation, das ist ein Szenario, was erforderlich ist, um zu erstellen und zu bewerten? Sie brauchen Ihren Befehlshandler. Sie benötigen auch Ihr Befehlsobjekt und Sie benötigen vielleicht einige andere Details. Sie können also erstellen und einfach einschließen, möchten Sie möglicherweise einen Ordner innerhalb von Urlaubsanlagen erstellen, der möglicherweise anstelle von Features hat , die Sie Urlaubsanweisung erstellt hätten. Und dann haben Sie Ihre Handler und alle Ihre Assets in diesem einen Ordner. So kann sich die Ordnerstruktur so lange unterscheiden, wie die Organisation so ist, dass Sie Ihre Assets finden können, wenn Sie sie benötigen, dann sind Sie auf dem richtigen Weg. Nun, während ich im Befehl Erstellt verlassen Allokation bin, eine andere Sache, die Sie in Betracht ziehen könnten, so dass Sie sehen, dass es so viele Überlegungen gibt, das ist nicht in Stein gesetzt, oder? Eine andere Sache, die Sie als andere betrachten könnten, ist, dass es innerhalb des Befehls ein bekanntes Muster ist, einfach das Befehlsobjekt für Ihre Felder zu verwenden , um die Befehle auszuführen. Anstatt eine ganze DTO innerhalb des Befehls zu haben, könnten Sie die Felder tatsächlich aus dem Detail innerhalb des Befehls einfügen. Und dann validieren Sie einfach den Befehl selbst, die Anfrage selbst, das Objekt, das in den Handler kommt, wäre nur dieses Objekt. Sie müssten nicht die Anfrage Punkt sagen, lassen Sie die Zuweisung, dto dot dieses Feld, Sie sagen nur Anfrage Punkt dieses Feld, dieses Feld usw. Es gibt also eine Reihe von Optionen, die Ihnen zur Verfügung stehen, aber ich werde an die Details mit allem, was gesagt und als Abschluss gemacht, der Kern oder das Anwendungsprojekt, wie wir es haben, enthält die Kernfunktionalität der Anwendung. So sehen Sie, dass an dieser Stelle alles abstrakt ist. Wir werden zum nächsten Modul übergehen, wo wir anfangen, einige echte Zitate einzugeben, Fleisch in die Repositories und jede andere Logik, die anwendbar ist. Wir haben uns angesehen, wie das Mediatormuster funktioniert, das lose Kopplung fördert , gekoppelt mit dem C-QRS-Muster, wo wir genau wissen können, welche Datei was tut. Und dieser Handler wird dieses Verhalten behandeln, dieses Szenario. Und wir können diese besondere Reaktion erwarten, weil diese Art von Beziehung oder Verhalten, das wir implementiert haben. Wir haben uns auch auf Features basiertes Layout angesehen, das meiner Meinung nach hilft Ihnen zu sehen, dass, okay, die Funktion zu verlassen Typen, können Sie alles darin finden. Und das hilft mir beim Layout. Sie haben vielleicht andere Ideen, aber das ist meine Empfehlung. Und dann haben wir uns die Validierung mit Fluent API oder fließender Validierung angesehen. In Ordnung, das sind also die Dinge, die wir in diesem Modul angesehen haben. Wenn wir also zurückkommen, werden wir definitiv einen Gang hochlegen und anfangen, etwas mehr Funktionalität einzubauen. 15. Sektion Übersicht: Hey Leute, willkommen zurück. In dieser Lektion starten wir unser Modul, in dem wir unsere Infrastrukturschicht einrichten , die Sie sich wahrscheinlich fragen, okay, was ist die Infrastrukturschicht? Nun, eins, es wird in diesem Ordner sitzen, der Infrastruktur genannt wird. Und zweitens, es ist das Projekt, in dem wir tatsächlich alle unsere Hindernisse implementieren werden, die im Kernbereich definiert wurden. Wir werden also unsere Datenbankkontexte einrichten, die wir Entity Framework Core als ORM verwenden , um mit unserer Datenbank unter unserer Anwendung zu kommunizieren. Aber in dieser Ebene, Sie Setup alles ist abgewickelt. Die Protokollierung Sie, wir werden die Repositories implementieren, die wir in das eigentliche Fleisch setzen, die Anwendung. Also lasst uns loslegen. Lassen Sie uns also zwei neue Klassenbibliotheken erstellen. Einer namens HR dot DV-Management-Infrastruktur und einer namens HR dot leave Management dachte Persistenz. Kennen Sie das Persistenzprojekt oder Persistenzschicht, wird sich mit unserer Kommunikation mit unserer Datenbank beschäftigen. Dies ist also, wo unser Datenbankkontext oder EF Core-Bibliotheken und Referenzen, all das. War es dort statt Infrastruktur , dort werden unsere Implementierungen sitzen. Alles klar, zwischen diesen beiden wird das Projektarchiv implementieren. Wir werden alle anderen Implementierungen von Drittanbietern einrichten, die erforderlich sind. Und wir werden auch Dienste einrichten, die in die Dienste gebootet werden, nennen es KI-Dienste Kollegen Sean oder den Dependency Injection Container für ASP.Net Core. Denken Sie daran, dass Bibliotheken getan werden müssen. Es ist gedonnert. 2.1. Und Sie haben bereits durch die Schaffung all den Zusammenbruch der Vielfalt gegangen können die gleichen Schritte folgen. Und wenn wir zurückkommen, beginnen wir mit der Einrichtung in verschiedenen Work Core in oder Persistenzschicht. 16. Entity Framework Kern hinzufügen: In Ordnung, also sind wir zurück und wir werden unsere Persistenzprojekte aufbauen. Lassen Sie uns also beginnen, indem Sie einen Verweis auf unsere Anwendungsprojekte hinzufügen. Also haben wir das Domain-Projekt, das alle Entitäten hat. Und das Endanwendungsprojekt hat einen Verweis auf das Domänenprojekt. So wird unser Persistenzprojekt einen Verweis auf unser Anwendungsprojekt haben , so dass wir einfach auf die Anwendung klicken können, um k zu gleichen. und dann ist das eine Abhängigkeit. Wir werden nicht auch zu NuGet-Paketen gehen. Wir werden nach Entity Framework suchen, aber das, das wir bekommen werden, ist Entity Framework, Core dot SQL Server. Also wird dieser, wenn er herunterkommt, mit allen Abhängigkeiten kommen, die wir brauchen. So können wir einfach weitermachen und die neueste stabile Version installieren. Und immer noch in Ihnen bekommen, lassen Sie uns einfach voran und suchen Sie nach Konfigurationserweiterungen und installieren Sie Microsoft dot Erweiterung nicht Optionen Punkt Konfigurationserweiterung. Das wird sich also als nützlich erweisen, wenn wir auf einigen unserer Sachen sitzen werden. Nachdem wir das alles getan haben, können wir weitermachen und eine neue Klasse erstellen. Und ich rief meine das Alter an, unser Lead Management BB Kontexte. Erstellen Sie also diese neue Klasse. Du kannst es etwas anderes nennen. Sie können es wahrscheinlich einfach verlassen Management, EB-Kontexte oder DVI-Kontexte nennen , das ist in Ordnung. Aber es wird jetzt von BB-Kontexten erben DVI-Kontexte Kommentare zu uns mit freundlicher Genehmigung von Microsoft dot Entity Framework Core. So können wir voran gehen und diese Referenz machen. Und dann können wir unseren DB-Kontext auf die verschiedenen Entitäten aufmerksam machen, die wir definiert hatten. Also, wenn Sie mit EF Core vertraut sind, dann wissen Sie genau, was ich meine. Also in dieser Datei haben wir ein paar Dinge. Wir haben einen Konstruktor, in dem wir unseren DB-Kontext initialisieren , um einen Parameter von DVI-Kontexten zu haben, Optionen aus seinem eigenen Typ, und der Name ist Optionen, und wir übergeben das an die Basis, die DVI-Kontexte . Dann haben wir unsere DB relativ zu unseren verschiedenen Entitäten sitzt. Also kann ich einfach voran gehen und die fehlenden Referenzen für diese einschließen und alles sollte alles grün sein. Als Nächstes werden wir ein paar Methoden außer Kraft setzen. Also der erste, den wir überschreiben, wäre das On-Model Create Team. Eigentlich ist es schneller, einfach über es zu tippen und dann drücken Sie Leertaste und dann werden Sie alle Optionen sehen. Also überschreiben wir das On-Model-Erstellen. Also wird diese Methode ausgeführt, wenn die Datenbank generiert wird, richtig? So können wir bestimmte Regeln aufsetzen. Also die Regel, die wir hier einrichten werden, zumindest, richtig? Nein. Wenn wir die Datenbank sehen wollten, können wir es von hier aus tun, aber wir sind nicht bereit für Seeding, da zumindest noch nicht. Wir wollen Konfigurationen aus der Montage anwenden. Und dann werden wir sagen, Art von DV-Management, DV-Kontext. Und ich werde sagen, Punkt Assembly. Ordnung? Das ist also alles, was wir zumindest in unser Modell einfügen, oder? Nein. Wie gesagt, wenn wir die Datenbank mit räumlichen Konfigurationen für Tabellen abspeichern wollten, könnten wir immer innerhalb dieser Methode, so dass sie angewendet werden, wenn sie im Datenbankmodell generiert wird. In Ordnung, eine andere Sache, die wir vor der Küste überschreiben wollen, ist unsere „Änderungen speichern“. Jemand zu wählen, um Änderungen mit der Stornierung Tolkien als Parameter zu speichern. Und ich werde diese Änderungen mit einem schönen Code ausstatten, netten praktischen Code, der uns erlauben wird, einige Audit-Protokollierung automatisch durchzuführen. Also denken Sie daran, dass wir eine Basiseinheit für jede von ihnen eingerichtet hatten , die automatisch mit wie ein Benutzer erstellt wurde, werden von oder anderen erstellt, erstellt eine Daten, et cetera. Also werde ich die foreach-Schleife so einstellen, dass sie jeden Eintrag in Änderungsstrukturpunkteinträgen durchläuft . Und wir machen nur eine implizite Datenkosten-basierte Domain-Entität. Und ich kann einfach voran gehen und die using-Anweisung dafür einschließen. Und dann für jeden, was ich tun möchte, ist das Datum, hinzugefügt, Datum, jederzeit geändert. Also kann ich immer sehen, wenn Sie im Begriff sind, eine Änderung zu sehen, ich möchte Einstiegs-Punkt-Entität, Punktglas modifiziert durch unsere Last-Modified Daten, sondern wir haben es mit dem Datum zu tun, richtig? Nein. Zeit. Nein. - Richtig. Und dann ging ich, um einen Scheck zu machen und ich werde nur sagen, ob der Einstiegsstatus Entitäten äquivalent ist, State DOT hinzugefügt, was bedeutet, dass es Schläge hinzugefügt werden, es ist ein neuer Datensatz. Dann würden wir das erstellte es auf datetime dot null setzen wollen. So erlauben wir, ist unser Datum eher erstellt, so dass wir immer die Last-Modified setzen. Es will, dass einige Dinge geändert werden. Eine Spannung, die wir sitzen, hat es verändert. Aber dann erst, wenn es hinzugefügt wird, setzen wir das erstellte es und so ist das. Der grundlegendste grundlegende Code für die Implementierung von Auditing, den Sie jemals finden können. Wieder einmal ist dies automatisiert, so dass jedes Mal, wenn wir Änderungen speichern drücken, all dies erledigt. Und dann verursachte es nur die Basis c von g und g ist Methode im Hintergrund. Das ist es also, um unsere Persistenzschicht in das Framework zu integrieren. Wenn wir zurückkommen, werden wir mit der Arbeit an einigen Implementierungen beginnen. 17. Durchdringung der Persistenzschicht: Willkommen zurück Jungs. In dieser Lektion werden wir unsere Persistenzschicht implementieren. Wenn ich also über die Implementierung der Persistenzschicht spreche, beziehe ich mich speziell auf unser generisches Repository, richtig? Also haben wir nur die Abstraktion, aber wir haben keinen Code, um dies zu sichern. Also lasst uns weitermachen und das tun. Also fügen wir einen neuen Ordner hinzu. Und ich werde diese Ordner-Repositories aufrufen. Und dann werden wir in diesem Ordner eine Klasse hinzufügen , die die Implementierung des generischen Repositorys relativ zum Typ T darstellt . Wir machen es wie üblich öffentlich, und dann machen wir es relativ zu t0. Und dann erbt es von IJ generisches Repository, das auch relativ zu T ist, wo T Doppelpunkt Klasse. Alles klar, gehen Sie weiter und fügen alle fehlenden Referenzen ein und erlauben Sie es dann, die Schnittstelle zu implementieren. Also schreibe ich das Zitat und dann gehen wir es zusammen durch. Nun, bevor wir fortfahren, erkannte ich, dass ich über Zillow, Schweiz für das Kopieren und Einfügen Telefon. Wir sitzen auf der Schnittstelle. So wie einige Cartoons für das Update und das Löschen, können wir das T entfernen, richtig? Wir sprechen nicht, um etwas zurückzugeben, wenn wir ein Update oder Löschen durchführen. Diese beiden sollten also nur Aufgaben sein, so dass Sie voran gehen und diese Änderung vornehmen können. Und dann wird das natürlich unsere Umsetzung beeinflussen. Unser generisches Repository beginnt also mit einem Konstruktor , der einen Parameter vom Typ leave management DVI-Kontexte akzeptiert. Natürlich ist der DB-Kontext im Grunde unsere Verbindung zur Datenbank. Also brauchen wir es in unserem Repository, um unsere Operationen durchzuführen oder Methode hinzuzufügen. Es beginnt mit unserer Gewichtung eines DB-Kontext-Aufrufs, um eine Senke hinzuzufügen, wo es gerade in Entität passiert, ist EF Core intelligent genug, um abzuleiten, welche Entität relativ zu allen DB-Sets übergeben wird , die in unserem DV-Kontext definiert wurden. Und mit db sitzen meine ich diese. Was auch immer Datentyp übergeben wird, wird er wissen, ob es einer der DB-Sets ist, die er erkennt. Also gehen wir einfach weiter und fügen die Entität hinzu, speichern Sie die Änderungen auf der neuen Rückkehr, diese Entität. Sie beim Löschen erneut EntfernenSie beim Löschen erneutden Typparameter aus der Aufgabe. Aber alles, was es tun wird, ist aussehen und DB-Kontext, finden Sie die Menge relativ zu t0, die es gegeben wird , und es wird diese Entität aus diesem Sitz entfernen. Alles klar, und danach speichert es Änderungen. So werden Sie feststellen, dass nichts wirklich passiert, bis Sie sehen, ob sich ändert. Dies ist das letzte Commit an die Datenbank. Wir haben die existierende Methode, bei der wir eine ID für unseren Datensatz erhalten. Und was ich tun werde, ist nach der Entität mit der lokalen GET-Methode zu suchen, die wir in einigen betrachten werden. Und dann kehren wir zurück, dass es nicht gleich null ist. Also, wenn es nicht gleich null ist, dann ja, es existiert, sonst ist das falsch. Natürlich, im Ghetto, was wir tun, ist, dass wir einen ungewichteten Aufruf an DB Context dot set t zurückgeben. Also noch einmal, wir suchen nach bestimmten Satz und wir finden den Datensatz relativ zur ID. In Ordnung, für unsere lese ich auf der Liste T, die alles bekommt, was es zurückkehrt. Alles, was wir tun, ist in der Menge zu suchen und wir machen eine zwei Listen asynchron für diesen Satz. Also bekommen wir nur alles von diesem Set und senden es an die Liste und geben das in unserer Gitarre für die Updates zurück, was wir tun, ist, den Eintrag in den Zustand zu setzen, um es zu ändern, so dass der EF Core, wir beginnen, es zu verfolgen und dann gehen wir voran und speichern Änderungen. Das ist also ziemlich viel für unsere Implementierung für das generische Repository. In Ordnung, jetzt, da wir unser generisches Repository implementiert haben, müssen wir jetzt unsere spezifischen Repositories implementieren, damit wir diese hinzufügen können. Beginnend mit dem Blatttyp-Repository werden wir uns ansehen, wie die Implementierung aussieht. Also habe ich das Blatttyp-Repository erstellt. Es ist eine öffentliche Klasse namens Leaf Type Repository, die von der Implementierung des generischen Repositorys relativ zum Blatttyp erbt. Alles klar, und dann gehen wir weiter und sagen, es ist auch, vom elif-Typ-Repository zu erben. Also zeigen die roten Linien hier ein paar Dinge an. Erstens müssen wir den fehlenden Namespace zu bringen, wir müssen in die tatsächliche Implementierung dieses, dieser Schwan, richtig, diese Schnittstelle hatte keine zusätzlichen Methoden, also ist das in Ordnung für null. Und dann beschwert sich das, weil wir den DB-Kontext vorhanden haben müssen. Für das generische Repository. Denken Sie also daran, dass Sie, wenn Sie etwas erben, das eine Abhängigkeit hat diese Abhängigkeit auch in den Erben setzen müssen. Das ist also eine einfache Lösung. Wir bekommen nur den Konstruktor und machen dann unsere Abhängigkeitsinjektion. Und das ist natürlich für den DB-Kontext, aber dann müssen wir auch den Bass Note lassen, dass er auch diesen DB-Kontext verwenden kann , der injiziert wird. Und das ist es für das Blatttyp-Repository. Der Vertrag hatte also keine zusätzlichen Methoden. Es gibt nichts Besonderes zu implementieren. Und weil es vom generischen Repository relativ zum Blatttyp erbt. Durch die Verwendung dieser Implementierung haben wir Zugriff auf alle Methoden, die hier definiert wurden. Sehen wir uns nun einige kompliziertere an. Schauen wir uns also Urlaubsanfragen an. Lassen Sie Anfragen Repository, ohne dies scheinen Abhängigkeitsanforderungen. Wir müssen also sicherstellen, dass wir den DB-Kontext, der den Bienen möglich ist, injizieren. Gehen Sie voran und schließen Sie alle fehlenden Namespaces ein, und dann müssen wir die Schnittstelle implementieren. Also hatte diese Schnittstelle tatsächlich ein paar Methoden, extra. Wir hatten Änderungsgenehmigungsstatus, wir hatten Urlaub Anfragen mit Details erhalten, und wir fügen eine weitere hinzu, um Urlaub Anfragen mit Details nach ID zu erhalten. Nur wenige Dinge geschehen in diesem speziellen. Die Implementierungen hier werden sich also von den generischen unterscheiden, da diese spezifisch für einige Operationen im Zusammenhang mit Urlaubsanforderungen sind. Die Implementierungen sind also wie folgt. Für die Änderungsgenehmigungsanforderung erhalten wir einen Parameter für Urlaubsanfragen und den Genehmigungsstatus. Wir setzen den genehmigten Zustand der Hebel-Quest auf den Wert, den sie erhalten hat, und den Parameter. Und dann setzen wir db-Kontexte keine Eingabe-Urlaubsanfragen. Sie sehen also, dass diese Zeit keine Entität ist, es ist nicht generisch. Es ist sehr spezifisch, weil wir in diesem spezifischen Repository sind. Also setzen wir den Einstiegsstatus oder den Entitätsstatus, ändern ihn für diese Urlaubsanforderung, und dann speichern wir Änderungen, so dass es beginnt es zu verfolgen und dann zu sehen, ob die Änderung entsprechend. Jetzt sehen Sie, dass dies eine sehr spezifische Operation im Gegensatz zu dem allgemeinen Update ist, bei dem wir nicht berücksichtigen können, was geändert wird. Also setzen wir einfach alles, um es zu modifizieren und es zu erlauben, LKW. Wieder einmal sind dies nur Ideen, weil Ihre Geschäftsregeln vielleicht viel komplizierter sind oder die Operation, die Sie innerhalb des Projektarchivs durchführen müssen, viel komplizierter ist als nur ein Feld zu sitzen. Daher benötigen Sie möglicherweise eine spezielle Funktion dafür. Jetzt für die Get's leave Anfragen mit der Details-Methode, alles, was wir wirklich tun, ist die Abfrage der Leave Requests Tabelle. Also var leave Anfragen sind gleich DVI-Kontexte zu warten, die Anfragen nicht verlassen. Und dann schließen wir den Blatttyp ein. Wir wollen also nicht unbedingt immer den Blatttyp einbeziehen. Wir wissen nicht, unter welchen Umständen wir es brauchen. Also haben wir diese relativ zu den Details, die neben dem Datensatz für den regulären generischen benötigt werden , der nicht einschließt, nur Daten aus der Tabelle zurückgibt. Diesmal enthalten wir Details. Es könnte dieser Blatttyp sein, es könnte mehr so viele enthält, wie Sie benötigen. Und dann schieben wir sie alle auf Listen. Und dann kehren wir zum letzten zurück, wo wir nur einen Urlaub Anfragen mit Details erhalten, die auf der ID basieren. Wir machen etwas Ähnliches, außer wir machen das Include und dann dx in der ersten oder Standard, wo die Warteschlangen-ID mit der ID Boston übereinstimmt. Jetzt machen wir zuerst unseren Standard hier im Gegensatz zu der Suche, eine Senke, die wir im generischen Repository gemacht haben, weil diese Methoden funktionieren, Sie können kein Include machen, wenn Sie eine Suche machen, es funktioniert einfach nicht. Wenn Sie also ein Include machen müssen, müssen Sie die erste oder die Single oder Standard verwenden, je nachdem, mit welcher Sie sich wohler fühlen. Und dann geben wir die Urlaubsanfrage zurück, die gefunden wurde. So können wir springen, um die Zuweisung zu verlassen und wir sehen, dass es eine relativ ähnliche Implementierung ist. Wir haben ähnliche Methoden. Also setze ich diese Methoden hier ein, nur um darauf hinzuweisen , dass Sie benutzerdefinierte Methoden in diesen Repositories haben können. Möglicherweise benötigen Sie sie nicht unbedingt in Ihrer Anwendung, verwenden Sie sie so, wie Sie sie benötigen. Ich behalte auch diese rote Linie, weil für den Fall, dass Sie in alles, was Sie brauchen, ist, diese Referenz, dass EF Core und dann ist das gut. In Ordnung, also haben wir noch eine wichtige Aktivität und dann sind wir fertig mit der Persistenzschicht. Und das ist, um die Registrierungsklasse für die Persistenz einzurichten. Also nur lokale Anwendungsdienste, Hadar Verteilung. Beharrlichkeit wird definitiv einen brauchen. Also gehen Sie weiter und fügen Sie diese neue Klasse hinzu. Ich rufe persistente Dienste oder Distribution an. Es sollte eine öffentliche statische Klasse sein. Und dann werden wir darin haben. Eine Methode, die zurückgibt, die ich als Sammlung diene und wir nennen es persistente Dienste konfigurieren. Also natürlich, wie üblich, gehen Sie vor und installieren Sie eine oder andere Any using Anweisungen, die benötigt werden. Und dann innerhalb dieser Methode, was wir tun werden, ist Code zu schreiben, um zu wandern. Sie speichern DB-Kontext und fügen unser Repository-Tool hinzu, die Service-Sammlung. Und das ist diese vollständige Methode, natürlich, was die roten Linien, weil immer lieben, Ihnen zu zeigen, was Redlands mir ein existieren und wie Sie sie lösen können. Aber so muss diese Methode aussehen. So können Sie voran gehen und beginnen, in die using-Anweisungen aufzunehmen, die fehlen. Also erstens haben wir den services.js ADB-Kontext, in dem wir den Typ übergeben, der die DB-Kontexte verlassen Management DB-Kontext und Optionen Punkt SQL Server ist . Erinnern Sie sich also an die DB-Kontexte, die wir ihm gesagt haben, dass wir im DB-Kontext beim Erstellen von Modellen gesagt haben, dass es im Konstruktor leid sein würde , richtig? Wir nahmen BB Kontexte Optionen. Diese Optionen kommen also wirklich von den Optionen , die hier definiert sind, einer Verteilung. Also gehen wir voran und verwenden EF Core für die Verwendung SQL Server-Konfiguration kommt in, weil wir gehen über die Konfiguration von der Client-Anwendung, die diese implementiert wird, genannt die Dienste Bootstrapper übergeben werden . Und so werden wir definitiv passieren müssen. Das ist kein Konflikt. Ich Konfiguration muss Microsoft-Erweiterungen Punktkonfiguration sein, nicht Herbst oben. Sei also sehr vorsichtig mit diesem. So können wir voran gehen und diesen Namespace einschließen. Und dann für Depositories haben wir Scoped hinzugefügt. Also fügen wir alle von ihnen sind Bereich. Aber dann für das generische, beachten Sie, dass wir den Typ des generischen ij Repositorys mit unseren eckigen Klammern Komma-Typ des generischen Repositorys, eckige Klammern hinzufügen . Aber dann ist jeder andere die Schnittstelle zum Implementierungspeer ohne irgendwelche Winkel Klammern. Aber ich gehe weiter und füge hier fehlende Referenzen hinzu. Und damit, und oh, tut mir leid, ich schrieb den Code falsch hier für diesen, fügen Sie Scoped ist offene Klammern und keine Winkel Klammern für die Anzeige geschult. In Ordnung, also lass mich das einfach wagen, damit du es sehen kannst. Da gehen wir. Es ist also umfangs Klammer, Typ des generischen Auges mit eckigen Klammern, Komma-Typ des generischen Repositorys mit eckigen Klammern. Ich tue es nicht wieder, diese sind in Klammern, während die anderen die eckigen Klammern haben, die das Interface und das Implementierungspeering umgeben. Nach all dem, natürlich geben wir Dienstleistungen zurück. Um also ein wenig darauf zurückzuverfolgen, was diese Verbindungszeichenfolge sein wird, haben wir noch keine App-Einstellungen, also wird dies in den Einstellungen der Anwendung leben , die diese Methode aufrufen wird. Wenn also persistente Dienste konfigurieren aufgerufen wird, wird erwartet, dass er mit diesem Konfigurationsobjekt möglich ist, das dann Zugriff auf die App-Einstellungen gewährt. Und wir werden in der Lage sein, diese Verbindungszeichenfolge zu möglichen Was ist unser DB-Kontext? Das ist also, was diese ganze Zeile oder dieser ganze Abschnitt tut. Nun, der Zweck der Kraft mit Scoped, gibt es drei Injektionsmodelle zur Verfügung, um uns. Wir haben in der Schule Singleton zu haben und Transient hinzuzufügen. Singleton bedeutet, dass bei einer Instanz dieses Dienstes existieren wird, werfen Sie die gesamte Anwendung. Dies kann aufgrund der Art des Dienstes gefährlich sein. Und es könnte nützlich sein, zum Beispiel, vielleicht ein Protokollierungsdienst, der einer im Sensor oder der gesamten Anwendung sein könnte. Sie möchten wahrscheinlich nicht so etwas für Ihre Datenbanktransaktionen. Denn wenn Sie dann mehrere Datenbanktransaktionen haben, möchten Sie, dass diese in Silos stattfinden. Deshalb würde es Scoped verwenden, was bedeutet, dass ich für die Lebensdauer unserer Suche etwas anfordere. Ich schreibe in die Datenbank, ich rufe Ihren Dienst für die Lebensdauer dieser Operation an. Dann add Scoped wird aufgerufen und Verbindung der Datenbank oder einer Instanz dieses Leaf-Typ-Repositorys oder einem dieser Repositories, wie es während unserer Anfrage aufgerufen wird. Sobald ich Anfrage fertig ist, wird es nicht mehr im Speicher sein. Das reduziert so die Konfliktchancen. Und dann fügen Sie Transient bedeutet, dass jedes Mal, wenn es immer etwas Neues tut, was bedeutet, dass Sie am Ende mehr haben können, als Sie wirklich brauchen, um eine Anfrage abzuschließen, was auch zu Konflikten führen könnte. Also wieder, Sie können sie sparsam verwenden, aber in diesem Kontext, add Scoped ist diejenige, die wir für unsere datenbankbezogenen Operationen wollen. jetzt mit all dem fertig, Lassen Sie unsjetzt mit all dem fertig,eine schnelle Rechnung machen, um sicherzustellen, dass wir richtig auf Kurs sind und dass wir keine Fehler haben und unsere Projekte erfolgreich aufgebaut haben. Wenn wir also zurückkommen, beginnen wir mit der Implementierung oder Infrastruktur. 18. Infrastrukturprojekt (E-Mail-Service): Willkommen zurück Jungs. In dieser Lektion werden wir unsere Infrastrukturprojekte einrichten, jetzt ist unser Infrastrukturprojekt ziemlich genau dort, wo die Implementierungen für alle unsere Drittanbieterdienste Platz finden werden. In dieser Lektion implementieren wir einen E-Mail-Dienst mit Hilfe von SendGrid. Und wir werden es im Infrastrukturprojekt einrichten. Nun ist das erste, was wir tun müssen, eine Abstraktion für die E-Mail-Absender einrichten, genauso wie wir Hindernisse für unsere Repositories hatten. Wir haben eine Behinderung unseres Vertrages für den E-Mail-Service. Nun, in diesem Zusammenhang habe ich zurückgeschaut und mir ist klar, dass die Ordnerstruktur hier auf lange Sicht nicht sehr intuitiv ist. Also ging ich weg, um hier zu refactorieren, weil ich Beharrlichkeit habe, dann habe ich Verträge. Aber Verträge sind der universellere Begriff, denn dann haben Sie Verträge für die Persistenz in ihren Verträgen für die Infrastrukturschicht und so weiter. Also werde ich umdrehen müssen. Diese Ordner sind im Besitz, was bei diesen sogenannten Persistenzordner-Verträgen nicht zu schwer sein wird. Und dann werde ich Verträge Beharrlichkeit nennen. Jetzt wird dies einen Ripple-Effekt für den gesamten Namespace haben, weil wir möchten , dass unsere Namespaces vollständig repräsentativ für das sind, was sie wirklich sind. Also haben wir Persistenz Punktverträge, nein, wir müssen das in Verträge ändern, die Beharrlichkeit gedacht haben. Und dann wird dies mit allen Namespace-Referenzen vermissen. Tut mir leid, schrecklich das. Aber es ist ein Faktor, der definitiv erforderlich ist um eine intuitive Ordnerstruktur zu haben, oder? Nach all dem, wenn wir einen Build machen, wird es auf alle Butt-Namespaces hinweisen, die in unserem Projekt referenziert wurden. Also, wissen Sie, schneller Weg, um voran zu gehen und diese zu reparieren. Aber Namespaces würden darin bestehen, überall nach Persistenzpunktverträgen zu suchen und sie dann durch Verträge dot br System zu ersetzen. Also können Sie das einfach tun und akribisch durchgehen und ersetzen jeden Begriff tut mir sicher, dass Sie nichts überschreiben, was wichtig sein könnte. Und sobald Sie diese Suche erschöpft haben, können Sie voran gehen und eine weitere Rechnung machen, nur um sicherzustellen , dass Sie keine Build-Fehler mehr haben. Und wenn das erledigt ist, schließe ich einfach alle Wannen, die bei der Operation geöffnet wurden , und dann können wir wieder gehen. In Verträgen wollen wir also einen neuen Ordner, unsere nennen diese eine Infrastruktur. Und dann werden wir in diesem Ordner einen neuen Vertrag oder eine neue Schnittstelle hinzufügen. Und ich nenne es ich e-Mail-Absender, weiß, dass ich e-Mail-Absender öffentliche Schnittstelle mit einer Methode sein wird, die E-Mail senden aufgerufen wird. Und es wird einen Parameter vom Typ E-Mail namens E-Mail nehmen. Jetzt müssen wir definieren, wie diese E-Mail aussieht. Also werde ich einen anderen Ordner für Modelle erstellen, richtig? Also lassen Sie mich einfach diesen Ordner hinzufügen. Wir nennen es Models. Und dann fügen wir im Ordner dieses Modells eine neue Klasse hinzu, die wir E-Mail aufrufen. Dies wird also unsere Vorlage sein, unser Modell dafür, wie jede E-Mail aussehen sollte. Und dann wird diese E-Mail die typischen Eigenschaften jeder E-Mail, die an den Betreff und den Körper, alle String-Eigenschaften haben. Jetzt, da wir dieses Modell definiert haben, können wir voran gehen und die using-Anweisung hinzufügen und das aussortiert haben. Bevor wir von unseren Modelldefinitionen weitergehen, haben wir ein anderes Modell, das wir brauchen, und dieses wird für die E-Mail-Einstellungen sein. Ordnung, also geht es um Schlaucheigenschaften für einen API-Schlüssel von der Adresse und dem Von-Namen, die alle eine Zeichenfolge sind. Nun, da wir ein paar Dinge frisch mit unserem E-Mail-Absender haben, fragen Sie sich wahrscheinlich, okay, warum brauche ich E-Mail? Also setzt es dann in den Kontext, weil wir gerade angefangen haben, den E-Mail-Dienst ohne reale Kontexte zu bauen. Wenn sich jemand für Blatt bewirbt oder sich sein Genehmigungsstatus so etwas ändern, möchten Sie ihn darüber informieren, dass diese Aktion stattgefunden hat. Keine seltsamen Aktionen finden gut in Bezug auf Funktionen statt, wir haben unsere Handler. Wenn Sie also eine neue Live-Zuteilung erstellen, müssen Sie vielleicht keine E-Mail senden, aber dann würde eine Urlaubsanfrage sicherstellen, dass eine E-Mail gesendet wird , wenn eine erstellt wird oder eine aktualisiert wird. In Ordnung, also lassen Sie uns den Create leave Request Handler betrachten wo wir einfach injizieren können oder ich maile Absender. Und ich werde das einfach mit dem IntelliSense tun. Initialisieren Sie das Feld schnell. Und dann, angesichts unserer Namenskonvention, werde ich dies einfach mit dem Unterstrich in unserem Handler umbenennen , nachdem alles erfolgreich war, bevor wir zurückkehren und die gesamte Operation beenden. Also geht der Handler immer noch auf diese Linie. So wird ein E-Mail-Objekt erscheinen und dann versuchen, es abzuschicken. Und wir beschäftigen uns mit einer Ausnahme. Schauen wir uns das langsam an. So var E-Mail ist gleich einer neuen E-Mail, die unser Modell ist, das wir gerade definiert haben. Wir haben die beiden, ich habe nur eine fiktive E-Mail dort, wenn wir zur gesamten Benutzerauthentifizierung kommen und tatsächliche Benutzer einreichen. Und wir werden uns ansehen, wie wir die tatsächlichen E-Mail-Adressen bekommen. Wir haben die Leiche. Und der Text dieser E-Mail sagt nur Ihre Urlaubsanfrage für und ich setze nur Interpolation ein, um den Inhalt Anfang zu beenden. Es wurde erfolgreich eingereicht und der Betreff ist Urlaubsanträge eingereicht. Wenn Sie möchten, können Sie das Datum weiter anpassen, indem Sie den Doppelpunkt D aktivieren. Traditionell würden Sie ToString sagen und dann das Format angeben. Aber wenn wir Interpolation in dieser Version von C Sharp verwenden, können wir einfach auf Doppelpunkt und die Formatierung setzen, na ja, die Formatierungszeichenfolge am Ende davon. Und das wird sich für uns darum kümmern. Also würde d Ihnen den langen Namen geben. Montag, Juni dieses Datum, in diesem Jahr. In Ordnung. Also, das ist es für oder Handler wissen, dass unsere gesamte Anwendung über den Eye E-Mail Absender weiß , müssen wir an der Implementierung arbeiten , so dass die Implementierung dieses wird in unserem Infrastrukturprojekt leben. Um damit zu beginnen, erstellt das einen neuen Ordner innerhalb des Infrastrukturprojekts namens Mahlzeit. Und dann erstellen Sie eine Klasse dort genannt e-Mail-Absender. Und dann wird diese Klasse, die natürlich das sind die Öffentlichkeit von i e-Mail-Absender erben. So können wir voran gehen und dann erkennen Sie, dass es einen Verweis auf die Anwendung benötigt. Also müssen wir weitermachen und das hinzufügen. Und mit dieser Referenz können wir voran gehen und die Schnittstelle implementieren. Bevor wir also weiter gehen, müssen wir zum neuen Git springen. Und wir brauchen ein paar Pakete. Swan ist die gleichen Konfigurationserweiterungen , die wir von den anderen Projekten verwendet hätten. Eine schnelle Möglichkeit, gemeinsame Projekte zu verwalten, besteht also darin, einfach zu dieser Lösung zu gehen und Managed NuGet-Pakete für die Lösung zu sagen, richtig? So haben wir bereits einige Pakete in einigen Projekten installiert , die wir in anderen benötigen, wie diese, die Konfigurationserweiterungen. So kann ich darauf klicken und ich sehe, dass es bereits in den Persistenzprojekten ist, aber ich wollte im Infrastrukturprojekt auch ich kann es ankreuzen, klicken Sie auf Installieren. Und so kann das die Zeit reduzieren, die Sie für NuGet verbringen , um das gleiche Paket immer wieder zu finden. Jetzt ist das nächste Paket, an dem ich interessiert bin, SendGrid. So können Sie zu den Bros springen und einfach SendGrid einsteigen, und dann können Sie die neuesten Versionen erhalten. Sie möchten also darauf klicken, stellen Sie sicher, dass Sie das richtige Projekt ausführen, und klicken Sie dann auf Installieren. Also, nachdem das installiert ist, werden wir beginnen, diese Klasse zu verdrahten. Eine Sache, die ich tun werde, ist, ein privates Feld vom Typ E-Mail-Einstellungen einzurichten und auf seine Unterstriche E-Mail-Einstellungen schreibgeschützt zu machen. Aber dann initialisiere ich es im Konstruktor mit diesem i-Optionen Email Settings Parameter. Lassen Sie mich nun erklären, was das ähnlich ist wie wir unsere Datenbank eingerichtet hatten. Und wir sagten, dass wir eine App-Einstellungsdatei haben, die wir die Verbindungszeichenfolge bereitstellen, wenn die Zeit kommt. Das ist die gleiche Art und Weise, wie wir übergehen können. Optionen sind Chunks von Optionen sind Konfigurationen aus der, aus der gesamten App-Einstellungsdatei, die dann in ein ganzes Objekt für uns deserialisiert werden kann. Also, was wir tun, Sie sehen, bekommen mich von der, von den Optionen sind die App-Einstellungen, die E-Mail-Einstellungen, JSON-Äquivalent, und senden Sie es über als diesen Parameter. Und dann können wir es einfach injizieren und es dann als unsere lokale Variable haben, unser Feld in unserer Klasse. Diese Abhängigkeitsinjektion ist also so cool, weil sie alles so locker gekoppelt und formbar macht . Lassen Sie uns also mit der Einrichtung unserer Send Email Methoden fortfahren. Die erste Zeile, die wir haben werden, ist ein Client, der einen SendGrid-Anspruch aufrufen oder initialisieren wird . Also gehen wir einfach voran und fügen Sie Anweisungen hinzu, die fehlen. Dann, nachdem wir den Client bekommen haben, müssen wir den ganzen Betreff und die beiden und den E-Mail-Text von unserem E-Mail-Objekt abrufen. Aber die beiden und das von besonders müssen ein spezieller Datentyp sein. Also werde ich sagen, var 2 ist gleich neuer E-Mail-Adresse. Und die E-Mail-Adresse hier kommt aus dem Sündenraster. So neue E-Mail-Adresse. Und dann müssen wir in E-Mail Dot Tube übergeben. Und dann müssen wir dasselbe für die von tun. Also werde ich sagen, var von ist gleich neuer E-Mail-Adresse. Und in diesem, werden wir Sie irgendwie in die Definition setzen, wo ich sehen werde die E-Mail von der E-Mail-Einstellungen Punkt von Adresse kommt. Und dann wäre der Name der E-Mail-Einstellungen Punkt von Name sein. Ordnung. Also haben wir das von und das bis definiert. Und dann, nachdem wir all das getan haben, müssen wir es sehen. Nachricht ist gleich männliche Hilfe ihr. Also Male Helper ist, das wird eine statische Klasse sein, die uns von sin grid gegeben wird, die uns erlaubt, einzelne E-Mail zu erstellen. Da gehen wir. Und Sie sehen, dass Sie verschiedene Optionen für mehrere Empfänger und mehrere E-Mails haben. Mehrere Empfänger haben in dieser Situation nur einzelne E-Mails gemacht. Aber Sie können sehen, dass Sie vielleicht E-Mail gesendet haben, senden Sie E-Mail an mehrere senden E-Mail mit einem Anhang, et cetera. So können Sie verschiedene Methoden innerhalb des E-E-Mail-Absenders definieren. Du bist nicht nur auf diesen, den wir tun, beschränkt. In Ordnung? So erstellen Sie einzelne E-Mail. Und dann müssen wir das alte füllen, nach WER sie es in der angegeben haben, in den Parametern für den Konstruktor. Also kommt der Fromm an erster Stelle. Und dann sagen wir auch, wir haben die. Und dann der Betreff, kann ich E-Mail Lot Betreff hier sehen. Und der Nur-Text-Inhalt wäre der E-Mail-Text. Und Sie können sehen, dass sie den Nur-Text-Inhalt im Vergleich zum HTML-Inhalt haben. Basierend darauf, wie Sie Ihre E-Mail verschlüsseln, könnten Sie diese E-Mail entsprechend zusammenstellen, oder? Aber im Moment werde ich nur E-Mail-Punktkörper für beide Parameter sagen. Also, jetzt, da wir das Nachrichtenobjekt formuliert haben, werde ich sagen, var Antwort ist gleich den Kunden, die E-Mails senden. Also hier werden wir tatsächlich die Nachricht abschicken, die wir gerade erstellt haben. Natürlich bekommen wir die rote Linie, weil wir ein Waschbecken sein müssen. Und sobald das erledigt ist, müssen wir keinen Booleschen Wert basierend auf der Antwort zurückgeben. Ich kann einfach zurückgeben sagen, wenn Antwortstatuscode äquivalent ist und ich kann einfach system.in es ist HTTP-Statuscode. Ok. Und ich glaube, dass SendGrid auch für akzeptierten jemanden sorgt, der beides tut, einige Rückkehr. Ich komme gerade zurück. Entweder ist es okay oder akzeptiert. Das wird also, wenn es einer von ihnen ist wahr. Wenn es keiner von ihnen ist, dann ist es falsch und sie werden wissen, ob die E-Mail erfolgreich war oder nicht. Aber der ganze Punkt davon, ich gehe wieder zu unserem Create Tumblr zurück und die Art und Weise, wie wir es in einen Try Catch eingewickelt haben, die API, die diesen Handler aufruft oder welchen Code diesen Handler aufruft , sollte nicht unterbrochen werden, wenn alles andere. Dies ist also der wichtigste Teil der Erstellung der Urlaubsanfragen, wenn die E-Mail-Felder, es bedeutet nicht, dass es das Programm abstürzen sollte. Deshalb fangen wir die Ausnahme ab, aber wir tun nichts, um sie durch die ganze Anwendung zu werfen. Nun, um alles abzuschließen, wir werden eine Registrierungsdatei für Infrastrukturdienste haben, genau wie bei jedem anderen Projekt davor. Wir haben also die Registrierungsklasse für Infrastrukturdienste die diesen Infrastrukturprojekten hinzugefügt wird. Und dann haben wir die gleiche Form, die alle anderen Verteilerklassen hatten. Wieder einmal wird ich Konfiguration injiziert. Und der Typ, der wir sind, der Namespace, den wir brauchen, ist die Microsoft-Erweiterungen Konfiguration, nicht Herbst oben und ich werde es jedes Mal aufbringen , weil es ihn mehr als eine gefangen hat, sorry. So werden wir sehen, Dienste dot konfigurieren E-Mail-Einstellungen. Also das alles studiert es, dass wir E-Mail-Einstellungen wollen. Ich werde nur bringen, dass man in B relativ zu einem Konfigurationsserver MouseY E-Mail-Einstellung, wenn wir die Punkt-Optionen tun, wir sehen, geben mir einen Teil der Konfiguration, die wie das Objekt EMEA-Einstellungen aussieht. Nun, was wir wirklich sehen werden, ist der Konfigurationspunkt bekommt Abschnitt. Und es wird in den App-Einstellungen für unseren Abschnitt mit dem Namen suchen. Wir rufen mich E-Mail-Einstellungen an, wenn die Zeit gekommen ist. Weise wird es wissen, dass wir diesen Abschnitt so formulieren , dass er genau so aussieht, wie wir erwarten, dass die Klasse aussieht. So wird es nur automatisch in diese hartcodierte Klasse serialisiert sind stark typisiertes Glas eher. Nächster Halt werden wir Dienste sehen, die Transient hinzufügen. Denken Sie daran, dass ich über die verschiedenen Modelle gesprochen habe. haben wir. Singleton, formen und transient. Also vergänglich bedeutet jedes Mal, wenn ich angerufen werde, werde ich eine brandneue Instanz sein. Also sehen wir, dass jedes Mal, wenn ich E-Mail-Absender angerufen wird, Geben Sie mir eine brandneue Instanz der, der E-Mail-Absenderklasse. In Ordnung, also gehen Sie weiter und fügen Sie alle fehlenden Referenzen ein. Und dann können wir das schließen und dann den Service zurückgeben. Das ist es also, wenn wir unsere Infrastruktur aufbauen, zumindest ist das eine sehr grundlegende Ebene. Wieder einmal werden alle Verträge, die wir für einen Drittanbieterbetrieb definieren müssen , in unserer Anwendung definiert, aber in unserer Infrastruktur implementiert. 19. Application erstellen und konfigurieren: Willkommen zurück Jungs. In dieser Lektion werden wir unsere API-Projekte einrichten. So haben wir das Fundament bereits in Form der Infrastruktur, der Persistenzprojekte oder Domain und unserer Anwendungsprojekte. Die Sache ist, dass sich diese mit Ihrer Anwendung entwickeln werden. Diese Schichten sind also diese Projekte. Sie sind nicht in Stein gesetzt, aber wir haben zumindest die Grundlage dafür geschaffen, eine API darauf zu bauen, die tatsächlich verantwortlich für toxische Informationen zwischen allen Client-Anwendungen und diesen Schichten für uns ist. Also lassen Sie uns mit der Einrichtung dieser API-Projekte beginnen. Wir werden es in unserem Ordner namens API ablegen. Wir gehen zu Neues Projekt hinzufügen, finden es leicht, können einfach in der Liste nach API suchen. Und wir verwenden die C-Sharp API-Projektvorlage, und wir nennen diese eine HR Dot Leave Management Dot API. Gehen Sie weiter und drücken Sie Weiter, und wir verwenden dotnet fünf sind die neueste Version, weil.net ist sehr abwärtskompatibel. Also die meisten, wenn nicht alles, was wir tun wird dieser Kurs mit zukünftigen Versionen von dotnet kompatibel sein und wir werden mit den Einstellungen fortfahren und erstellen. Jetzt ist dieses API-Projekt ziemlich nackte Knochen. Es gibt uns einige Beispielcode in Form dieser Wettervorhersagen Controller, die wir nicht unbedingt brauchen werden. Bevor wir vorwärts gehen, lassen Sie uns die Abhängigkeiten hinzufügen, die dieses API-Projekt haben wird. Und diese Abhängigkeiten umfassen unser Anwendungsprojekt oder Infrastrukturprojekt und oder Persistenzprojekt. So ziemlich jedes der Projekte, in denen wir diese Register-Service-Methoden einrichten würden . werden Abhängigkeiten für die API sein, da die API in der Lage sein muss, diese Dienste in ihrer Codebasis zu registrieren. So können wir einfach voran gehen und diese Projektreferenzen hinzufügen. Und sobald wir das getan haben, können wir unsere Konfiguration fortsetzen. Also, wenn wir über das Erstellen und Konfigurieren sprechen wir haben keine erstellt, wir müssen konfigurieren. Also in Bezug auf die Dinge, die Abhängigkeiten davon haben, was wir in der API sitzen werden. Wir sprechen über die E-Mail-Einstellungen. Also denken Sie daran, dass in unserer Infrastruktur würden wir erwähnt haben, der E-Mail-Absender oder würde E-Mail Absender andere implementiert haben und es ist abhängig von E-Mail-Einstellungen kommen über KI-Optionen, E-Mail-Einstellungen, die wir bereits besprochen wird, wird aus unserer App-Einstellungsdatei kommen. Eine andere Sache, die wir einrichten müssen, ist für unsere Persistenzschicht. Sorry, ich wähle nur wild für Persistenzschicht oder DB aus. Der Kontext ist abhängig einer Verbindungszeichenfolge, die erneut von der API angezeigt wird. Also unsere App-Einstellungsdatei hier haben wir Blöcke oder Abschnitte, die diese Definitionen haben. Also lasst uns am ersten arbeiten, und das ist unsere Verbindungszeichenfolge. Also über dieser Protokollierungsdefinition hier werde ich nur die Eingabetaste drücken und dann werde ich meinen Verbindungszeichenfolgenabschnitt einfügen. Also Verbindungszeichenfolgen. Und dann hat es den gleichen Namen wie das, was wir in der Persistenzumverteilung erwähnt hätten , oder? Verbindungszeichenfolge abrufen. Und dann ist es verlassen Management-Verbindungszeichenfolgen. So weiß die Verbindungszeichenfolge, in der App settings.js ON nach Verbindungszeichenfolgen zu suchen, erhalten Sie diese nach Namen. Und seine Definition hier ist, dass ich den lokalen MS SQL DB-Server verwende, also müssen Sie ihn so eingeben, wie Sie es auf dem Bildschirm hier sehen. Das ist in Visual Studio integriert. Datenbank ist gleich, und ich rufe meine HR Unterstrich verlassen Management-Unterstrich DB. Man kann es etwas anderes nennen, wenn man es wünscht. Und abgesehen davon, und jeder ist Semikolon getrennt und dann haben wir vertrauenswürdige Verbindung ist gleich wahr Semikolon mehrere aktive Ergebnissätze ist gleich wahr. Das ist also Ihre Verbindungszeichenfolge. Jetzt für E-Mail-Einstellungen, wir werden einen neuen Abschnitt namens E-Mail-Einstellungen haben, und dann haben wir diesen API-Schlüssel. Also muss ich, wir müssen mit dem SendGrid gehen, dann bekommt unseren API-Schlüssel Plötzlichkeit setzen einen Platzhalter für null. Und dann haben wir den von Namen, das ist, wo die E-Mail scheint zu kommen und dann die von Adresse wird keine Antwort auf verlassen management.com oder verlassen Antwort. Keine Antwort, sorry, bei Ahrq.com, was immer Sie wollen. Jetzt, falls Sie nicht sehr vertraut sind mit dem, was SendGrid ist. Es ist ein zweistufiges Produkt, das uns Zugriff über Paul für E-Mail-API-System ermöglicht. Und Sie können einfach kostenlos starten. Es ist natürlich bis zu einem gewissen Punkt kostenlos , und Sie wollen es nicht missbrauchen. Aber sobald Sie sich anmelden, erhalten Sie diesen API-Schlüssel, was Sie direkt in den E-Mail-Einstellungen, in der App settings.js IN bleiben können . können wir später machen. Natürlich möchte ich nicht, dass Sie meinen Schlüssel sehen, weil der Schlüssel privat ist, also möchten Sie sicherstellen, dass Sie damit die Privatsphäre bewahren. Also, jetzt, da wir unsere AP settings.js, JSON-Datei mindestens o mit den mindestens vier oder Verteilung unserer Dienste ausgestattet. Lassen Sie uns zur startup.js springen. Sie sind also nicht einige der Datei startup.js. Es ist im Grunde der Container, der besagt, dass dies alle Abhängigkeiten sind, über die meine Anwendung wissen muss. Und ich mache sie durch Abhängigkeitsinjektion zugänglich. In Ordnung. Wir reden jetzt schon seit einiger Zeit über Abhängigkeitsinjektion. Und jede dieser Registrierungsdateien erlaubt es uns im Grunde , diese als Abhängigkeiten in einer Anwendung zu registrieren. Was wir also tun müssen, ist unsere API wissen zu lassen , dass dies Abhängigkeiten sind, über die jeder wissen sollte. Wenn wir also über die Icon-Figuration gesprochen haben, bemerken Sie, dass es in den Start übergeben wird, während es direkt in den Start injiziert wird. Und das erlaubt uns, dieses Konfigurationsobjekt dann in andere Teile unserer Umverteilung zu übergeben . Also hätten wir es in der Infrastruktur gesehen, wenn ich mich nicht irre, da gehen wir. Ich Konfiguration benötigt die Konfiguration und wir brauchen sie auch für die Persistenz. Genug reden, lasst uns ins Geschehen kommen. In unserer Konfigurationsdienstmethode möchten wir diese drei Zeilen einschließen, nämlich die Application Services konfigurieren, Infrastrukturdienste konfigurieren und persistente Dienste konfigurieren, von denen wir alle kennen Boot kommt von unseren oder Ferndienste, Service Umverteilung Dateien in den verschiedenen Projekten. Also hier ist der Fang. Es wird also einfach weitergehen und alle fehlenden Abhängigkeiten und Namespaces für jeden dieser hinzufügen. Bitte beachten Sie auch, dass wir diese Konfigurationsobjekte übergeben müssen. In Ordnung, also haben wir es in das Startup injiziert und dann können wir es weiterleiten, so dass, wenn diese Methoden in ihren jeweiligen Projekten aufgerufen werden und sie über die notwendigen Tools verfügen , um auf das zugreifen zu können, was sie brauchen, um von unserer App aus zugreifen zu können -Einstellungen. Eine andere Sache, die wir in dieser API einrichten möchten, ist, oder was wir CORS-Richtlinie nennen. Unsere Kursrichtlinie bestimmt also grundsätzlich wie die API anderen Clients erlaubt, damit zu interagieren. Also im Moment ist diese Politik ziemlich offen. Wo sieht der Dot-Dot-Dot-Dot-Cores Builder jeden Ursprung erlauben, jede Methode zulassen, einen beliebigen Header zulassen. Dann in unserer Konfigurationsmethode gehen wir nach unten und ich werde es nur hier zwischen Use Authorization und Verwendung von Endpunkten kleben . Und das wird aufgeklärt und auch nicht, dass sie diese Politik durchgängig nutzen sollte. Jetzt haben wir einen guten Weg mit allen Konfigurationen. Wir haben noch einen weiteren Schritt für diese Lektion, und das ist, unsere Datenbank zu generieren. Also haben wir all das Setup erledigt. Wir haben die Persistenzschicht jetzt haben wir sie tatsächlich verdrahtet. Nein, wir übergeben tatsächlich die Verbindungszeichenfolge. Jetzt weiß es, dass, wenn es existiert, auf welchem Server es existieren sollte und wie der Datenbankname sein sollte. Also lassen Sie uns unsere eigene zu kommen Konfiguration unserer Datenbank kommen. Wir müssen also Migrationen ausführen. Und ich mache nur einen schnellen Build, der erfolgreich war. Bevor wir also zu den Migrationen übergehen, müssen wir Zugriff auf unser EF Core-Tool erhalten. Also geh in den Paketmanager, all das. Es wird nach Werkzeugen suchen. Und sicher genug, Microsoft dot Entity Framework Core Tools ist die zweite in den Suchergebnissen. Also werde ich das in meinem API-Projekt installieren. Und mit diesem Setup werde ich auch das API-Projekt als meine Start-up-Projekte festlegen. Also kann ich das aus diesem Dropdown-Menü tun, Viele oben, oder ich könnte mit der rechten Maustaste darauf klicken und sagen, als Startprojekt festgelegt. Jetzt können wir mit all dem fertig sind, zu unserer Package Manager-Konsole fortfahren. Wenn Sie es also nicht in Ihren Menüelementen oder als Symbolleiste wie ich haben, können Sie immer zu Tools gehen, zum NuGet-Paketmanager und die Konsole dort aufgelistet sehen. In dieser Package Manager-Konsole werden wir SHE-Migration hinzufügen und wir können ihr einen Namen geben, so dass ich es nennen kann anfänglich erstellen initiale Migration, etwas, um anzuzeigen, dass es die erste war, richtig? Eine andere Sache, die Sie tun möchten, ist die Standardprojekte zu ändern. Das Standardprojekt muss also das gleiche Projekt sein, in dem Ihr DB-Kontext eine Einstellung ist, die das Persistenzprojekt ist. Und für Kontexte, denken Sie daran, dass in unserem Persistenzprojekt oder einem DB-Kontext wir gesagt hatten, dass das Modell in der Nicht-Modell-Erstellung, wir sagten, Anwenden von Konfigurationen aus der Assembly und wo immer dies die Assembly ist, Das ist ziemlich genau das, was diese Zeile angegeben hat. Also brauchen wir hier unser Migrationsverzeichnis. Stellen Sie also sicher, dass das gesetzt ist. Wenn Sie es nicht tun, erhalten Sie einen bösen Fehler. Ein Boot, das auf das falsche Zielprojekt gesetzt wird. Also, wenn wir voran gehen und hinzufügen, dass Migration wird seine Magie zu tun. Und dann bekommen wir diese Migrationsdatei, die uns all diese Tabellen gibt, die wir ursprünglich erstellt hatten. Also kurze Tour durch unsere Migrationsdatei, wenn Sie nicht so vertraut sind, haben wir eine Op-Methode und Add-on-Methode. Die andere Methode hat im Grunde Code und wenn Sie es nur als C-Sharp-Entwickler lesen, als SQL-Entwickler, sehen Sie, was es tut. Es erstellt eine Tabelle mit dem Namen, mit diesen Spalten, mit all diesen Fix für jede Spalte. In Ordnung? Und dann bedeutet das, dass, wenn Sie diese Migration rückgängig machen, dies die Dinge sind, die tun werden. Es wird die gleichen Tabellen fallen lassen. Also für jeden da oben ist Erwachsener. Nun, da wir unsere Migrationsdatei vorhanden haben, können wir fortfahren und die Datenbank aktualisieren. Die Datenbank sagt also im Grunde, wenn sie nicht existiert, werden erstellt. Wenn es existiert, werde ich die Änderungen übernehmen. Es existierte nicht. So hat es es nur Schnee erschaffen. Und um zu überprüfen und zu überprüfen, ob es erstellt wurde, können wir zum SQL Server Object Explorer gehen, erweitern und erweitern Sie den lokalen DB Schrägstrich und Mrs Hill lokale DB macht den Server, den wir angegeben haben. Und wenn Sie einen anderen Server verwenden, können Sie zu diesem bestimmten Server fortfahren. Und wenn wir expandieren, ist es eine Basis, wir werden unsere EHR DV Management dB sehen. Und wenn wir die Tabellen erweitern, werden wir unsere Tabellen sehen, die entsprechend definiert wurden. Wir haben keine Gefahren gesehen. Alle Tische sind leer. Später, wenn wir beginnen, unsere eigene Anwendung zu bauen, können wir voran und schauen, wie ISI Daten. Aber im Moment ist dies Mission erfüllt. 20. Thin API Controller: In dieser Lektion werden wir uns mit dem Hinzufügen von Vermittlungsdiensten zu unserer API beschäftigen. Nun, der Kontext dafür ist, dass Medien uns erlauben, Verhaltensweisen in unserer Anwendung basierend auf einer Antwort auf Handler-Typ der Beziehung anzugeben . Eine der Konsequenzen oder Vorteile daraus ist, dass wir viele der schweren Operationen von unserem aufrufenden Code versenden können , der in diesem Fall unser Controller sein wird. Und das können wir woanders abstrahieren. Also weiß der Controller wirklich nur, dass ich eine Anfrage erstelle und ich schicke sie ab, um behandelt zu werden. Also für den Kontext habe ich auf dem Bildschirm den Controller aus dem vorherigen Projekt, was Inspiration für uns ist, dieses Bedarfsmanagementsystem zu wiederholen. Und hier würden Sie sehen, dass wir keine dünnen Controller haben, wir haben Fett-Controller. Also sind sie Kontrolleur, wirklich. genau das, was der Name sagt, steuert den Fluss und alles, was die Anwendung tut. So reagiert es auf Anfragen eines Benutzers nach Daten, et cetera. Nun, im älteren Projekt, hatten wir, was wir Fat-Controller nennen, oder wir tun alles innerhalb des Controllers. Wieder einmal funktioniert das. Es ist also nicht so, dass es nicht funktioniert. Wenn es getan ist, werden wir arbeiten. Aber ist es das am besten praktizierte Holman Tenable ist das? Denn wenn ich überprüfen wollte, dass diese Operationen erfolgreich durchgeführt werden, würde ich eine Menge Schwierigkeiten haben es auf diese Weise zu testen, weil dies nicht in einer Vereinigung ist, das ist genug innerhalb unseres Controllers. Das erhöht meine Unfähigkeit, die Teile der Anwendung zu testen , um sicherzustellen, dass sie ordnungsgemäß funktionieren. Und es erhöht meine Zeit für die Fehlerbehebung und Regressionstests und all diese Dinge. Hier überprüft es, ob etwas existiert und wenn es nicht existiert, gibt es kein Telefon zurück. Und dann macht es Mapping und es macht eine Suche, und dann gibt es die Ansicht zurück. Lesen Sie Andrew, wollen Sie nur so wenige Farben wie möglich ohne Geschäftslogik. Dies ist eine Form der Geschäftslogik. Das wollen wir nicht wirklich in unserer Anwendung. In Ordnung, hier ist eine andere Situation, in der wir unsere Platte erstellen und wir tun einfach zu viel in dieser Option. Das sind also die Dinge, die wir reduzieren wollen, wenn wir mit dünnen Controllern sprechen. Lassen Sie uns also beginnen, indem Sie Mediator in unseren API-Projekten installieren. Sie kennen den Bohrer, Sie können einfach mit der rechten Maustaste gehen Sie zu NuGet. Wir haben nach Mediator gesucht und installieren es. Sobald Sie diese Schritte abgeschlossen haben. Sobald Sie damit fertig sind, gehen wir weiter und fügen Sie unserem Projekt einen neuen Controller hinzu. Es ist ein MVC-Controller und wir wollen einen API-Controller mit Umleitungsoptionen. Wir werden mit der einfachsten beginnen, die Art verlassen und gehen Sie voran und fügen Sie hinzu. Lassen Sie uns nun untersuchen, wie Medien uns irgendwie helfen werden, oder? So haben wir bereits die grundlegenden guten Optionen, die für uns zum Glück generiert werden. Aber dann müssen wir unser Mediatorobjekt in unseren Controller injizieren. Also wirst du an Schlaganfall arbeiten. Und dann werden wir auf I. verweisen. Mediator wird von uns verlangen, dass wir diese using-Anweisung haben sowie dieses Feld initialisieren. Und dann können wir diese Medien nutzen, um Arcbest Straßen zu widersprechen oder Schnee zu verursachen. Kurzer Rundgang durch diesen Controller. Und an diesem Punkt gehe ich natürlich davon aus, dass Sie mit Controllern vertraut sind. Und durch Erweiterung, API-Entwicklung, wenn wir die Liste der Datensätze erhalten wollen, sind alle Urlaubstypen in der Datenbank werden diese Methode treffen, die nur ihre API-Slash-Typen bekommt. Das ist es, was erwartet wird, um uns zu erreichen, aber alle Blatttypen. Und dann würde jede dieser Methoden auf die anderen rohen Operationen übertragen , die den Put, das Löschen sind. Es ist für Updates. Oder wenn Sie nicht so vertraut sind mit dem, wovon ich spreche, würde ich Sie ermutigen, meine API-Entwicklungskurse zu überprüfen, damit Sie voll und ganz wissen können , was die Feinheiten hinter diesen Methoden sind und wie sie funktionieren . Lassen Sie uns also für die Get's fortfahren, die erwartet wird, dass alle Blatttypen in der Datenbank zurückgegeben werden. Wir werden Code haben, der ähnlich aussieht. Wir werden var leave Typen haben, ist gleich einem warten. Also die Methode senden in unseren Medien gefunden, um zu widersprechen und alles, was genau senden wir? Wenn Sie sich die Überlastung ansehen, erwartet es ein Objekt vom Typ oder ein Objekt mit den Apartments werden Anfragen genannt, so dass es nicht weiß, welche Art von Anfrage es die Anfrage senden wird. Und die Erwartung ist, dass es etwas bekommen wird , das innerhalb von Blatttypen gespeichert werden kann. Wissen Sie, welche Anfragen wir senden würden? Während Sie zurück zu unseren Anwendungsprojekt-Funktionen springen, lassen Sie Typen und Abfragen. Wir werden hier sehen, dass wir die Get-Blatt-Typ-Listenanforderung haben, die voraussichtlich die Liste der Blatttyp-Details zurückgeben wird. Also in unserem Blatttypen-Controller würde ich sagen, dass ich ein neues Objekt der Typlistenanforderung sende. Und dann gehen Sie weiter und schließen Sie alle Missings mit Aussagen ein. Und dann werde ich den Methodenkopf in öffentliche asynchrone Task-Aktionsergebnisseändern den Methodenkopf in öffentliche asynchrone Task-Aktionsergebnisse und Details auflisten. Jetzt weiß es, dass es erwartet wird, dass ein Aktionsergebnis zurückgegeben wird, das diese Liste von Blatttypen hat. Diese return-Anweisung ist also nicht mehr gültig, da nein, ich werde Blatttypen zurückgeben und diese zwei Zeilen betrachten. Kontexte. Ich werde es nur mit dem alten Code vergleichen, oder es ist unsere alte Option hätte die Vielfalt der Typen gehabt. Es hätte tatsächlich den Anruf an die Arbeitseinheiten orchestriert, um die Aufzeichnungen zu holen, sie direkt zu bringen, Dollar. Und dann werden wir die Zuordnung durchführen, weil es die Domänenobjekte zurückgeben würde , wenn wir wollen, dass die VMs Kontexte sind, so dass es das Gleiche wie ein DTO ist. Und dann würden wir all diese Operation innerhalb der Aktion selbst durchführen, bevor wir die Ansicht zurückgeben. Im neuen Paradigma, was wir tun, ist, dass wir Medien nur wissen lassen, dass wir verlangen die Blatttypliste oder der Handler alle Operationen ausführen wird, ist das Kleben aller Mapping und das Abfragen und alles, und es gibt nur die Objekte zurück, über die wir wissen müssen. So würde die API nie mit den tatsächlichen Domänenobjekten interagieren , die aus der Datenbank kommen. Wir machen all diese Transformation, bevor sie den ganzen Weg zurück kommt. Lassen Sie uns also ein bisschen voran, wo ich den Code bereits geschrieben habe, aber wie üblichwerde ich ihn langsam durchgehen und jede Zeile erklären, werde ich ihn langsam durchgehen und jede Zeile erklären damit Sie voll und ganz schätzen können, was passiert. Sie können bei Bedarf pausieren und replizieren. Und wir werden sowieso zusammen durchgehen. Alles klar, also eine einzige schnelle Anpassung an das HTTP GET habe ich die Rückkehr begrenzt, okay, mit Blatttypen. In Ordnung? Und Sie bemerken noch einmal, Aufgabe, Aktion Ergebnisse Liste der fünf dB HL. Dies ist also sehr explizit, welchen Datentyp es null für das HTTP GET mit einer ID zurückgeben wird. Sobald ich ähnliche, sehr ähnliche Codeaufgabe gemacht habe , verlassen Aktionsergebnisse Diabetes. Natürlich muss es asynchron sein. Und wir sagen, var Blatttyp ist gleich und dann erwarten wir den Mediator Dotson mit der neuen Anfrage. Denken Sie also daran, dass die Anfrage behandelt wird. Mediator kümmert sich um diesen Teil. Wir müssen sicherstellen, dass wir die richtige Anfrage basierend auf dem, was wir wollen, verwenden. In dieser Situation ist die Anforderung, Blatttyp bt EverQuest zu erhalten , wo es den bestimmten Blatttyp mit allen Eindringlingen und anderen Fonds baumelt oder Anforderungen erhält , die da sein könnten. Für die Details. Wir müssen ihm auch den ID-Wert geben, den Sie erhalten werden, da es in unserem Handler stark auf die ID angewiesen ist, um zu wissen, welcher Datensatz abgerufen werden muss. Und dann kehren wir zurück, okay, mit dem Blatttyp. Jetzt in der Post haben wir noch ein paar Zeilen und es ist wirklich nur ich Ihnen zeigen, wie Sie es ohnehin ausbrechen können, aber es ist nicht unbedingt notwendig. Denn genau so, wie in 19 alles hätte gehen können und wir einfach das neue Objekt hier erstellen. Ich hätte das in diesem tun können, Medien zu senden. Stattdessen. Allerdings sagte ich var Befehl ist gleich einem neuen Leaf Typ Befehle erstellen. So ist die Post-Methode für die Erstellung konzipiert. Alles klar, also lassen Sie mich von Desire2Learn BAC-Diagramm starten, aber ich hatte von mir dort öffentliche asynchrone Task-Aktionsergebnisse. In Wirklichkeit müssen Sie nicht unbedingt sehen, was der Rückgabetyp ist. Es hilft bei der Dokumentation über das Ghetto zu swagger. Also würde ich es zurücklegen. Unabhängig von dieser Situation wäre die Antwort ein int. Also konnten wir int sehen, aber wie ich schon sagte, es ist nicht unbedingt notwendig. Also werde ich weitermachen, ohne dass es notwendig ist, jetzt und später werden wir sehen, warum es eine gute Idee gewesen wäre, es zu setzen. Also Aufgabe, Aktion, Ergebnis, Post, und wir tun von Körper, und dann verwenden wir den spezifischen Detailtyp für die Operation. Also denken Sie daran, dass wir besprochen haben, die Sie körnig bekommen Lassen Sie es generell. Nun, dies ist eine Situation, in der wir das Überschreiben verhindern würden , indem wir körnig werden, denn wenn sie sich drehen, wenn sie Informationen über Blatttypen senden, ist das, was wir durch diese Option akzeptieren, auf die -Eigenschaften innerhalb des von uns angegebenen Typs. Im Gegensatz zu Blatttyp Detail oder Blatttyp BTO, die mehr Details hat, sind mehr Felder, die sie erstellen. Blatttyp ist nur so konzipiert, dass die Datenpunkte akzeptiert werden, von denen wir wissen, dass wir unbedingt benötigen, damit unser Blatttyp erstellt wird, sodass alles andere ignoriert wird. Also, wenn wir diesen Befehl formulieren, sagten wir neu erstellen Blatt Befehl, D, Befehl. Muss dieses Detailobjekt verlassen. Also gehen wir in diesem Objekt. Und dann ist unsere Antwort relativ zu dem, was der Vermittler zurückgibt. In dieser Situation war unsere Antwort int, denn das hatten wir gesagt. Wenn Sie den Blatttyp erstellen, geben Sie einfach seine ID zurück. Das war also der Handler, den wir für diese Art von Anfragen entworfen haben. Wenn wir also alle k mit der Antwort zurückgeben, wäre das mit der Blatt-ID in Ordnung. Nun geht es zum Put, put wird für das Update verwendet, wieder ist in Task-Aktionsergebnissen. Und dann ist es standardmäßig diesen ID-Parameter haben und wir ändern vom Körperumfang in den Blatttyp DTO. Also haben wir, wir hatten von früher besprochen, dass der Blatttyp BTO, wir wurden nicht zu körnig damit. Ich habe ein Update-div-Tag, div TO unterscheidet sich von allem anderen. Das ist in Ordnung. Also in dieser Situation akzeptieren wir alle möglichen Ängste aktualisiert werden könnten. Und wir brauchen definitiv die ID innerhalb dieses Objekts, weshalb wir das erreichen. In der Tat, betäubt es diese ID ist optional. Also könnte ich eigentlich sagen, ich brauche keinen ID-Parameter. Wenn Sie also den Put aufrufen, müssen Sie keine ID eingeben. Und dann würde dieser Kommentar tatsächlich nur aktualisieren die Kommentare etablieren Einheitlichkeit. Also dann Aufgabe Aktion Ergebnis, setzen Sie eine Stunde suchen ist die Körperkontexte mit dem Blatttyp DTO. Denken Sie daran, dass unsere Validierung innerhalb unserer Handler stattfindet. Das ist also noch weniger. Weniger Dinge zerrissen Kugeln genau hier. Wenn wir darüber reden, hat die ID Comb-over, existiert die ID? All diese Dinge passieren innerhalb unseres Handlers, zwischen dem Handler und sind fließende Validierungen tatsächlich. Und wenn sich etwas auf dieser Seite anfühlt, dann wird diese ganze Operation scheitern. Jedenfalls. Wir schauen uns später an, wie wir mit Fehlern umgehen. Aber im Moment wollten wir uns nur darum kümmern, wie unsere Controller aussehen müssen. Also, wenn wir den Befehl zum Aktualisieren senden, haben wir die Seife nicht verkabelt, um etwas zurückzugeben, zumindest nichts Nützliches, oder? Wir haben gerade gesagt, Unit dot value unit repräsentiert eine Leere, also mussten wir etwas zurückgeben, aber wir haben gerade gesagt, okay, du wirst nur etwas Willkürliches zurückgeben , um zu sagen, dass es erfolgreich war. Und so ist die HTTP-Antwort, die einem Put entspricht, normalerweise kein Inhalt, was ein Werkzeug für ist, okay, also können wir einfach zurückgeben, dass wir nicht mit uns sprechen und die Antwort auf eine Variable. Löschen sieht ähnlich aus. Löschen nimmt einen ID-Parameter, Aufgabe, Aktion Ergebnisse, löschen int id. Und dann haben wir den Befehl, der nur die ID nimmt, und dann senden wir über den Befehl und Rückgabe oder alle Inhalte. Wenn Sie also möchten, dass alles nur zwei Zeilen sein soll, dann ist das so einfach, wie den Befehl zu übernehmen ihn in den gleichen Parameter zu setzen. Und alles kann zwei Zeilen sein. Ordnung, also zeige ich Ihnen nur den Unterschied, den großen Unterschied zwischen diesem Controller, der alles macht , was dieser Controller mit dem ganzen Code macht, in Ordnung, mit den Bearbeitungen wurden Validierungen hier durchgeführt. Für das Löschen tun wir eine Form der Validierung. Auch hier sind alle diese Dinge null, veraltet in andere Teile der Anwendung. Und unser Controller kann genau das tun, was er tun soll, nämlich eine Anfrage zu erhalten, einen Anruf zu machen, und dann geben Sie Ihre Daten zurück. Hier ist meine Herausforderung an dich. Gehen Sie vor und verdrahten Sie die anderen Controller für die anderen Typen, für die Features. So haben wir Blatttypen sind fertig. Gehen Sie weiter und versuchen Sie die Anfragen und lassen Sie Zuteilungen. Sie können natürlich benutzerdefinierte Optionen in Bezug auf das erstellen , was der Vorgang ausführen muss. Aber jetzt überlasse ich dich, das zu tun. Also werde ich im nächsten Video wiederkommen. Wir werden Notizen vergleichen. 21. Fertigstellung: Alles klar, das ist also eher ein Review-Video als ein Video zum Hören. habe nur ein paar Dinge, auf die ich in dieser Lektion konzentrieren möchte, die Sie wahrscheinlich versucht haben und wahrscheinlich Programme mit einem wenn nicht dann Lob an Sie hatten. Beginnen wir also mit dem Leave Allocations Controller, wirklich und wirklich, dies ist ein Steuerelement, das ziemlich identisch mit unserer Urlaubstypen Kontrolle sein wird , weil wir wirklich und wirklich nur crud Operationen hier machen. Wir bekommen die Liste, wo sie nach ID bekommen. Und natürlich, wenn du es nicht abgeschlossen hast, kannst du immer einfach anhalten und weitermachen und mich replizieren, wie du mich durchmachen siehst. Wir machen das Gleiche für die Post. So werden Sie feststellen, dass alles, was so ziemlich gesagt Urlaub Anfragen bemerkt, Urlaub Zuteilung. Sie könnten fast sagen, dass Sie einen neuen Controller erstellen könnten,alles aus dem Blatttypen-Controller kopiert, in denneuen Controller eingefügt und dann den Blatttyp mit der Leave-Zuweisung oder dem Typ mit der Wortzuteilung überwachthaben alles aus dem Blatttypen-Controller kopiert, in den neuen Controller eingefügt und dann den Blatttyp mit der Leave-Zuweisung oder dem Typ mit der Wortzuteilung überwacht . Ich gebe dir nur Tipps, wie du das ganz schnell und ziemlich effektiv hättest tun können, oder? Denn dieser ist ziemlich identisch mit den Blatttypen. Lassen Sie Anfragen, auf der anderen Seite, hat eine winzige Überraschung. Und das ist in der Form des Updates, richtig? Also wieder einmal, wenn ich langsam genug durchgehe, werde ich die Optionen von den Blatttypen in Urlaubsanfragen repliziert. So ist der größte Teil des Inhalts dieses Controllers identisch mit den anderen beiden, mit Ausnahme unserer PUT-Operation. Und wenn Sie bemerken und sehr genau hinsehen, würde ich sagen, setzen Operationen x2. Also jeder andere nur bei einer Operation eins, aktualisiere Endpunkte. Aber im Falle des Urlaubsantrags hatten wir Platz für zwei Arten von Aktualisierungen gemacht. Eines, wo es eine regelmäßige Updates ist. Und beachten Sie, dass wir diesmal den ID-Parameter im Put haben. Und das liegt daran, dass unser Befehl Urlaub Anfragen nach der ID und nach einem Detail fragt, das ist in Ordnung. Aber wieder, diese verschiedenen Geschmacksrichtungen sind relativ zu dem Stil, den Sie denken. Viel einfacheres Szenario. Also zeige ich Ihnen nur verschiedene Optionen. Ich sage nicht, dass es so sein muss. Sie haben die verschiedenen Möglichkeiten. Verwenden Sie diejenige, die für Ihre Situation und Ihr Projekt am besten geeignet ist. Jetzt haben wir in dieser Situation noch einmal den ID-Parameter, den wir mit dem Befehl möglich sind, und wir bauen einen Urlaub Anfrage DTO. Das andere Aktualisierungsszenario hätte jedoch nur einen Änderungsgenehmigungsstatus für unsere Urlaubsanfragen. In diesem Fall habe ich eine benutzerdefinierte Endpunktänderungsgenehmigung erstellt. Also, um zu diesem zu kommen, sagen Sie api Slash Requests Controller slush Genehmigung. Und ich brauche wirklich den Ausweis. Lassen Sie mich also voran gehen und fügen Sie es der Wurzel hinzu, damit es Genehmigung des Slashdot ID-Werts geändert wird. Da ich auch die Dokumentation entsprechend aktualisiert habe. Und ich muss diesen ID-Parameter setzen, Buck. So knifflig gesagt, lege es zurück und baue meine Anforderungsobjekte auf, Ordnung, oder eher mein Befehlsobjekt. Also zeige ich Ihnen nur all die Überlegungen, die gemacht werden müssen. Was am Ende des Tages, unsere Controller sind schlank und die Vorteile davon können Sie sehen, okay, also drei Zeilen, aber all das funktioniert oder in den früheren Videos, nur damit ich drei Zeilen hier setzen kann. Warum hat Titus nicht die ganze Logik hierher gebracht? Welche wieder, ich verstehe völlig, weil es funktionieren würde. Aber am Ende des Tages, Zitat, ist viel testbarer und ich muss den Controller nicht testen, um zu wissen, ob ich die Ergebnisse von diesem Endpunkt bekommen würde. Stattdessen kann ich den Handler testen, der diese Ergebnisse zurückgeben soll. Und wenn der Handler funktioniert , funktioniert der Endpunkt. Also, wissen Sie, es verlagert nur Ihren Fokus von kompakter zu sein, ein bisschen modularer zu sein und den Code und die Verantwortung über mehr Lust zu verbreiten, so dass Sie eine bessere Wertschätzung oder eine bittere Kontrolle darüber haben können , was jede Komponente nicht abgesichert ist, sie alle miteinander verbunden. 22. Seed: In Ordnung, also schließen wir uns mit unseren API-bezogenen Operationen ab. Und in dieser Lektion möchten wir einige Standarddaten in unsere Datenbank aufnehmen. Der nächste Schritt wäre natürlich, es zu testen, aber dann ist es immer gut, einige Beispieldaten zu haben, damit wir die Lesevorgänge ganz einfach und effektiv durchführen können. Um Daten in unserer Datenbank zu sehen, werden wir uns ansehen, wie wir das mit Entity Framework erreichen. Jetzt habe ich bereits einen gemacht und ich habe die anderen zwei von einem gemacht, also können wir sie zusammen machen. Aber lassen Sie uns beginnen, indem Sie zum Persistenzprojekt gehen, fügen Sie einen neuen Ordner namens Konfigurationen, und in dort einen anderen Ordner namens Entitäten. Und dann werden Sie eine Konfigurationsdatei pro Entität haben. So ziemlich viel diese Konfigurationsdatei ermöglicht es Ihnen, in irgendeinem Entity Framework bezogenen oder einer Datenbank zu setzen , Konfigurationen sind Standardwerte oder Regeln, die Sie in der bestimmten Tabelle in der Datenbankübergehen möchten der bestimmten Tabelle in der Datenbank wird dann der gesamte Code mit freundlicher Genehmigung von EF Core geschrieben. Schauen wir uns also die an, die ich bereits gemacht habe, und das ist für die Lease-Typ-Konfiguration. Also kannst du pausieren, das ausziehen und dann können wir die Stücke und Teile gemeinsam durchgehen. Also haben wir die Blatttypkonfiguration und dann erbt sie von der I-Entitätstypkonfiguration relativ zum Klassentyp, mit dem wir es zu tun haben, was der Blatttyp ist. Also, dann wird alles in dieser Codebasis im Grunde relativ zum Blatttyp sein. Also, wenn Sie das tun, werden Sie am Ende mit, es wird Sie bitten, im Parlament die Schnittstelle und dann würde das diese Methode Stub für Sie generieren. Also innerhalb dieses Methodenstubs werden wir public void konfigurieren. Und dann haben wir diese Int. Es ist alles, was tatsächlich für Sie generiert wird. Je mehr die Hauptteile davon, was Sie bauen oder schreiben werden, in diesem Builder-Abschnitt sein. Also würden wir sagen, dass Builder Daten hat. Und dann würden wir sagen, lassen Sie Typ oder erstellt ein neues Objekt. So ist dies eine Methode hat Tod ist eine Methode, die offene und enge Klammern hat. Und dann sehen wir einen neuen Blatttyp und dann füllen wir ein Objekt. Dies ist also das Domain-Objekt, das wir Ihre IDs eins sehen, Ihre Standardeinstellung ist es, in Datenbanken 10 zu gehen und Ihr Name ist Urlaub. Und dann, so viele Sie benötigen, können Sie tatsächlich jede Initialisierung eines Objekts oder Instanziierung eines Objekts innerhalb dieses gesamten Blocks durch Koma trennen . Nein, ich habe die anderen beiden noch nicht gemacht. Also werde ich sie irgendwie von Grund auf neu machen. Auch wenn nicht, haben Sie es wahrscheinlich schon mit dem Blatttyp getan. Nun, das ist in Ordnung. Also für die Leave Allocation Konfiguration, es erbt, aber es gibt keine Verwendung Anweisungen überhaupt. Deshalb siehst du die rote Linie. Also werde ich Steuerpunkt mit Microsoft Entity Framework Core, der Domänenreferenz, verwenden und dann die Schnittstelle implementieren , die diesen Methodenstub für mich generiert. Aber es gibt nichts für mich, um für die Zuweisung zu konfigurieren. Ich habe momentan keine Voraussetzung für die Zuteilung. In Ordnung. Also sehe ich keine Urlaubsanweisung. Ich ändere nichts über die Standardwerte für die Tabellenstruktur. Ich mache nichts anderes. Wie gesagt, kann diese Konfiguration für weit mehr als nur Seeding von Daten verwendet werden. Und wenn Sie ein besseres Verständnis davon wünschen, wozu es fähig ist, können Sie immer alle meinen Entity Framework Core-Kurs überprüfen. In Ordnung, also tun wir dasselbe für die Anfrage. Und wir werden es einfach noch einmal lassen, wir haben keine Urlaubsanfragen, die wir als Standard benötigen, aber wir haben einige Standard-Blatttypen, also das ist gut genug für jetzt. Zumindest können wir die API ausführen und GET-Anfragen für diese Tabelle ausführen und überprüfen, ob es funktioniert. Der nächste Schritt nach dem Schreiben dieses Codes wäre also, zu unserer Package Manager-Konsole zu gehen und wir müssen Migration für Seeding-Urlaubstypen hinzufügen. Sobald Sie das tun, gelangen wir zu einer Migrationsdatei, die uns mitteilt, dass sie diese Daten in die Datenbank für uns einfügen wird . Nächster Schritt, wie wir wissen, wäre es, Datenbank zu aktualisieren. Ok, großartig. Dieses Mal werden wir nicht direkt in die Datenbank gehen, um zu überprüfen, ob diese erstellt wurden. Was wir tun werden, ist unsere API zu testen. So sehen wir uns in der nächsten Lektion. 23. Swagger: Na gut, Leute, willkommen zurück. In dieser Lektion werden wir uns eine ansehen, unsere API testen und sie dokumentieren. Der Schlüsselpool, der beide Aufgaben umfasst, heißt Swagger. Swagger ist ein Open-Source-API-Dokumentationstool, das auf den offenen API-Standards basiert. Jetzt kommt es aus der Box für dotnet fünf API-Projekte. Also, wenn wir über springen, um zu starten und ein wenig zu scrollen, wessen hier sehen , dass wir die Swagger Ginn Library hinzufügen, die das Swagger doc mit einer offenen API-Info erstellt. Damit wir all diese Dinge ändern können. Ich kann nur sehen, HR verlassen Management API. Gib ihm einen Titel, gib dir eine Version. Sie können weitere Knoten hinzufügen, Kontaktbeschreibung, et cetera, et cetera. Es ist also ein sehr leistungsfähiges Werkzeug. Und wie ich schon sagte, es kommt aus der Schachtel und du hast das nicht da gemacht. Und ein weiterer Teil, den Sie sich ansehen würden ist hier unten in der Konfigurationsmethode, wo es heißt, wenn wir in der Entwicklung sind, dann verwenden Sie Swagger und API. Also, wenn Sie Swagger verwenden möchten, weil ich von Unternehmen kenne, die Fußball als ihre Dokumentation in der Produktion verwendet wurde, dann können Sie immer dieses Salz dieser if-Anweisung verwenden und es unabhängig von Ihrer Umgebung verwenden. Alles klar, damit du weitermachen kannst und diese Änderung vornehmen kannst. Nein, lassen Sie uns unsere Projekte leiten. Also werde ich nur F5 mit dem API-Projekt als Startup-Projekt treffen. Und das führt dazu, dass wir dieses schöne Dokument bekommen, das uns all unsere potenziellen Endpunkte zeigt und wie sie es genannt werden können. Beachten Sie, dass wir noch die Wettervorhersage haben. Wir können das später löschen, aber ich zeige Ihnen nur, dass wir nicht viel getan haben. Alles, was wir getan haben, war unsere Controller einzurichten, den Code zu schreiben, den wir wissen, dass wir schreiben müssen. Aber hier ist dieses schöne Dokument, das uns alles über unsere API zeigt. Wenn ich also auf eines klicke, dehnt es sich aus und es zeigt mir genau, was ich erwarten kann. Also dieser Endpunkt, der R ist, dieses Verhalten api Schrägstrich verlässt Allokationen, die das get ist, das alle Datensätze in der Leave Allocations Tabelle abruft. Es wird mir einen 200 Erfolgscode geben. Und das ist eine Vorschau des Objekts, das Geld bekommen würde. Also nochmals werde ich immer wieder auf Details zurückgehen und wie körnig Sie auf das bekommen, was Sie anzeigen möchten. Beachten Sie, dass in diesem speziellen Detail, wir haben die ID, wir haben die Anzahl der Tage, wir haben den Blatttyp mit seiner eigenen ID, den Namen, und der Standard ist, dann haben wir die Blatttyp-ID. Also könnten Sie sich das ansehen und sagen, das ist irgendwie überflüssig. Wenn ich bereits das Blatttypobjekt habe, möchte ich nicht schwer, die ID hier zu wiederholen. Und das wäre eine Angstaussage, richtig? Also, wissen Sie, wir sind nicht sehr granular mit der Urlaubs-Zuteilungsliste DTO. In dieser Situation verwenden wir nur das neue Allokationsdetail. So könnten wir senden zu viele Details sind zu viele Felder in dieser Antwort. können wir entsprechend anpassen. Schauen wir uns also Urlaubsanfragen an. Urlaubsanforderungen würden ID haben, der Blatttyp, das angeforderte und genehmigte Datum ist wahr. Warum hat es dies im Gegensatz zu derjenigen , die die Details bekommen, die viel mehr hat. Swagger betrachtet also unsere Rückgabetypen auf die bestimmte Steuerung eher als unsere Optionen. Und ich springe einfach zurück zum Controller, damit du sehen kannst, was ich meine. Denken Sie daran, dass ich sagen werde, dass es einen Vorteil gibt, den Rückgabetyp direkt darin zu setzen , dass ich tatsächlich resultiere, weil Saga dies tatsächlich verwendet, um zu sagen , okay, dies ist der Datentyp, der von dieser Auktion gegen diese zurückgegeben wird Datentyp für diese Aktion. Oder außerhalb davon wird es nur eine Annahme machen. Und der, der Rückgabetyp oder das Fema, das Sie möglicherweise sehen möglicherweise nicht repräsentativ für das, was tatsächlich zurückgegeben wird. Also, das ist einer der Vorteile, die entfernt sind sagte es gibt Vorteile, die Rückgabetyp hier setzen. Das ist einer von ihnen. Saga wird die Objekte ableiten, für die es das Schema in JSON anzeigen muss. Und das ist zumindest eine bessere und klarere Dokumentation für diejenigen, die mit Ihrer API interagieren werden. Okay, also lassen Sie uns einen Test machen. Lassen Sie uns zu api Schrägblatttypen springen. Da diese in die Datenbank gesät wurden, sollten wir, Ich erwarte mindestens zwei Datensätze, nachdem wir versucht haben, erzählt. Lassen Sie uns also diesen Endpunkt treffen, um es auszuprobieren und auszuführen. Was ich tun werde, ist einen Haltepunkt auf dem Controller und dem Handler zu setzen, den diese Operation treffen sollte. Also, wenn ich auf 2Ts ausführe, die Steuerung oder die Option eher, richtig? Denken Sie daran, dass es einen Datsun und ein Symbol vermitteln wird, mit dem Nein anfordert, ich drücke F5 und dann wird es den nächsten Haltepunkt treffen , der der Handler ist. Sie sehen also, wann vom Controller zu Handler und wo die ganze Magie wirklich innerhalb des Handlers und des Handlers geschieht, haben wir unser Repository unter Mapper. Beide initialisiert injiziert. Und dann führen wir im Handler die Abfrage aus, und dann geben wir die Detailversion von den Daten zurück. In Ordnung, also werde ich nur noch einmal F5 drücken und ihm erlauben, seine Operation abzuschließen. Und dann zeigt uns Swagger die Daten, die aus der Datenbank zurückkommen. Dort gehen wir, benannte Urlaub Standard ist ID1, et cetera, et cetera, et cetera, et cetera. Und auf die gleiche Weise, wenn ich zum Get gehe und ich versucht habe, zu transportieren, dann erlaubt es mir, die ID zu übergeben. Also werde ich in ID1 übergeben, ausführen, und dann bringt es mir die Wanderer-Karte mit der ID eins. Jetzt Fußball ermöglicht es uns, alle rohen Operationen zu tun, zumindest Test jemals Endpunkt, den wir angelegt haben. Also lassen Sie uns einen anderen ausprobieren, wo wir erschaffen werden. Beachten Sie also den Unterschied zwischen diesem Schema und dem Schema, das vom Detail über gets zurückgegeben wird, richtig. Dieser hat die ID, den Namen, der Standardwert ist, dass dieser nur Name auf Standardtagen hat. Das liegt daran, dass wir natürlich ein anderes Detail mit begrenztem Umfang verwenden. Also wegen des Namens werde ich hier nichts ändern. Ich werde eigentlich nur setzen, lassen Sie diese Standarddaten. Lassen Sie uns ausführen und dann schauen, was wir bekommen. Wir erhalten einen 500-Fehler. Alles klar, warum haben wir zu 500 Fehler bekommen? Lasst es uns genau lesen. Denk daran, was wir sagen werden. Wir haben nichts geändert. Der Name wäre string gewesen und der Standardwert, diese wären 0 gewesen. Wenn Sie sich genau erinnern, hatten wir eine Setup-Validierung, um zu sehen, dass der Standardwert niemals kleiner als eins sein sollte. Was wir hier sehen, ist ein 500-Fehler, weil die API nicht wusste, wie ich damit umgehen sollte, dass es eine Ausnahme vom Handler erhält. Und diese Ausnahme ist von Typvalidierungsausnahme. Sieht das vertraut aus? Richtig? Es lässt uns also nur wissen, dass es einen Fehler gab und diese Ausnahme ausgelöst wurde. Wir haben keine Ausnahmebehandlung integriert. Also alles, was geworfen wird, Swagger weiß nicht, was zu tun ist, zeigt uns nur , was die Anwendung Ihnen gegeben hat, was in Ordnung ist. Das ist es, was es im Moment tun soll. Und wir werden das verfeinern, während wir weitergehen. Aber der Punkt ist, dass das funktioniert. Also, wenn ich in etwas Sinnvolleres setzen und dieses Mal werde ich in Mutterschaftsurlaub mit Standardtagen von 90 wieder ausführen, dann bekommen wir wieder unseren Antwortcode von 33 wäre diese ID. Also kann ich zurück zu dem get testlet 3 ausgeführt wird. Da gehen wir. Mutterschaftsurlaub Standard ist 90, et cetera. Also zeige ich Ihnen nur, wie nützlich Swagger für Sie ist, um das Dokument für die API zu sehen und zu testen, ohne eine andere Anwendung installieren zu müssen. Nun, da gesagt, verwende ich Postman im Allgemeinen, um meine API-Tests durchzuführen. Aber für den Zweck dieses Kurses ist Swagger perfekt und hat seinen Zweck erfüllt. 24. Einteilung – Abschnitt Übersicht: Wir wissen, dass ein großes Portal für die Anwendung erstellt haben. Wir haben das meiste, was für die Stiftung da sein muss, ausgearbeitet. Wir haben die API eingerichtet und haben sie bis zu einem gewissen Grad getestet, wo wir sehen , dass sie tatsächlich mit der Datenbank kommuniziert und es funktioniert. Aber dann, wie wir mehr als einmal gesehen und diskutiert haben, ist das Testen ein sehr wichtiger Teil der Anwendungsentwicklung. Also brechen wir einfach aus, um die API Andrea zu testen, um dies manuell zu tun, wo wir es tatsächlich in das Test-Tool für die übermittelte API einfügen sollen. Und dann sehen wir, dass es vorgelegt wurde und alle. Und wir waren dann zuversichtlich, dass unser Code funktioniert. Aber dann stellen Sie sich eine viel größere Verpflichtung mit vielen weiteren Berührungspunkten vor. Wir haben nur einen Berührungspunkt getestet, wissen Sie nur, aber dann stellen Sie sich vor, 50, 60 Endpunkte zu testen. Sie haben nicht die Zeit oder Kapazität dafür. Es wäre eine Zeitverschwendung, wirklich zu versuchen, das alles durchzugehen. Deshalb werden wir uns mit Unit-Tests beschäftigen und wie es uns helfen kann, diese Prüfungen zu automatisieren , um sicherzustellen, dass unser Code das tut, wofür wir es entwickelt haben. Jetzt auf den Punkt gebracht, Unit-Tests ist Code, der Code testet. Ja, das ist richtig. Wir werden Code schreiben, um unseren Code zu testen. Dies ist einer der Gründe, warum Leute ein Proton scheuen, weil einige Leute es als Zeitverschwendung sehen , weil dann würden Sie Code zweimal schreiben. Und dass einige Leute sehen, ist absolut wichtig, weil sie Code nicht vertrauen, der nicht von einem Komponententest getestet wurde. Es gibt Personen, die beide Extreme abonnieren. Ich bin nicht notwendigerweise einer von ihnen. Ich glaube, dass Werkzeuge in dem Kontext verwendet werden für den sie entworfen wurden, und zu dem Zeitpunkt, zu dem Sie bereit sind. In dieser Situation ist es definitiv ein Werkzeug, das wir wollen, weil wir sicherstellen wollen, dass unsere Handler sich konsistent mit dem verhalten, für das wir sie entwickelt haben. Wir wollen auch schreiben, was wir die Integrationstests nennen, was nur die Unterbrechung zwischen den verschiedenen Schichten unserer Anwendung wird. Unit-Tests. einmal funktioniert es so wirklich großartig, um Zeit zu sparen. Auf lange Sicht. Es dauert eine Weile, um die Tests zu schreiben. Und unser Test ist nur so gut, wie er geschrieben wird. Aber dann gibt es Frameworks da draußen, die uns helfen können, sicherzustellen, dass wir Qualitätstests haben und dass wir volle Abdeckung für unser Angebot haben, eine andere Sache, die Unit-Tests uns hilft, ist Dokumentation. So konnte er Dokumentationen und Kommentare überall in Ihrem Code hinterlassen. Aber gut geschriebene Tests können Ihnen tatsächlich zeigen , was Code-Bits hier und da tun sollten. Einige Leute verwenden also Komponententests als eine Möglichkeit , ihren Code inoffiziell und inoffiziell zu dokumentieren. Jetzt im Allgemeinen gibt es drei Haupttypen von Tests, die wir normalerweise erfüllen. eine ist Komponententest, der andere ist Integrationstest, wiederum testet die Interaktion zwischen den Schichten. Und dann Funktionstests, die normalerweise wie UI sind , um zu testen, was die Benutzererfahrung sein sollte. Wenn wir zurückkommen, schauen wir uns an, unseren ersten Komponententest zu schreiben und wir werden unser Testprojekt innerhalb des Künstler-Ordners einrichten. Und wir werden unsere Anwendungslogik, auch bekannt als die Handler, testen , um sicherzustellen, dass sie das tun, was wir denken, sie tun. 25. Einheitstests für Anwendungscode: Hallo Jungs. Lassen Sie uns also beginnen, indem Sie ein neues Testprojekt für unsere Anwendungsebene erstellen. Also in unserem Testordner, in unserer Lösung, werden wir eine erstellen, die ich meine HR-Management-Anwendung genannt habe, die Komponententests. Von Anfang an wäre es ein neues Projekt und wir suchen nach einer X-Unit-Projektvorlage. Und dann wollen wir ihm natürlich den Namen geben, und es muss um fünf Uhr gemacht werden. Also, sobald du das alles getan hast, kannst du zu NuGet springen und wir wollen MOQ installieren oder verspotten und klug. Also wird Mach uns helfen, Spott unserer Beharrlichkeit zu erschaffen. Es gibt Repositories und andere Objekte, die benötigt werden, um zu simulieren, was unsere Anwendung oder unsere Handler wirklich tun. Und sollte uns nicht helfen zu behaupten, dass dies das ist, was wir von dieser Art von Operation erwarten. Jetzt habe ich bereits eine Ordnerstruktur für Sie eingerichtet. Und ich denke, sie sind mehr an Sachen interessiert stapelbar sind, als dass du dich hinsetzst und mich tippst. Also habe ich vorangegangen und einige der Vermögenswerte vorbereitet, aber wie üblich werden wir sie langsam und zusammen durchlaufen, damit wir vollständig verstehen können , was bei jedem Schritt passiert. In diesem Projekt haben wir zwei Ordner mindestens für Nein, Also sind wir 14 Blatttypen. Einer für Mach-Rauche wird die Mock-Repositories schütteln. Jetzt haben Sie zwei Möglichkeiten. Natürlich können Sie eine Datei pro Mock-Repository haben, eine Mock-Repository-Datei haben und mehrere Instanzen darin haben. Das liegt an dir, jetzt verwende ich nur eine Datei und was wird nur einen Test ausführen. Wenn Sie also 50 Dinge haben, sind Funktionen, die Sie ausführen müssen. Unsere Handler sind Funktionen, gegen die Sie Komponententests ausführen müssen Dann wäre es wahrscheinlich besser, sie einfach in bestimmte Dateien pro Datensatz aufzuteilen , die Sie vorher verspotten möchten. Also lasst uns zuerst in die Mocks gehen. Also habe ich bereits eine Methode in dieser Datei in dieser Datei durchgemacht und eingerichtet. Also lasst uns das gemeinsam besprechen. Also habe ich dies zu einer öffentlichen statischen Klasse gemacht und ich rufe ein Mock-Repositories auf. Wieder einmal hätte ich leicht sehr spezifisch sein können und etwas wie Mach leave type repository sagen können. In der Tat werde ich meine eigene Unterwerfung nehmen und es einfach so machen. Also haben wir diese Datei, insbesondere für Mach verlassen Typ Repository, die Toronto Newcomb Buck gut, Mock Lever Location Repository, et cetera, et cetera. Mach leave type repository ist also eine statische Klasse und es hat eine statische Methode darin. Diese Methode ist wieder öffentlich statisch gestaltet. Und beachten Sie, dass es mit diesem Keyword Mock verziert ist , der uns mit freundlicher Genehmigung der Mock Library kommt, richtig? Und es wird uns erlauben, jede Art von Repository hier zu verspotten. Also möchte ich ein Mock-Leaf-Typ-Repository, das das Elif-Typ-Repository verspottet. Und dann rufe ich die Methode get leaf type repository auf. Jetzt wird diese Methode eine Liste von Blatttyp-Objekten haben. diesen können Sie völlig fiktiv sein. Es gibt nichts zu sagen, dass sie so aussehen müssen, wie es in der Datenbank wäre. Es gibt keine, es gibt nichts Besonderes daran ist nur eine Liste von Objekten, die ähnlich sind, wie wir von der Datenbank erwarten würden, wenn es um die Domäne-Urlaubstyp-Objekte geht , richtig? Also muss ich nur, du könntest zehn haben, du könntest 15 oder 20 mehr haben , basierend auf deinem Szenario und was du testen musst. Vielleicht brauchen Sie mehr, vielleicht brauchen Sie weniger als das, aber das liegt an Ihnen. Also gehe ich nur mit zwei fort. In Ordnung, dann initialisieren wir unser Spot-Repo. Also werde ich sagen, Umweltgruppe war gleich dem neuen Mock. Und der Typ ist wieder, ich werde Typ-Repository verlassen. Also, bis wir all dies tun, werden Sie unsere rote Linie neben dieser Methode sehen, weil es sagt, dass nicht alle Pfade einen Wert zurückgeben, weil wir den Mock zurückgeben müssen. Bevor wir also den Mach zurückgeben können, müssen wir ihn aufstellen. So sind Beispieldaten vorhanden. Das neue Objekt des Mott-Repositorys ist vorhanden. Also, jetzt müssen wir buchstäblich Mock Repo Dot Setup aufrufen. Wir verwenden einen Lambda-Ausdruck, wo es uns Zugriff auf die Methoden gibt , die innerhalb des ursprünglichen Repo gewesen wären. Wenn wir also die get-Methode testen oder zumindest einrichten möchten, erhalten sie alle methodischen Mittel, dass, wenn ein Test dieses Mock-Repo aufruft und wir einen Test gegen Code aufrufen möchten, der dies verwendet, alles bekommt. Es wird im Mock Repo passieren. Und dann sitzen wir auf, sie bekommen alle Methoden. Das ist also ein Block oder ein Setup. Unser Lambda-Ausdruck R-dot Ghettos L, Das ist alles in einem Block, und dann gibt die Liste der Blatttypen. Also jeder Code, der die Spott geboren wird, wird das Get off für dieses Repository aufrufen, den Spott. Was im Test aufgerufen wird, gibt diese Liste der Blatttypen zurück. Das ist es, worum es geht. Ordnung, also können Sie, InOrdnung, also können Sie, haben Sie die volle Kontrolle über Ihre Beispieldaten. dazu, T aufzustehen und mit diesem Misha mit den Beispieldaten zu beginnen, aber es ist alles für einen guten Zweck. Nein, die nächste wäre, einzurichten, was passiert, wenn wir die Add-Methode aufrufen. Okay, so Spott blaue Punkte Setup, wieder dieser Lambda-Block, wo wir die Add-Methode aufrufen. alles ist also ein Block. Und ich werde einfach erklären, was hier passiert. Wir sehen unsere dot-dot-dot normal, aber die add Methode benötigt standardmäßig ein Objekt vom Typ leaf type entity. In Ordnung, also lasse ich es einfach an. In Ordnung, also müssen wir eine Blatttyp-Entität in die Add-Methode übergeben. Was wir hier tun, ist, dass wir eine Behauptung machen , dass Sie diese Methode nur aufrufen können, wenn ein Objekt vom Typ, Blatttyp übergeben wird. einmal kann dies ein Dummy-Objekt sein. Es muss nur vom Typ, Blatttyp sein. Es muss nicht all diese Daten und etwas Besonderes haben. In Ordnung, wenn es also nicht vom Blatttyp ist, kann diese Methode aufgerufen werden. Und es kehrt zurück ist ein Objekt sinken. Was wir also tun werden, ist einen Delegaten zu tun, um zu sagen, nachdem wir das Objekt vom Typ leaf erhalten haben, und dann haben wir unseren Lambda-Ausdruck oder -Methode blockieren sie, verschieben Sie es einfach in den nächsten Satz, damit Sie es klarer sehen können. Dann sagen wir verlassen Typen, das ist unsere Liste Punkt hinzufügen. Also für die Lebensdauer des Tests, wenn jemand die Add-Methode aufruft und diese Blatttyp-Objekte übergibt, werden wir es nur zur Liste der Blatttypen und im Gegenzug zu diesem bestimmten Blatttyp hinzufügen . Also, das ist nur halten das Setup funktioniert und dann basierend auf dem Szenario oder testen Fourier-Setup kann variieren. So bemerken Sie, dass sie alle Setup sieht ziemlich anders aus der, die, sorry, sie werden Setup hinzufügen. Und dann löschen Sie eine mil anders und dann das Update ein mil anders. Also gerade jetzt sitzen wir einfach oder fürs Hinzufügen und bekommen alle. Und dann gehen wir weiter und geben das Spot-Repo zurück. Nach der Rückkehr würde dieser Pfeil weggehen, und das ist, was diese Methode vier ist. Also, nachdem Sie all das repliziert haben, können Sie einfach, ich bin sicher, dass Sie pausieren und schreiben es nicht, aber ich hoffe, Sie haben ein besseres Verständnis davon, wie der MAC uns hilft, Daten zu simulieren, ohne die Datenbank wirklich zu berühren. Jetzt springen wir zu unserem ersten Komponententest. Jetzt wird dieser Abfragen sein, Ordner. Ich habe Tabs und Befehle und Abfragen hinterlassen. In Ordnung, also werden die Handler, die Abfragen durchführen innerhalb von Abfragen getestet und Befehle in den Befehlen angezeigt. Also der erste, den wir haben, ist der get leaf type list Request Handler Test. Es ist fast voll, aber zumindest kann niemand einen Fehler machen, was getestet wird. Anstelle dieser Datei können Sie natürlich mehrere Tests haben, aber dann wollen wir in diesem Szenario nur haben, wir brauchen nur einen Test wirklich für den Gastlisten-Handler oder nein, lassen Sie mich einfach durch das führen, was geschieht innerhalb dieser ersten 10 Zeilen. Nun, wir müssen wissen, dass wir Auto-Mapper brauchen und wir wissen, dass wir ein Repository brauchen, um mit dem Handler zu interagieren, oder? Und ich werde einfach springen, habe ich nicht die Tests geschrieben, die wir das zusammen machen werden, aber ich wollte nur zeigen, was passiert, wenn wir versuchen, unseren Handler zu instanziieren, wir bekommen einen Fehler. Warum? Da ein 100 einen Parameter vom Typ I elif Typ Repository und einen anderen Parameter vom Typ high mapper erwartet. Das ist ein Komponententest, der sie nicht einfach injizieren kann. Das sind 12. Wir würden es nicht reinspritzen wollen. Ich meine, das könnten wir wahrscheinlich, aber wir würden es nicht wollen, weil wir es mit Mocks zu tun haben, oder? möchte nicht in das echte elif-Typ-Repository injizieren , da das mit der Datenbank sprechen wird. Wir wollen nicht, dass unser Komponententest tatsächlich mit der Datenbank spricht. Wir wollten es nur simulieren. Also, was ich getan habe, ist initialisieren oder deklarieren oder andere zwei private Felder, eines für den Mapper und eines für unsere Spot-Repos, richtig? Also private schreibgeschützte Mach vom Typ II elif Typ Repository-Leute. Dann haben wir unseren Konstruktor. Also im Konstruktor, sobald dieser Test auf on aufgerufen wird, um unser lokales Spott Boot zu initialisieren, um gleich zu sein, um die Mock Leaf Typ Repository Klasse dot get leaf type Repository-Methode aufzurufen . Okay, damit nein, wir werden all das Setup machen und die Spottleute für den Einsatz in diesem Test zurückgeben. Jetzt für den Mapper, wir wieder, wir injizieren nichts. Also brauchen wir diesen Mapper, um alle tatsächlichen Mapping-Konfigurationen zu kennen , die in unserer Anwendung existieren. Also, was wir tun werden, ist das Mapper-Konfigurationsobjekt zu initialisieren. Seien Sie eine neue Markt-Mapper-Konfiguration. Und dann haben wir hier einen Lambda-Ausdruck mit unserem Objektblock, in dem wir Lambda Tolkien Punkt Profil für das Mapping-Profil hinzufügen sehen. Nachdem wir das Mapping-Profil und die Konfiguration eingerichtet haben, dann können wir wissen, dass einfach passieren, dass nicht. Also sagen wir, Mapper ist gleich Mapper. Config dot erstellt einen neuen Mapper, der diese Konfiguration verwendet. Also in allem ist unser Mapper hier im Künstler wirklich Es ist repräsentativ für den echten Mapper in der Anwendung. Also alle Methode unten wissen, hat eine öffentliche asynchrone Aufgabe erhalten verlassen Typliste. Also sind wir spezifisch, wissen, worauf wir genau testen? Wo Testen für die Methode, die die Blatttypen Liste abruft. Es ist mit diesem Faktenattribut verziert weil dies die Verpflichtung sagt, dass dies ein Komponententest ist. Das ist also ein Sprichwort, Hey, was auch immer hier passiert, muss gekämpft werden. Was auch immer Behauptungen hier bestanden werden müssen. Wenn sie nicht bestehen, ist dieser Test fehlgeschlagen. Nun lassen Sie uns tatsächlich in den Hunderten interagieren, so sind die Tests eher. Also sagen wir, var Handler ist gleich neu. Und dann instanziiere ich die 100, die ich den Test in dieser Methode gewünscht habe. Beachten Sie die roten Linien, weil es unsere Mock-Ripple oder eine Instanz eines elif-Typ-Repositorys erfordert . Also Spott Bull gibt uns ein Mock-Objekt, aber dann kann ich das tatsächliche Zitat unquote tatsächliche Objekt durch MLK Repo-Dot-Objekt erhalten. Nächster Halt, wir brauchen unseren Mapper. Okay, das sieht gut aus. Als nächstes wollen wir den Methodenaufruf tatsächlich testen. Also werde ich sagen, var Ergebnis ist gleich Handler dot handle. Alles klar, denn es gab Handler hat diese Methode namens handle und es erfordert ein neues Objekt oder es erfordert die Anforderungsobjekte. Also müssen wir ein neues Objekt des Ziels übergeben. Und ich werde das alles abnehmen und den Einsatz, die using-Anweisung verwenden. Da gehen wir. Damit wir nicht einen ganzen Text haben. Und dann danach braucht es auch nach der Annullierung. Tolkien, okay, also gegen Leine auf oder ich kann einfach in Stornierung Tolkien gepunktete Linie passieren. Ordnung, also dieser Bus, der da drin ist, aber dieses verschüttet rot und enthält alle fehlenden Referenzen. Da gehen wir. Also sehen wir nur das nennen. Wir geben keine Stornierungs-Token ein. Wir sind bossy und dieses neue Objekt, also müssen wir es nicht unbedingt sein. Also ist Mach wirklich nur dafür, die Spitze. Ordnung? Nein, wir können ein Ergebnis sehen. Und wenn Sie sich den Datentyp für Ergebnisse ansehen, oh, nun, wir müssen darauf warten. Entschuldigung. Wenn Sie sich den Datentyp für das Ergebnis ansehen, ist es tatsächlich Liste. Ja, da gehen wir. Der Datentyp für das Ergebnis ist also eine Liste des Blatttyps DTO. Also ist es einfach genug, um Türen Aussagen und sagen, Okay , gut, wenn die Kegel größer als eins ist, dann das oder so, nur um sicherzustellen, dass wir mehr als eine zurück, weil die Liste, also sollten wir wieder eine bekommen oder mehr. Aber am Ende des Tages können wir uns hinsetzen und an alle möglichen Szenarien denken und so weiter, dass wir überwältigt werden können. Deshalb haben wir den Rahmen führen sollte, um uns zu helfen. So kann ich Ergebnis dotplot sagen. Denken Sie daran, dass dies wirklich nur aufgelistete Dinge ist. Es ist nur eine Liste. Aber ging zum Typ sollte vom Typ sein , weil ich sicherstellen möchte, dass ich den richtigen Datentyp bekomme. Der Datentyp, den wir von unserem Handler für diesen speziellen Aufruf erwarten, wäre die Liste. Der Datentyp wäre eine Liste mit Blatttypdetails. Also werde ich jetzt Mandarin-Linien sehen und kennen. Lasst uns einfach diesen Teil durcharbeiten. Lassen Sie den Typ DTO. Ordnung? Nein, wenn ich das mache, gibt es eine reine Larry-Linie, weil sie vom Typ sein sollte, das hast du wahrscheinlich noch nie gesehen. Also, wenn ich WC mit kurz steuern, so dass ist, wo es sollte nicht ins Spiel kommt. Es hilft uns mit unseren Behauptungen, mit unseren Annahmen darüber, was passieren sollte. Ich werde voran gehen und die using-Anweisung für die DTU auch einfügen. Aber dann ist das der Punkt, den ich sicherlich werde. Also habe ich den Handler aufgerufen, ich führe einen Befehl aus oder führe eine Operation aus, habe ein Ergebnis erhalten. Und dann sehe ich, dass die Ergebnisse vom Typ, Blatttyp DTO sein sollten. Das ist also eine Behauptung dort. Und mal sehen, was haben wir Kinsey Ergebnis Punkt und der Start, beginnen Sie mit der Eingabe sollte ich alle möglichen sehen, richtig, alle diese. Unsere möglichen Dinge, die wir behaupten können oder es sollte nein sein, sollte in Reichweite sein, sollte in Ordnung sein. All diese Dinge sind Dinge, auf die Sie überprüfen können. So kann ich sehen sollte und sagen T2 weil ich für meine Testdaten weiß, dass das Shooting, oh sorry. Mehr C-Punktanzahl sollte sein. Da gehen wir. In Ordnung. Dies sollte also nur auf einer anderen Eigenschaft oder dem Objekt selbst versteckt werden. Und es ermöglicht es, die Behauptung für jedes Szenario zu erhalten, das erwartet. Also wissen Sie, dass wir das gesagt haben. Lassen Sie mich an das Projekt schreiben und sagen, Tests ausführen. Und das wird uns autistische Spore geben, die dann den Test durchführen und uns zeigen, was Vergangenheit ist. In Ordnung. Also, dass eins nach vier, wenn es zwei sein sollte. Nein, ich weiß, ich habe zwei gesetzt, aber sagen wir, ich sagte fünf und führe diesen Test erneut aus. Nirgends bekommen Fehler. Und wenn ich erweitern, dass nur ein bisschen, wer sieht, sollte Behauptung verlassen sollte fünf, Boot war zwei. Das bedeutet also, wenn sich etwas in meinem Code geändert hat und es massenhaft sucht, weiß ich, dass mein Code zu allen Zeiten zurückkehren soll, aber dann etwas Gene. Sagen wir mal, ich habe den Test nicht geändert. Ich weiß, dass es auch ist. Richtig. Aber dann, wenn ich in einen Mutterartikel. Ordnung, also hier kommt das Ändern des Codes ins Spiel. Und ja, das ist alles statistisch, aber noch einmal sprechen wir nur über Sonare. Also Mutterschaft oder wenn ich den Code ändere, der zu einem zurückkehren sollte, sollte immer zu 18 zurückkehren, etwas einzuführen. Nein, es gibt drei zurück. Meine Komponententests nur durch Ausführen werden mir sagen, wenn sich etwas ändert. Lassen Sie mich einfach den Komponententest wiederholen. Und meine Behauptung ist immer noch zwei, aber dann drei Spiel-Dollar. Also gleich neben dem Fledermaus weiß ich, dass es einen Fehler im Handler gibt , mit dem ich es zu tun habe oder weil etwas schief gelaufen ist. Das ist also irgendwie das, was Komponententests auf den Tisch bringt. Nun lassen Sie uns unsere erstellt verlassen Typ Befehl Handler Test sind. Und so können Sie anstelle des Befehls-Ordners voran gehen und diese Datei einrichten. Und es wird ziemlich ähnlich aussehen wie der Get-Blatt-Typ. Wir haben das gleiche Mach-Repository verwendet. Wir haben die gleiche Initialisierungsprozedur verwendet wird. Und dann haben wir Test, das ist die aktuelle, dass natürlich mit der Tatsache und der Aufgabe, wo wir sehen schaffen Blatttyp. Also rufen wir den Handler auf, der die Create Leaf Type Command Handler ist, singen Es sind die Objekte wie nötig, und dann haben wir die Ergebnisse. Also unser Ergebnis wird von unserem Essen Handler Dot Handle schaffen Blatt Typ Befehl kommen . Und denken Sie daran, dass unser Blatttypbefehl zum Erstellen eine lebenslange BTO erfordert. Das bedeutet, dass wir hier ein Objekt benötigen, um in null zu übergeben, Sie haben zwei Optionen. Sie können die neuen Objektkriterien in diesem Handler erstellen und verwenden. Wenn Sie jedoch mehrere Tests haben, können Sie einfach ein Objekt vom Blatttyp D2 erstellen und dieses für mehrere Tests verwenden. Also werde ich den zweiten Ansatz verwenden, bei dem ich meine private schreibgeschützte DTO belassen und dann werde ich es im Konstruktor initialisieren. Einige Leute nach einer Weile haben sie so viele Assets initialisiert, dass dieser Konstruktor zu groß wird. Was sie tun würden, ist vielleicht ETL auf eine andere Methode zu farm, die sie wie initiale, anfängliche Einrichtung oder Initialisierung aufrufen . Und dann machen sie all diese Initialisierungen da drin. Und manchmal werden Assets tatsächlich über Tests verteilt. Was sie also tun würden, ist, alles in eine völlig andere Datei zu erstellen, wie ein krass Punkt Setup, rechts Typ Test Setup verlassen. Das wird nur weitergehen und alle benötigten Objekte zurückgeben. Es gibt also keine beiden Möglichkeiten, aber das sind keine großen Tests. Also wollen wir das Konzept nur unter die Finger bringen , bevor wir darüber nachdenken, es zu sehr zu behindern, oder? Also haben wir all das Setup und wir haben unser Blatttyp-Detail, das übergeben werden muss. Also, oh tut mir leid, ich bekomme diesen Bereich, weil es der erstellen Blatttyp BTO ist, entschuldigen Sie sich. Also lassen Sie mich einfach diesen Datentyp reparieren und dann sollten wir gut gehen. Und da gehen wir. In Ordnung, und natürlich ist kein Ausweis darin. In Ordnung, also lasst uns sehen, was wir in diesem hier behaupten müssen. Zum einen, wenn wir ein neues Blatttyp-Tool, unser Mock-Repo, hinzufügen , dann sollte der Kegel zunehmen, oder? Genau die gleiche Art und Weise, als wir in unsere Datenbank hinzugefügt, wenn es zehn, wissen, es gibt 11. Denken Sie also daran, in unserem Mock Repo, wir hatten die Add-Methode eingerichtet, die einen beliebigen Typ von leave annehmen sollte und es der Liste hinzufügen sollte. Was bedeutet, dass, wenn ich die Liste anrufen oder alle von bekommen. Das Repo direkt nach einer Add-Operation, dann sollte es eine weitere Datei geben, dann gibt es null, einen weiteren Datensatz und es gibt zu der Zeit, richtig? Also gibt es drei null. Lassen Sie mich zuerst die Aktualisierung dieser Behauptung auf drei sagen. Und dann werde ich den Spott Repo anrufen. Also werde ich sagen, var leave Typen. Ich ging, um das Repo für Khomeini abzufragen. Also natürlich machen wir die gedachten Spo-Repo-Dot-Objekte, und dann können wir einfach alles bekommen. Also, wenn wir uns noch anrufen, wissen wir alles genau, was wir bekommen. Wir kriegen die Liste. Dann kann ich meine Ergebnisse denken, sollte es sein. Und wir wissen, dass wir die ID-Werte zurückgeben. Nach dem Aufruf des Create Tumblr für den Blatttyp sollte es vom Typ int sein, richtig, also ist das unsere erste Behauptung. Und dann werde ich auch sagen, dass Blatttypen Punkt, Punkt sein sollte. Und ich werde sicherstellen, dass es vier sagt, weil wir wissen, dass wir mit drei Null nach dem Anruf beginnen, sollte es für sein. Nun, bevor ich den Test durchführe, werde ich ihn einfach umbenennen, um etwas nützlicher auszusehen, oder? Erstellen Sie also Blatttyp-Tests. Aber was Sie dann mehrere Tests haben können, sind Menschen Blatttypen von Tests für das erstellen , was passiert, wenn es ungültig ist was passiert, wenn es gültige Tests für das ist, was passiert wenn Werte ein bestimmter Wert sind und Sie einen Geschäftsregel in ihrer Arbeit sollte sich auf diese Weise oder auf diese Weise verhalten , basierend auf der Art, was immer dort übergeben wird. So viele Szenarien, ich kann mich nicht hinsetzen und an jedes Szenario denken, aber ich gebe Ihnen nur den Rahmen, auf dem Sie Ihre Tests formulieren können. Also dieser Test ist, ist eine Behauptung, dass, wenn ein gültiger Blatttyp hinzugefügt wird, Dies ist das erwartete Verhalten. Also werde ich zurück zu unserem Handler springen tut, damit wir verstehen können, wieder den Zweck der Unit-Tests. Also zu testen, dass wir Buck benötigen, das ist einfach. Okay, ja, wir haben das MLK-Repo, wo nur Abfrage im Mock-Repo, der Handler soll sowieso eine Sache tun , die zurückgegeben wird, was im Repo ist, das ist in Ordnung. Aber dann in einer Situation, in der wir mehrere Ergebnisse in unserem Handler haben, wollen wir für jedes Ergebnis testen. Und dann können Sie es wahrscheinlich in den guten Test und den Bluttest zerlegen. Das liegt in Ihrem Ermessen, was Sie sicherstellen möchten, dass Sie über die potenziellen Ergebnisse verfügen. Denn wenn sich Geschäftsregeln ändern, wenn ein Entwickler hereinkommt, die if-Anweisung ändert, selbst wenn versehentlich, dann ändert sich eines der Ergebnisse und Sie möchten das so früh wie möglich abfangen. Also in unserem create leaf type Befehl, und denken Sie daran, dass wir hier einige Validierung durchführen, richtig? Also validieren wir den Blatttyp und werfen dann eine Ausnahme. Wenn es ungültig ist. Dann, wenn es gültig ist, gehen wir durch und wir geben die ID zurück. Also haben wir das schon getestet. Und wir sehen, wo das Hinzufügen der Sache tatsächlich mehr Rekorde bringt. Wenn wir zu Git Repo wären. Und das ist gut, aber wir müssen testen, was passiert, wenn schlechte Daten eingehen, stellen Sie sicher, dass sie korrekt gemäß unseren Geschäftsregeln behandelt werden. In Ordnung, also haben wir die Behauptungen gemacht. Wir behaupten, dass, wenn ich ein ungültiges Anforderungsobjekt mit einem ungültigen Blatttyp D bekomme ein ungültiges Anforderungsobjekt mit einem , Typ Anfrage DTO leaf ab initio verlassen, sorry, dass wir eine Ausnahme erhalten sollten oder wir bestimmte Dinge in ihrer Antwort bekommen sollten basierend darauf, wie Sie Ihren Code geschrieben haben. Das sollte passieren. Dieses Szenario ist MIT. Beachten Sie auch, dass CO, da wir in Einheit zwei sind, sehen, wie viele Verweise darauf, wie viele Tests für Ihren Code übergeben werden. So können Sie immer wissen, dass Sie im Grün sind oder Sie im Bernstein oder Grün sind oder Sie nicht im Grün sind, wenn es um die Tests geht. Also werde ich zurück zu unserem Test springen und ich habe einen weiteren Test für den ungültigen Blatttyp hinzugefügt. Okay, also haben wir den gleichen Code, in dem wir unseren Handler eingerichtet haben, richtig? Und dann wiederholt sich das noch einmal. Was einige Leute tun und was ich manchmal dazu neige, ist, diesen wiederholenden Code in ein privates Feld zu verschieben und im Konstruktor initialisiert zu werden. die Testkohledatei wächst, möchten Sie möglicherweise einige Teile davon anbauen, da wir dies nicht jedes Mal tun müssen, wenn Sie einen Test haben, müssen Sie initialisieren. Es ist also der gleiche Befehlshandler, den wir mit einem C-Mock-Repo und demselben Mapper verwenden werden . Also, nachdem ich auf dem Spot-Repo saß, bin ich der Mapper. Wir können einfach unseren Handler initialisieren, um diese Objekte zu erhalten. Dann sieht Künstler aus, nun, wir haben eine Linie weniger, um die wir uns Sorgen machen müssen, richtig? Also sagen wir einfach Unterstrich-Handler, Datetime-Rechnung, und gehen Sie voran. Also in diesem neuen Test werde ich meinen Blatttyp DTO nehmen und ich werde es ungültig machen. Denken Sie also daran, dass wir es initialisiert haben, um 15 Tage und diesen Namen zu haben. Aber dann wissen wir, dass, während wir darauf testen, wenn ich den Typ jemals damit überlassen würde, dann sollte es ungültig sein, richtig? Also machen wir es einfach ungültig. Und dann werde ich etwas anders machen. Nein, also testen wir auf eine Ausnahme. Ordnung, also werde ich sagen, Validierungsausnahme e x ist gleich 0, sollte es. So erhalten wir eine statische Klassenaufrufe sollten keine Senken-Validierungsausnahme auslösen. Und dann öffnen wir Klammern und Sie können öffnen und schließen. Und dann sagen Sie stattdessen asynchrone Delegaten Lambda-Pfeil. Jetzt gehen wir zu unseren Gewichten, der Handleraufruf, der in den Details vorbeigeht. Also es buchstäblich nur diese Neun, die wir darin setzen, sollte asynchrone Methode werfen. Dann können wir am Ende testen, um alle Blatttypen zu erhalten. Also gehen wir in die Blätter, denken Sie daran, dass wir das hier oben getan haben und wir sagten, dass es vorher wissen sollte. Also nach einer ungültigen Operation sollte es immer noch drei sein, richtig? Also, das ist, was wir unterscheiden Bereich. Wir stellen sicher, dass dies nicht in unser Mock-Repo-Dataset geschafft hat. Und dann kann ich auch sicherstellen, dass die Ausnahme nicht null sein sollte. Das ist also meine Art, um sicherzustellen, dass eine Ausnahme tatsächlich Thron war. Jetzt, da ich das alles getan habe, und wenn du ein paar Tage testest, bekommst du den Fötus. Wenn Sie also entweder gefüllt werden, weil Sie den Test verfeinern müssen , um sicherzustellen, dass Sie das Richtige testen oder Sie sind, haben Sie den Test gelesen und Sie interagieren nur und es schlägt fehl weil Ihr Code nicht den Test. In Ordnung, also sind zwei Teile aufpassen. Jetzt, da ich das alles getan habe, gehen wir weiter und führen eine neue Reihe von Tests durch. Und ich habe überall alles grüne Lichter bekommen. Der ungültige Blatttyp fügte also alle übergebenen Assertionen hinzu, was bedeutet, dass er sie dem Repo nicht korrekt hinzugefügt hat und die Ausnahme ausgelöst weil die Ausnahme nicht null war und die gültige erfolgreich hinzugefügt wurde. Und dann haben wir natürlich die Dinge in der Welligkeit richtig abgerufen. In Ordnung, damit wir den Test Explorer schließen können, und es waren die grünen Zecken hier. Und wenn wir dann in unserem Code zurückblicken, ist das, was sah Feld kein Sehen vorbei. In Ordnung, Sie können also sehen, wie viele Tests in diesem Befehl auf diese bestimmte Handler-Methode verweisen . Das ist also ein schneller und schmutziger Überblick über Komponententests und wie es uns bei unserer Codeabdeckung helfen kann. Und herzlich, natürlich, die rote obwohl Tests für Ihre anderen Handler und erkunden wie die verschiedenen Szenarien getestet werden können. 26. ASP.NET MVC Projekt: In Ordnung, also richten wir unser Projekt in diesem neuen Modul ein. Und was wir für unser UI-Projekt verwenden werden, ist die ASP.Net Core Web App, MVC. So könnte unsere Client-Anwendung oder UI leicht mit jeder Technologie erstellt worden sein, die eine RESTful-API verbrauchen kann. Wir haben also unsere API, die wir bereits eingerichtet haben. Aber wenn wir diesen Client erstellen, Wir hätten Winkelansicht verwenden können, reagieren oder Larve oder Blazer, jeder von ihnen. Aber ich werde mich wirklich an die MVC halten, weil es selten ist , dass Sie tatsächlich sehen, dass ein MVC der Verbraucher einer API ist. Es ist normalerweise das All-in-One sowieso, und das ursprüngliche Projekt war bereits MVC integriert. Also werden wir irgendwie halten, dass MVC Gefühl, es zu tun. Kein Problem. Aber dann wurde die zugrundeliegende Architektur bereits entkernt und eingerichtet. Also gehen wir voran und Sie können einfach MVC suchen. Und denken Sie daran, dass es sich um ein ASP.Net Core Web handelt, nicht um die ASP.NET-Webanwendung. Alles klar, so dass Sie als nächstes treffen, geben Sie ihm den Namen, in diesem Fall nennen wir es h i dot leave management dot MVC, und wir verwenden ein dotnet 5-Projekt. Sie können Rasierer auch auf Zeitabschluß aktivieren, während Sie hier sind. Und dann kannst du einfach auf Erstellen klicken. Jetzt, wenn das fertig ist, werden Sie mit diesem Projekt enden, das die Standard-MVC-Vorlage Boilerplate für eine Standard-MVC-Anwendung für dotnet Core ist . Sie werden sehen, dass es unserem API-Projekt sehr ähnlich aussieht, außer dass es ein paar weitere Ordner wie Ansichten und Modelle hat. Wird MVC Model-View-Controller. Und dann haben wir die gleiche Startdatei, die gleiche program.cs Datei, die App-Einstellungen. All diese Dinge sind eine Art allgemeiner Plädoyer. Und wir haben den ww www root Ordner, der alle vier statischen hat. Also, wenn Sie bereits mit MVC vertraut sind, wo Sie kein Problem haben, aber ich werde mein Bestes versuchen, am besten zu sein, um so detailliert wie möglich mit allen Änderungen und dem Code, der geschrieben werden muss, und wie alles zusammenhängt. Wenn wir zurückkommen, schauen wir uns an, wie wir mit der Integration unserer API in unsere Kunden beginnen können . 27. NSwag für for: In Ordnung, also sind wir Buck und Artist zu sein, ist unsere Client-Anwendung einzurichten , um unsere API zu konsumieren. So haben wir bereits unsere MVC-Anwendung erstellt und wir haben unsere API-Dokumentation in Form des sogar noch. Also werden wir n Swapped verwenden, um uns zu helfen, zu generieren, es erzeugt buchstäblich den Code , der uns helfen würde, diese API zu konsumieren. Und zwischen Swagger und in Swag werden Sie sehen, dass wir in wenigen Klicks, in ein paar Minuten, den ganzen Code haben, oder zumindest den größten Code, der benötigt wird , um tatsächlich die Kommunikation zwischen dem Client und der API herzustellen . Also Schritt 1, rufen Sie Ihre Swagger-Dokumentation auf und dann können Sie zu der JSON-Datei gehen, die sie generiert, indem Sie auf diesen Link klicken, diese JSON-Datei aufruft, die im Grunde diese Anzeige antreibt, die wir hier sehen. Also das nächste, was ich möchte, dass Sie tun, ist zu Google oder Bing gehen und die GitHub-Seite für n swag Studio finden. Dann können Sie das herunterladen und installieren und es ist gut dokumentiert, aber wir werden genau das durchmachen, was Sie tun müssen, um es in Betrieb zu nehmen. So können Sie es einfach herunterladen und installieren. Und sobald Sie das getan haben, werden Sie mit diesem schönen Interface begrüßt. Es gibt also nur wenige Dinge, die Sie auch tun möchten. Beginnen Sie mit diesem Verfahren. Nummer eins, Sie möchten sicherstellen, dass die Laufzeitumgebung korrekt ist. Also standardmäßig denke ich, dass es zu Net Core 21 gehen kann. Wir benutzen Netz fünf, also kannst du das einfach ändern. Und dann muss die Spezifikations-URL die URL zur JSON-Datei sein, die von Swagger kommt. So können Sie das einfach aus dem Browser kopieren und dort einfügen. Klicken Sie auf Lokale Kopie erstellen. Und dann sehen Sie die Dokumentation hier oben. Jetzt mit all dem erledigt und nur die Hinweise, dass diese in Swag andere Arten von Client-Anwendungen unterstützen, was TypeScript bedeutet. Wenn Sie View oder Reactor eines dieser JavaScript-Frameworks verwenden , könnten Sie genauso einfach Code mit diesen Frameworks generieren und für diese Arten von Frameworks tauschen. Wir halten uns jedoch an die C-Sharp-Kunden fest, also würden Sie das einfach nehmen und Sie erhalten den neuen Tab. Und dann gibt es ein paar Einstellungen hier. Lassen Sie mich einfach nach oben scrollen. Es gibt ein paar Einstellungen hier, die wir sicherstellen wollen, dass sie in der Polizei sind. Nummer eins, richten Sie den Namespace ein. Also für Namespace habe ich HR Dot Leave Management Dot MVC Dot Services. Das ist der Namespace, in den ich den gesamten Code generieren möchte. Es gibt andere Dinge, die bereits angekreuzt werden können, aber ich werde einfach durchgehen und sicherstellen, dass wir die Karte F1 einrichten. Verwenden Sie also die Basis-URL für die Anfrage. Sie möchten sicherstellen, dass das angekreuzt ist und die Basis-URL-Eigenschaft in der Basisklasse definiert werden muss. Ordnung? Sie möchten sicherstellen, dass Sie den injizierten HTTP-Client von einem Konstruktor angekreuzt haben und Schnittstellen für Clientklassen generieren. Scrollen auf, ich denke, die meisten davon sind bereits standardmäßig da. Sie möchten sicherstellen, dass die generischen Detailtypen angekreuzt sind. Und fast bis zum Ende. Wir wollen auch sicherstellen, dass wir dann tatsächlich zum Ende kommen, denn ich denke, alles andere wird hier standardmäßig bereits ausgefüllt sein. Also werde ich nicht zu viel Zeit auf Dinge verbringen, die bereits da sind und nicht ich bin nicht müde, nicht unbedingt notwendig. Also alles, was außerhalb des Punktes ist, wird nur sicherstellen, dass diese vorhanden sind. Du kannst alles übrig lassen. Und dann möchten Sie am Ende den Ausgabedateipfad einfügen , damit Sie einfach zu Ihrem Projekt gehen können, das korrekt als Projekt bezeichnet wird. Viele Visual Studio, sorry, grep, klicken Sie auf ein Projekt und gehen Sie zu Öffnen im Explorer, nehmen Sie diese URL oder diesen Pfad und fügen Sie es hier, was wir setzen Dienste Schrägstrich, Schrägstrich Client-Dienst Punkt CSS. Nachdem Sie das alles getan haben, können Sie fortfahren und Dateien generieren drücken, und es sollte nicht sehr lange dauern, diese Dateien zu generieren. Und wenn das erledigt ist, können Sie zu Visual Studio springen und zu Ihrer Dienstbasis- und Dienstclientklasse wechseln. Ich habe etwas schneller, was wir später besprechen werden, aber es konzentriert sich nur auf die Server- und Service-Grant-Datei. Also haben wir diese Client-Datei, die generiert wird und es gibt uns eine Schnittstelle und die Implementierung der Schnittstelle out of the box, richtig? Viele Dokumentationen zu Anmerkungen müssen sich nicht wirklich um zu viele dieser Dinge kümmern. Aber am Ende des Tages, es erzeugt ein Boot 1700 Zeilen Code, zumindest in meinem Buch. Basierend auf der Größe Ihrer API können Sie mehr erhalten, Sie können weniger erhalten. Aber der Punkt ist, dass all das für uns getan wurde , damit wir uns auf wichtigere Dinge konzentrieren können, oder? Also wollen wir intelligenter arbeiten, nicht härter. Und andere wichtige Sache zu beachten ist, dass innerhalb von Swag, jederzeit, wenn sich die Dokumentation ändert, was bedeutet, dass jemand eine Änderung an der API vorgenommen hat, Swagger. Infolgedessen hat sich, wenn auch an den Endpunkten Anforderungen geändert, was ändert sich das? Sie können immer einfach löschen, dass Sie in setzen. Und so wieder, regenerieren Sie diese Datei, so dass Sie nicht zu bekommen, dass das Hin und Her reduziert, vor allem in einer agilen Umgebung, in der Änderungen unvermeidlich und schnell sind. So können Sie immer das Tempo mit regenerate in diesem Client halten und den Code um ihn herum ändern, wenn nötig? Nein, ich habe nicht erwähnt, dass ich ein paar andere Akten habe, und während wir auf die Details von ihnen eingehen, werde ich es Ihnen nur zeigen. Also habe ich Verträge und die Verträge, mit denen ich eine Vertragsdatei oder eine Schnittstelle pro Endpunkttyp habe, mit der ich interagiere, und auch eine Service-Implementierungsdatei für jeden Vertrag, der avons für Windows gestartet wurde, aber ich gebe Ihnen nur eine Vorstellung davon, was diese zusätzlichen Dateien in der Basisdatei, Basisordner sind. Ich habe auch eine API-Antwort und sie sind mehr PFAS, die in die Basis gehen , nur damit wir diese Erweiterbarkeit haben können. Aber nein, du musst dir keine Sorgen darüber machen. Das nächste, was Sie vielleicht tun möchten, ist Newtons Soft einzurichten. So erhalten Sie wahrscheinlich einen Fehler irgendwo, wo das Wort Newtons von diesen in dieser Datei referenziert wird. So können Sie immer zu New gets gehen. Und dann würden Sie nach Newtons weichen, sorry, Microsoft dot ASP, NET Core, VC dot Newton weichen JSON suchen wollen. Sie können also voran gehen und das installieren, einen neuen Build machen, und diese Bereiche sollten verschwinden. Als nächstes möchten wir in unserer Startup-Klasse unseren HTTP-Client registrieren. Also sagen Sie, in den Konfigurationsdiensten würden Dienste sagen, die Client hinzufügen. Ich führe PaaS in IE-Client und Client. Diese beiden untersuchen nach mehr generierten Dateien. Und dann wollen wir ihm die Basisadresse übergeben. Es ist also nur ein CEO oder ein gleichwertiger Kunde, weißt du, das ist ein Lambda-Ausdruck. Die Basisadresse der Punkte ist gleich dem neuen URI. Und dann wollen wir die URL zur eigentlichen API. Um diese URL-API zu finden, können Sie zum API-Projekt gehen, Eigenschaften erweitern und Einstellungen starten. Und dann würdest du diesen SSL-Port sehen. Also ist es im Grunde http localhost Doppelpunkt für voll, in meinem Fall 44, 3, 27. In Ihrem Fall könnte es anders sein, oder? So HTTPS localhost und dieser SSL-Port, wie Sie es in Ihrem Rasen Sittings sehen. Damit haben wir also tatsächlich den Kunden oder zumindest die Grundlage für den Kunden eingerichtet. Die Verträge und die Dienstleistungsdefinitionen, die wir hier haben, und wir werden die Fischerei letztendlich zurückkehren, beziehen sich auf die spezifischen Operationen, die pro Anruf erforderlich sind. Denn wenn wir C rufen, bekommt alle Blatttypen. Wie werden wir die Blatttypen in unserer Anwendung anzeigen? Wir müssen immer noch Modelle haben. Wir müssen es immer noch von JSON deserialisieren, weil, wissen Sie, Rest APIs, die sie senden und empfangen, JSON. Also müssen wir von JSON in einen Typ konvertieren , den unsere Client-Anwendung schätzen kann. Und dann können wir dem Benutzer erlauben, mit ihm entsprechend zu interagieren. Also, wenn wir zurückkommen, schauen wir uns all die an. Obwohl Codierung Aktivitäten, die wir in unseren eigenen setzen müssen, unseren Kunden. 28. Benutzerdefinierte Setup und Basiscode: Jetzt werden wir also einige der unterstützenden Dateien und Funktionen erstellen oder durchlaufen , die wir einrichten werden, bevor wir mit dem Aufbau unserer Client-Anwendung fortfahren . Das sind also wirklich einmalige Operationen, die wir durchmachen werden und ich werde erklären, warum sie hilfreich sind. Nicht notwendigerweise notwendig, aber zumindest hilfreich. Beginnen wir also mit unseren Drittanbieter-Bibliotheken in neuen Gets. Wir gehen und holen den Herbst oben und wir werden vor Ort bei Julian Hansen lagern. Alles klar, das wird uns später helfen. Wir werden es jetzt nicht unbedingt benutzen, aber Sie können einfach voran gehen und es von Nein bekommen, so dass wir einfach alles ein für allemal einrichten können. Wir bekommen sowohl Herbst-Ober- als auch letztendlich Erweiterungen. Und wir haben bereits die Newton's Soft. Mit all dem, was im Startup installiert ist, werden wir sicherstellen, dass wir den Auto-Mapper hinzufügen. Jetzt fragst du dich wahrscheinlich, okay, warum füge ich ultimative Papiere hinzu? Wieder, nachdem wir es wahrscheinlich schon in der Anwendung gemacht haben. Also hatten wir diese Dienste für den Vertrieb in unserer Anwendungsebene eingerichtet und wir hatten Herbstoper hinzugefügt. Also fragen Sie sich wahrscheinlich, okay, genau wie mit der API, als wir gerade konfigurieren Anwendung und Dienste aufgerufen haben. Warum konfigurieren Sie keine Anwendungen und Dienste, die Clint sind? Nun, die Realität ist, dass der Klient wirklich nichts über irgendetwas anderes in diesem Projekt weiß , oder? Es ist also ein eigenes Projekt. Stellen Sie sich vor, wenn wir sagen, eine Ansicht oder eine Angular-Anwendung verwenden , wird es dasselbe sein. Es wird keine geben, ja, abgesehen von der Tatsache, dass es keinen Bottom-up geben würde, aber Tatsache ist, dass es keine Kern- oder Infrastrukturreferenzen geben würde. Es verweist kaum auf die API, weiß nur, dass eine API an einer Adresse gefunden werden sollte, und das ist die Annahme, die es macht. Deshalb verweisen wir nicht auf eine der anderenBibliotheken innerhalb dieser Client-MVC-Anwendung. Deshalb verweisen wir nicht auf eine der anderen Es ist eigenständig und alles, was es tut, ist zu einem Endpunkt erreichbar und erwartet danach ein bestimmtes Ergebnis, was der API-Aufruf wäre, den wir hier konfiguriert haben. Deshalb fügen wir Herbst-Obermaterial individuell zu diesem Projekt hinzu. Und noch einmal, das liegt daran, wenn wir die DTO mit bekommen, müssen wir möglicherweise Daten Bits massieren, bevor wir dem Benutzer angezeigt werden, in irgendeiner Weise, Form oder Form mit ihm interagieren. Also fügen wir Auto-Mapper hinzu, und ich habe bereits vorangegangen und das hinzugefügt. Nun, Sie müssen sich keine Sorgen darüber machen, dass diese Linie durch diese drei Zeilen im Detail in ein paar gehen wird. Also gehen Sie einfach voran, fügen Sie Herbst oben. Und dann wäre die nächsten paar Dinge, die wir in Kraft setzen müssen ein benutzerdefinierter Antworttyp zu erstellen. Also würde unser Antworttyp hier verwendet werden, wenn wir mit der API und der API-Antwort sprechen, es könnte mit der Befehlsantwort sein. Es könnte mit der RBS-Befehlsantwort sein, vielmehr könnte es mit den Validierungsfehlern sein, was auch immer es ist. Wir wissen es nicht. Denken Sie daran, dass wir nur mit einer API interagieren, also erwarten wir entweder, dass gute Sachen zurückkommen , oder irgendeine Form der Ausnahme ist ein Feuer von Butterlaichen. Wir wissen es nicht. Also erstellen wir unseren eigenen generischen Antworttyp auf dem Client, in der Lage sein wird, eine Nachricht zu erhalten. Es wird gut sein. Liebe, Validierungsfehler in Form einer Zeichenfolge zu bekommen. Es wird wissen, ob es erfolgreich war und es würde einige Objekte, Objekte zurückbekommen. Also nenne ich es „t go“, wir wissen nicht, was es sein könnte. Es könnte ein Objekt mit dem Sie wissen, wir wurden das Objekt in einigen der erstellen zurückgegeben, es könnte eine ganze Zahl sein, würde nur die ID, wir wissen nicht. Natürlich wäre es klug von uns, all diese Dinge zurückzuverfolgen und zu standardisieren. Für pädagogische Zwecke hätten wir verschiedene Szenarien durchlaufen. Aber wenigstens in die mehr unternehmerische Umgebung gehen, würden wir das standardisieren wollen, damit wir definitiv wissen können , was für jedes Szenario zu erwarten ist. Das ist also unser Response-Zeug vom Kunden. Ordnung, also in der nächsten Datei weiterzumachen , die wir haben, die sich ansehen will, ist, dass ich behaupte. Also im Basisordner haben wir einen Client und Sie haben Clients, die Sie wahrscheinlich sehen. Ok. Aber haben wir nicht den AAE-Client und den Kunden gesehen? Und wenn Sie das sehen, dann haben Sie Recht. In unseren Service-Kunden, die generiert wurden, haben wir ironclad und wir haben Kunden. Aber dann wollen wir einfach eine kleine Erweiterung davon schaffen , damit wir nicht zu tief graben müssen, um bestimmte Dinge zu erreichen. Also eins, Sie würden bemerken, dass dies ein Teil ist. Ordnung? Die coole Sache an einem partiellen ist, dass es bedeutet, dass Sie mehrere Versionen derselben Klasse haben können. Natürlich werden sie alle zusammenarbeiten. Aber jeder Kevin hat mehrere Dateien mit demselben Namen, demselben Klassennamen oder Schnittstellennamen. Und es ist, als ob sie alle zur Laufzeit zusammenführen. Es ist also ziemlich cool, wenn Sie noch nie mit Partials interagiert haben. Aber wir haben das Teilstück, das für uns bereits generiert wird. Wir werden also nur unsere eigene Teilimplementierung oder unsere eigene partielle AAE-Client-Schnittstelle erstellen , die nur Zugriff auf den HTTP-Client hat. Ordnung, also im Dienst, dann haben wir diesen HTTP-Client. Es ist sehr tief. In Zeiten wahrscheinlich nicht sehr zugänglich, also erstellen wir nur eine öffentliche Version davon. Und dann in der Umsetzung, die öffentliche Teilklassenkredit in der, in Haarschnitt, sorry, von Island. Wir haben nur das öffentliche Eigentum, das unsere Rückgabe dieses Privateigentums von den Servicetypen bekommt. Es gibt also unseren privaten HTTP-Client. Das bedeutet also, dass wir nicht wirklich mit dem HTTP-Client interagieren können , falls Sie etwas damit tun möchten. Wie später, wenn wir Sicherheitsmaßnahmen machen, werden wir damit unterbrechen wollen, dass es Kopfzeilen angelegt wird, bevor es Entzündungen aussendet. Sie werden also sehen, dass Sie in einigen No 1, die Sie mit dem Client und dem Client beachten möchten, sicherstellen möchten, dass sie sich im gleichen Namespace wie ein Service, Dienstgradient, befinden. In Ordnung, also tatsächlich, als ich das tat, hatte ich nicht den Punkt, weil ich ihm nbc dot Dienste gegeben habe. Das ist der Namespace, dem ich in Swag gebe, um diese Datei zu generieren , obwohl sie im Basisordner liegt. Und dann wurde ich Client automatisch mit dem Namespace dot ds erstellt. Sie haben also zwei Möglichkeiten. Sie könnten entweder in diesem zu diesem, und dann sicherstellen, dass in Swag weiß, dass Namespace diese übernehmen sollte. Oder Sie können einfach sicherstellen, dass dies Dienste sind, denn wenn sie sich nicht im gleichen Namespace befinden und sich nicht als Partiale sehen. So können Sie das einfach zur Kenntnis nehmen, wenn Sie es tun. Wenn Sie irgendwelche Fehler bekommen, können Sie nicht herausfinden, warum Sie sie bekommen. Jetzt gehen wir zurück zu unserem Ordner „Verträge“. Und da drin würdest du sehen, dass ich eine Datei namens i local storage service habe. Nein. Ich werde darüber reden, weiterzugehen. Die lokalen Speicherdienste für wir werden die Authentifizierung mit JSON Web Tokens oder JWT für kurze Zeit implementieren , nachdem ein Tolkien einfach zu Anwendung war, Anwendung hier eine Client-Anwendung ist, müssen wir eine Möglichkeit, es zwischen Operationen zu speichern, so dass Sie sich anmelden und dann, während Sie eingeloggt sind, schauen Sie wahrscheinlich auf Ihren Urlaub, Sie tun wahrscheinlich eine Reihe von Dingen. Jeder kann an jedem Punkt im System alles tun. Aber wir werden eine Authentifizierung verlangen, damit Sie bestimmte Dinge erledigen können. Ein Token muss also definitiv vorhanden sein. Wie ich schon sagte, das werden wir später hinzufügen. Aber ich möchte dies zumindest den Auge lokalen Service, lokalen Speicherdienst von null einrichten , weil es für eine andere Bestie Setup benötigt wird , die wir tun möchten. Nein. Nachdem Sie also diese lokale Speicherbibliothek von NuGet erhalten haben, werden wir nur eine Schnittstelle erstellen, auf der wir einige der Operationen in unsere eigenen Methoden abstrahieren können . Wir wollen also, dass klare Speicher vorhanden ist, Speicherwert und einen festgelegten Speicherwert erhalten. Und es ist wirklich nur ein Wertschlüsselpaar. Also geben wir ihm nur einen Schlüssel und einen Wert. So können Sie dies verwenden, um kleine Bits von Informationen zu speichern. Natürlich möchten Sie nichts zu sensibles innerhalb des lokalen Speichers speichern , da dann Ihre Anwendung für Schwachstellen öffnen kann. Aber das ist ihr Zweck. Nachdem Sie diese Schnittstelle eingerichtet haben, können Sie die Implementierung im Ordner „Dienste“ einrichten. Wir haben also einen lokalen Speicherdienst, der von meinem lokalen Speicher erbt. Und wir haben ein Feld vom Typ lokalen Speicher, das zu uns kommt aus der Bibliothek, die uns von Hansens Punktnetz gegeben wird. Und hier im Konstruktor sitzen wir nur wie eine kleine Konfiguration und initialisieren dann den Speicher. Unsere Konfiguration sagt also neue kostengünstige Speicherkonfiguration. Automatisches Laden und automatisches Speichern sind wahr. Und dann der Dateiname, den ich ihm gerade den Namen gegeben habe, der auf die Anwendung hinweist, zu der es gehört. So können Sie voran gehen und das tun. Und dann ist der Speicher gleich dem neuen lokalen Speicher. Und alle Methoden sind ziemlich unkompliziert. Im übersichtlichsten Speicher haben wir nur die Liste der Schlüssel, die wir aus dem Speicher löschen möchten. Diese Koordinate ist also praktisch, wenn sich jemand wahrscheinlich abmeldet und Sie die Verweise auf die Token und was auch immer Sie sonst gespeichert hätten entfernen möchten. Sie können einfach voran gehen und alle Schlüssel übergeben und es würde nur entfernen Sie sie für Sie. Sie haben den eingestellten Speicherwert, wo wir den Schlüssel und welchen Wert auch immer übergeben und dann wird er ihn speichern. Nein, Dies ist t. Ja, es kann wie ein Objekt oder eine Zeichenfolge, unabhängig vom Datentyp, aber es wird es in eine Form von gespeichertem Wert und dann Speicher analysieren , die grundlegende Analyse beibehalten, halten Sie es einfach und stellen Sie sicher, dass Sie sind darauf aufmerksam zu machen. Ruft den Speicherwert im Grunde gibt nur zurück was es auf dem angeforderten Schlüssel basiert. Und dann können wir immer überprüfen, ob es existiert, oder? Geben Sie also den Schlüssel ein und es wird Speicher Xist zurückgeben, der nur ein boolescher Wert ist. Ja, es existiert oder nein, tut es nicht. Niemand Schritt, den ich Touren übersehen hätte, um dies zu den Startdateien hinzuzufügen. Wir müssen also sagen, dass Dienste dieses Mal singleton hinzufügen weil wir nicht mehrere Instanzen unseres lokalen Speichers benötigen. Das wäre eigentlich. Ziemlich schlechte Idee, richtig? Daher möchten wir nur, dass eine Instanz des lokalen Speichers für den gesamten Benutzer, die Benutzerlaufzeitumgebung oder die Verwendung dieser Client-Anwendung beibehalten wird. Und wir sind nur in den Augen Low-Cost-Speicher-Service sowie den lokalen Speicherservice übergeben ? Nein, In unserem Basis-HTTP-Dienst , der im Basisordner in unseren Diensten lebt. Wir werden nur ein paar Basisoperationen aufsetzen , die jeder Dienst in der Lage sein soll. Also eine, wo wir die Felder für I, Low-Cost-Speicher, Speicherservice und einen Client haben , den wir mit unserem Konstruktor initialisiert haben, sind wir damit vertraut oder einfach nur injiziert. Und dann später, Haben wir nicht zwei Methoden. Wir haben eine, in der wir API-Ausnahmen umwandeln ist es so dass API-Ausnahme tatsächlich von unserer KWK kommt. Denn beim Betrachten des Endpunkts, beim Betrachten, was zu erwarten ist, wurde klar, dass wir Kostümausnahmen mit Statuscode und Antwort und anderen Dingen bekommen konnten , richtig? Also haben wir Zugriff auf diesen Basistyp, aber dann wollen wir ihn wahrscheinlich in die Antwort konvertieren, wenn er jemals vorbei kommt. So können wir sehen, ob der Statuscode der API-Ausnahme 400 ist, dann sehen wir Validierungsfehler aufgetreten sind, weil das die schlechte Anfrage war, richtig? Wenn es 404 ist, dann sehen wir die Nachricht, das Element konnte nicht gefunden werden. Und dann, wenn es 500 ist und Sie sehen, dass etwas schief gelaufen ist, und so viele Fehlercodes wie wir b hätten, wissen wir, dass wir von der API zurückkommen könnten. Wir können sie immer hier einrichten und haben, zumindest bis zu einem gewissen Grad, angepasste Nachrichten pro Epoche Typ angepasst. In Ordnung, die nächste Methode wäre, das Bier Tolkien hinzuzufügen. So geschützte Leere am Bearer-Token ermöglicht es uns zu sehen, ob der Low-Cost-Speicher mit dem Wort Tolkien einen Wert hat. Manche haben wieder einmal gearbeitet, Linda, Linda, genau dort, wo wir noch nicht bereit sind. Ich lege es nur hin und wir besprechen es später im Detail. Aber diese Methode ermöglicht es Ihnen, das Bearer-Token dem Client Punkt HTTP hinzuzufügen, Client standardmäßig oder fordert Autorisierung, richtig? All dieser Code ist also im Grunde, wie Sie Zugriff auf die Autorisierungs-Header in jeder HTTP-Client-Kommunikation mit unserer RESTful-API erhalten. Und was wir tun werden, ist das Hinzufügen eines neuen Authentifizierungs-Header-Werts. Lassen Sie mich einfach die Linie brechen hier sitzt oder klar. Wir fügen also einen neuen Authentifizierungs-Header-Wert mit dem Namen Bearer hinzu. Und wir setzen es aus dem lokalen Speicher, erhalten Speicherwert vom Typ String mit diesem Schlüssel. Okay, also das ist deine Seele wird die Token bekommen, die mit unseren HTTP-Anfragen gesendet werden sollen. Aber wir sind nicht ganz bereit, dies im Detail zu besprechen, aber Sie können den Code von null schreiben. Wieder einmal, all dies ist gewachsene Arbeit. Niemand, den wir auf unser Kostüm schauen werden. Ich nenne sie nicht gerne Kostüm, aber unsere Erweiterungen der verschiedenen Funktionen sind die verschiedenen Arten von Interaktionen, die wir mit der API gleich haben werden, alle Blatttyp-Interaktionen, alle die Requests und Allokationsinteraktionen. Wir haben sie in ihren eigenen Verträgen behindert. Und dann werden alle von ihnen sowieso mit dem Basis-HTTP-Dienst interagieren, denn wenn wir uns sichern, werden sie bestimmte BCE-Funktionalität und zur allgemeinen Unterbrechung benötigen. Also, wenn wir zurückkommen und anfangen, den Blatttyp einzurichten, denn das ist immer der einfachste, richtig? Die eine ist ziemlich unkompliziert. Also fängt es mit diesem an. Und ich werde sehen, wie wir alles zusammenbinden. 29. Erleichterung der Type Management Service: Hallo, Willkommen zurück. Wir werden beginnen, die Blatttyp-Serviceanforderungen zu betrachten. Aber bevor wir in den Vertrag und die Service-Implementierung im UI-Projekt eingehen, möchte ich, dass wir einige Housekeeping Dinge mit den Handlern und der API machen. Und ich werde natürlich erklären, warum diese vorteilhaft sind, bevor wir vorwärts gehen . Also, um zu beginnen, lassen Sie uns einfach zum Create leaf Type Command Handler springen. Und wenn Sie unser erstes Gehör benötigen, ist das im Anwendungsprojekt auf den Kernordner. Alles klar, was ich Sie ermutigen würde, einen zu tun , ist, das zu standardisieren, was zurückgegeben wird. Also an allen Punkten wollen wir wahrscheinlich die Antwort des Befehls bs haben. Denken Sie daran, dass eine bs-Kommandoantwort es uns ermöglicht, das Erfolgsflag, die ID des neuen Datensatzes, sowie eine Nachricht zurückzugeben die ID des neuen Datensatzes, , richtig? Sie möchten also Ihren Handler-Code umgestalten. Ich werde dies einfach lange genug auf dem Bildschirm belassen, dass Sie entsprechend pausieren und umgestalten können , wo, wenn die Validierung fehlschlägt , die Antworterfolge fällt. Sie werden eine Nachricht haben und wir setzen alle Validierungsfehler ein. Und dann haben wir noch etwas anderes. Wenn es in Ordnung ist, dann haben wir die true, die Nachricht und wir geben die ID mit dem Antwortobjekt zurück. Natürlich, wenn wir das aktualisieren, um bs Kommandoantwort zurückzugeben, bedeutet das, dass unsere Anfrage auch das zurückgeben muss. Sie können also einfach den Blatttypbefehl aktualisieren , damit ich die Rückgabe der bs-Befehlsantwort beantrage. Das sind also Summen der Änderungen, die wir im Handler sowie in der Befehlsklasse benötigen. Obwohl. Gehen wir davon aus, lassen Sie uns zur API springen. Nun, als wir die API diskutierten, haben wir auch erwähnt, warum es eine gute Idee in den Task-Aktionsergebnissen ist , auch den zurückgegebenen Datentyp einzubeziehen. Und wir haben in der Swagger-Dokumentation gesehen, dass, wissen Sie, für diejenigen, die unseren Rückgabetyp hatten, die Dokumentation tatsächlich eindeutig angegeben hat, was zurückgegeben werden würde. Nun, da wir den Rückgabetyp für unsere create-Befehlshandler angepasst haben, lassen Sie uns auch die Aktion Ergebnisse Rückgabetyp für den Beat mit der bs Befehl Antwort anpassen . Schwer, denn wenn wir das tun, bekommen wir die Antwort, kehren wir in Ordnung. Mit dieser Antwort. In Ordnung. Damit wir wissen, verbessern Sie unsere Dokumentation und dann werde ich Ihnen eine andere Sache zeigen , die es noch besser macht in Bezug auf das, was die Dokumentation aktuell ist und dass explizit uns hilft zu tun. Noch eine Sache, bevor wir weitermachen, möchte ich, dass Sie mit der rechten Maustaste auf Ihr Testprojekt klicken und Tests ausführen. Also nur für den Fall, dass Sie nicht davon überzeugt sind, warum Komponententests wichtig sind. Wenn Sie die Tests ausführen, erhalten Sie wahrscheinlich alle Fehler für die Tests, die überprüfen sollten, ob die Validierung oder der gültige Blatttyp oder ungültige Blatttyp erfolgreich hinzugefügt wurden, Warum schlagen sie fehl? Nun, wir haben gerade unseren Refactor gemacht, also ändern wir einfach etwas in unserem Code, unser Teslas Huhn für eine Sache. Und offensichtlich würde das, was wir geändert haben, diesen Test brechen. Wenn Sie nun zu Ihrem Test zurückkehren, denken Sie daran, dass wir gesagt haben, dass das Ergebnis der ADD-Operation vom Typ int sein sollte. Also noch einmal, dies ist eine gute Möglichkeit zu sehen, wo das Refactoring Ihres Codes tatsächlich die Dinge ändern würde, oder? Also nein, der gültige Test hätte gesagt, sollte Blatttyp int sein. Wir werden das ändern, sollte auf Kommandoantwort basieren. Jetzt zählte der ungültige darauf, dass eine Validierungsausnahme ausgelöst wurde, was vorher der Fall war oder faktoriert oder Schnee. Also müssen wir tatsächlich diesen Test anpassen, um zu wissen reflektieren, dass Es keine Ausnahme eine. Und dass wir nur die gleiche Art von Operation machen, bei der wir gerade auf 0 warten, weil das unser neuer Code tut, richtig? Also rufen wir das Warten auf Ergebnisse an. Und die Ergebnisse sollten von der typbasierten Befehlsantwort sein und der Code sollte drei sein. Also, wenn wir diese Tests erneut ausführen, dann sehen wir, dass wir alle unsere erfolgreichen Tests haben. Also wieder einmal, Einheit selbst war es, uns zu halten, hilft uns in Schach zu halten mit unseren Faktoren und unseren Kernänderungen in einem so großen Projekt. Nun, da wir modifiziert oder API haben, müssen wir den Kalten Krieg, den Service-Client, regenerieren. Und zusätzlich zu nur regenerieren, gibt es ein paar Änderungen, die ich mit den Einstellungen darauf hinweisen möchte, wie Sie das tun. Also nochmals, gehen Sie weiter und holen Sie sich diesen JSON-Link, wenn Sie ihn nicht bereits aktiviert haben. Und dann am Ende Swag-Schnittstelle, werden wir es einfügen und wir werden die lokale Kopie neu erstellen. Also müssen wir diesen Schritt jedes Mal tun, ob Sie es hatten, es gibt nicht, weil was immer es im JSON sieht , das ist, was es verwenden wird, wenn es den Code generiert. Also zeige ich auf diese Zehe, weil vor der Post-Methode , die wir gerade modifiziert haben, nur einen Rückgabetyp von 200, 100 mit vielleicht einem int hatte . Nein, Sie werden sehen, dass es andere Rückgabetypen hat. In Ordnung. Die Schlussfolgerung daraus für das Ende SWACH Studio ist, dass es die Tatsache kompensieren muss , dass es unseren Rückgabetyp der bs-Befehlsantwort erwarten sollte. Also werden wir das Gleiche sein. Also, wenn Sie es schon offen haben, ist das in Ordnung. Aber wenn nicht, können wir es noch einmal durchmachen. Es ist R-dot verlassen Management, aber MVC dot services.js, ich setze dieses Mal auf die Basis Mr. es aus dem ersten Mal, wollen sicherstellen, dass wir die Ausnahmeklassen generieren. Injizieren Sie HTTP-Client über den Instructor und generieren Sie Schnittstellen für den Clientzugriff. Und wir wollen die Detailausnahmen im Fußball umschließen. Ausnahme-Instanz. Wir wollen die Details generieren. Aber eine Sache, die, wenn Sie vorher hatten, würde ich gerne für Sie deaktivieren, ist dies auf einem Boot, die US-Basis-URL für die Anfrage. Also hatten wir es anfangs angekreuzt. Sie können das Häkchen entfernen. Grund, in dem Dienstgewährungscode zu sein, den Sie alle geöffnet haben , würden Sie sehen, dass sich ein BaseUrl-Feld befindet und auf eine Zeichenfolge wartet. Also umgehen wir eigentlich die Notwendigkeit, die Zeichenfolge in diesen Code zu setzen , weil wir registriert oder HTTP-Client mit seiner Basisadresse. Also brauchen wir das nicht. Verwenden Sie BaseURL für Anfrage mehr. In Ordnung, also können Sie Punkt 1 entfernen und voran gehen und sicherstellen, dass alles andere entsprechend angekreuzt ist. Und sobald Sie das getan haben, haben Sie natürlich auf den Ausgabepfad hingewiesen und dann erzeugen Sie Dateien. Sobald Sie also, dass dieser Service Trends CS-Datei regeneriert und aktualisiert wird, um zu wissen, dass neue Rückgabetypen oder Typen, wenn Sie mehr als eine Sache umgestalten, wird alles, was neu in Ihrer API ist , in der -Dokumentation und als Ergebnis, spiegelt sich in Ihrer neuen Service-Markenklasse. Nun, da wir die Grundlagen mit unseren Handlern und unserer API abgeschlossen haben. Springen wir zurück zu unserer Benutzeroberfläche. Also bin ich in der Startup-Klasse und Lee kann sehen, dass ich die Dienstlinie „Ich lasse“ vom Typ „Dienstblatt“ nicht kommentiert habe. Wir werden die anderen zu gegebener Zeit entkommentieren, aber Sie können einfach mit diesem auf kommentiert beginnen. Und schauen wir uns die Implementierungen an. Zuvor möchte ich jedoch darauf hinweisen, dass wir das Mapping-Profil haben. Also habe ich das Mapping-Profil erstellt, das die gleichen Prozeduren folgt , um von unserer Anwendungsebene verwendet wurden, wo wir von Profil mit freundlicher Genehmigung von Herbst oben erben und dann beginnen wir , in diese Profilkarte Konfigurationen setzen. Ich habe auch einige Ansichtsmodelle erstellt. Ich werde tatsächlich mit dem ViewModel beginnen, bevor wir uns die Blätter Service-Implementierung und Schnittstelle ansehen . Also, wenn wir einfach nicht wissen, wo das ist, habe ich in unserem Models-Ordner erstellt, lassen Sie Typ VM. Ich habe diesmal alles in eine Akte gelegt. Also in der Blatttyp-VM, werden Sie sehen, dass ich das habe, was die VM darstellt, die alle Felder hat, aber es hat nur die ID. Und dann habe ich erstellt verlassen, dass VM, wo wir den Namen haben und der Standard ist, so lassen Sie, dass VM erbt von erstellen Blatt diese VM. Wir haben also immer untersucht, wie wir Wiederholungen zwischen den VMs reduzieren können. Und noch einmal hängt es davon ab, wie detailliert Sie in Bezug auf die Daten oder die Datenpunkte erhalten möchten , anstatt dass Sie in Ihre Ansichtsmodelle einfügen. Lassen Sie hier also, dass VM ID hat und erbt alle anderen Felder von Create und erstellt diejenigen, die nicht diese ID haben. Und wir haben bereits besprochen, dass es von der Detailebene ist, warum das so gemacht wird. Also wieder, aus dem Mapping-Profil, kann ich zwischen dem ViewModel nativ in der, der UI-Anwendung oder der Art und Weise und den Details mit freundlicher Genehmigung unserer AI-Dienst-Clientdatei oder Service-Grant-Datei Entschuldigung, wo wir alle Details Art von Bezug auf in dieser Datei gemacht werden. So können Sie voran gehen und diese Art von Mapping und diese Modelle replizieren. Jetzt springen wir zu, glaube ich, geben Sie Service ein. Also diese Schnittstelle, es ist in Verträgen und es implementiert im Grunde alle Crowd-Funktionen, von denen wir wissen, dass sie nativ sind. Sie müssen ich Typoperationen verlassen werden, werden Typoperationen angenommen. Also haben wir die Get-Blatt-Typen, die eine Liste von Lift zurückgeben, IBM, derjenige, der das Detail erhält, das dieselbe VM zurückgibt. Wir haben die Reaktion der Aufgabe insular. Sie schauten sich die Antwortklasse an. Hier erwarten wir also tatsächlich diese Antwort gegenüber dem Vater. Wir erhalten diese Basisantwort von dem Befehl, der unseren Blatttyp erstellt. Also wird unsere Aufgabe eine Antwort zurückgeben, aber dann Interieur, dies repräsentiert den ID-Wert zurückkommt, weil das ist, was wir wirklich, wirklich wollen, richtig? Also eine Antwort relativ zum Typ von int erstellen Blatttyp und wir übergeben in diesem Blatt diese VM. Wir haben auch die Aufgabe zu aktualisieren und eine Aufgabe zu löschen. Nachdem wir also alle diese in der Schnittstelle eingerichtet haben, wie wir zuvor gesehen haben, müssen Sie, sobald Sie einen Vertrag haben, die Implementierung haben. Also drüben in der Implementierung, die ich gerade in den Services-Ordner eingefügt habe, haben wir den Blatttyp-Service. Also lasst uns das gemeinsam durchgehen. Dies erbt also vom Basis-HTTP-Dienst, den Sie zusammen durchlaufen haben. Und dann lasse ich Typ-Service an diesem Punkt wird Ihnen alles sagen, was Sie brauchen, um die Implementierung zu tun. Kein Problem, Sie gehen voran und lassen Sie es alle erforderlichen Methoden implementieren. Also innerhalb dieses Blatttyp-Service haben wir den lokalen Anstieg, der IM-Ober- und AAE-Client wird injiziert. Alle werden also entsprechend injiziert und initialisiert. Wir müssen auch zu unserer Basis übergehen. Und die Basis ist hier der Basis-HTTP-Dienst, der HTTP-Client sowie der lokale Speicherdienst. Das hast du schon gesehen. Also musst du all diese Dinge einstellen. Bitte zeigen Sie, um dort wirklich für dieses Segment zu stoppen, wenn wir zurückkommen, werden wir uns die verschiedenen Methoden ansehen, die implementiert wurden. Ich habe da schon Code, aber das ist in Ordnung. Wir werden es im Detail auf dem Comeback durchgehen. Aber das sind Ihre Methoden, die vom elif-Typ-Service geerbt werden, und sie sind alle dort platziert, die darauf warten, implementiert zu werden. Also werden wir das ebenso wie unsere Controller und unsere Ansichten in der nächsten Lektion durchgehen. 30. UI der die Verwaltung von Type Type Type: In dieser Lektion gehen wir durch unsere Controller und Ansichten und die allgemeine Benutzeroberfläche, wie wir führen unsere Anwendung interagiert mit der API für alle Crud-Operationen. Aber bevor wir dort ankommen, habe ich einige Korrekturen, die wir an unserer Schnittstelle und der Implementierung für unseren Blatttyp-Service vornehmen müssen . Korrekturen würden also die Aktualisierung der Rückgabetypen für das Update und Löschen beinhalten. Ich habe irgendwie Kopieren und Einfügen. Und in der vorherigen Lektion hätten Sie wahrscheinlich über die falschen Implementierungen kopiert , sind falsche Prototypen für diese Methoden. Sie können also voran gehen und diese entsprechend aktualisieren, wo sie alle die gleiche Aufgabenantwort relativ zum Typ int zurückgeben sollen . Und für das Update und die Löschaktualisierung ist gut, einen int ID-Parameter und den Blatttyp VM zu nehmen . Und das Löschen wird diesen int ID-Parameter nehmen. So können Sie voran gehen und diese Änderungen vornehmen und natürlich die Implementierungen innerhalb der Blatttyp-Service-Datei aktualisieren . Jetzt, um die Benutzeroberfläche zu erstellen, müssen wir natürlich die zugrunde liegende Implementierung setzen und dann den Code und alles verkabeln. Also beginnen wir mit den sehr einfachen, die der Blatttyp R wäre, um Blatttypen zu erhalten, was die Liste sein wird. Und sie bekommen Blatttypen Details, die es wäre. Okay, also lassen Sie uns die Implementierungen für dieses Tool betrachten. Sie sind ziemlich einfach. Alles, was wir tun, ist eine Variable zu initialisieren, die ich in den Blatttypen aufrufe oder Napoleon über Blatttypen gleich warten Client. Dieser Client ist also nicht das HTTP-Grant, das in das injiziert wird , was der Client vom übergewichtigen HTTP-Dienst kommt, oder? Zugegeben, es wäre fast dasselbe, denn der einzige Grund, warum wir diesen haben , ist, dass wir ihn an die Basis weitergeben können. Alles klar, aber bleiben wir einfach dran. Also Unterstrich Client stellt das Basisproblem HTTP Service Gland. Und das ist es, was wir benutzen. Also warte ich auf diese Arbeit Trend, Punktblätter, alle ein Waschbecken. Alles klar, das gibt uns Zugriff auf alle Methoden , die für uns im Service-Client generiert wurden, vereitelt den End Swap. Sie werden also Blatttypen von Blatttypen sehen, Leads werden am vollständigsten von jemandem namens ihm Methoden in Ihrem API-Controller gesehen, Sie können etwas andere Namen sehen, aber ich habe gerade auf besonders Benennungskonvention für Standard-API Entwicklung. Und ich bekomme nur die. Also ich denke, es ist klar genug, dass diese eine bekommt alle von den anderen bekommt, will nur, et cetera. So oder so, die Parameter können immer Ihr Leitfaden sein. So Vardy-Typen ist gleich, um alle Blatttypen zu warten. Und dann geben wir Mopp, Mop-Liste, Blatttyp, VM, die Blatttypen zurück. Alles klar, deshalb gibt dies diese Liste der Blatttyp-VM zurück, da dies in der Liste zurückgegeben würde, sind öffentliche Zone des Blatttyps DTLs Stunde, die sie nur zu unserer lokalen Blatttyp-VM zuordnet. Also haben wir uns bereits den Mapper und die Konfiguration dafür angesehen. Nein außerhalb davon, für die Details, was wir hier tun, ist nur eins zu bekommen. Also sehen wir var Blatt, um z gleich 08 zu sein. Klient. Blatttypen bekommen eine Spüle und die bekommt nimmt unseren Mentor von int id auf. Und dann geben wir ebenfalls eine Mock-Version zurück, um Typ VM dieses Blattes zu verlassen. Jetzt gehen wir zu einem der komplizierteren. Beginnen wir mit dem Löschblatttyp, und ich werde den Blatttyp löschen muss nur die ID. Es benötigt nur die ID, weil der API-Parameter, wenn es die ID benötigt. Also machen wir einen Trendfang in dieser Situation, wo wir ein Gewicht client.read Blatttypen sehen, asynchrone Übergabe in dieser ID löschen. Und dann werden wir eine neue Antwort vom Typ int zurückgeben, wo der Erfolg wahr ist. Alles klar, wenn das nicht erfolgreich war, dann fangen wir deshalb und konvertieren wir oder API, die unsere API-Ausnahme hätte, die mit den entsprechenden Informationen in die Antwort zurückgekommen wäre. Okay, das ist so ziemlich das für die Löschung. Und dann das Update. Eigentlich sieht es dem sehr ähnlich aus, außer in Richtung ID und der Blatttyp als Typ leaf, dass VM. Dann werde ich ein Mapping machen, um das von Blatt in eine VM in den Blatttyp DTO zu konvertieren , bevor wir es dann senden. Und das alles über diese Blatttypen setzen async. Wenn Sie den Mauszeiger darüber bewegen, werden Sie sehen, dass es eine ID vom Typ string, meine am Ende generierte Zeichenfolge, benötigt . Ich fand es überraschend, was ich gerade gesagt habe, lassen Sie mich damit arbeiten, anstatt zu versuchen, es zu umgehen. Deine nimmt int, dann ist das in Ordnung. Sie müssen diesen ID-Punkt nicht zu String machen, aber in meinem Fall dauert es eine Zeichenfolge, also kein Problem, ich nehme die int-ID, ich wandle sie nur in String um. Und ich übergebe auch diesen Blattdiabetes. Nun, das bin ich gerade konvertiert. Dann, wenn alles erfolgreich war, geben wir einfach eine Antwort mit Erfolg gleich wahr. Wieder einmal, es ist in einem Versuch fangen. So würde jede Ausnahme abgefangen werden. Kennen Sie mit dem erstellen bringt Sie in ein bisschen mehr. Also habe ich angefangen oder du hättest eine Vorschau davon gesehen. Nun, lassen Sie mich Sie durch, was dieser Code dieses Mal macht. Also wieder, es gibt eine Antwort mit Tauchen Sie in Staking zurück, erstellen Sie Blatt-VM als seinen Parameter. Und es ist wirklich die gleichen Code-Bits, aber nur mit ein paar weiteren Plots und Drehungen. Also hier sehe ich Blatttyp-Detail erstellen und ich mache das Mapping. Und dann sehe ich mir die Antwort von der Post. Der Grund, warum ich dies tun muss, ist, daran zu denken, dass wir unseren API-Aufruf aktualisiert haben, um diese Befehlsantwort zurückzugeben. Die anderen, die ich zurückgebe, null Inhalt, richtig? Deshalb gibt es nur Aufgaben. Aber im Falle des Create wir tatsächlich Feedback nach dem Anruf. Also bekommen wir eine bessere Antwort, die bs Kommandoantwort ist. So generiert der Service-Client tatsächlich dieses Glas für uns, um die Antwort des Basisbefehls zu imitieren, die von der API stammt. Also denken Sie daran, an diesem Punkt, dass wir immer noch nichts über AICPA wissen , wurden nicht mit der tatsächlichen Basisantwort-Implementierunginteragiert der tatsächlichen Basisantwort-Implementierung , die wir bis in unserer Anwendungsebene durchgeführt haben. All das wird genau hier im Mandanten erledigt. Also im Grunde Non-Response hilft Buck, nachdem wir einen Post-Versuch machen. Und denken Sie daran, dass das gegen einen Versuch ist, auch wenn es das Gefühl hat, dass es nicht unbedingt ein Fehler weil er aus Validierungsgründen gescheitert sein könnte, aber immer noch etwa 200 Antworten bekommen würde, richtig? Also der Versuch fangen, und nur um ein wenig zurückzuverfolgen, ist der try-catch hier wirklich, dass, wenn der Service-Client so eingerichtet ist, dass, wenn die Antwort nicht ein 200 ist, es als Ausnahme sieht, Deshalb machen wir diese Bekehrung. Wissen Sie im Fall der, der Create, wir hätten eine 200 Antwort mit dieser Basisbefehlsantwort bekommen können, aber dann ist es nicht erfolgreich. Also kommen wir zurück, okay, http weise. Aber die Operation selbst war nicht erfolgreich, so dass der Motor sagt uns, dass er nicht erfolgreich war. Wir haben diesen Motor geschrieben, damit wir das richtig wissen. Aber für den Fall, dass Sie eine Drittanbieter-API bei uns konsumieren, hätten sie zu diesem Zeitpunkt deutlich machen müssen, dass Sie eine 200 bekommen könnten, aber Sie müssen immer diese Flagge überprüfen, wenn sie wahr oder falsch ist. Also in diesem Fall, wenn es erfolgreich ist, dann kleiden wir unsere Antwort aus, das ist unsere lokale Antwort vom Typ int. Wir statten die Daten mit der ID aus. Denken Sie daran, dass wir darüber gesprochen haben, die ID des neu erstellten Datensatzes zurückgeben, und dann ist der Erfolg wahr. So vor Ort wissen wir, dass unser Versuch, zu schaffen, tatsächlich erfolgreich war. Andernfalls erhalten wir nicht alle Pfeile, die in dieser Basisbefehlsantwort mit diesen Paketen mit den Validierungsfehlern verpackt worden wären . Und dann bringen wir sie in unsere lokale Reaktion ein und häufen sie auf. Und dann geben wir diese Antwort zurück, so dass es wahr oder falsch war oder diese Antwort zurückgeben. Und wieder einmal fangen wir alle Ausnahmen ab, die geworfen worden wären. Jetzt, wo wir eine exemplarische Vorgehensweise haben, sieht unser Service-Implementierungscode aus. Und natürlich ist dies immer noch durchdrungen von Veränderungen in einer agilen Umgebung. Sie können es auf eine Weise tun und in Ingwer die Straße runter , weil es etwas anderes, das in Ordnung ist. Aber vorerst haben wir das. Der nächste Schritt wäre also, unsere Controller zu erstellen. Und der Controller, mit dem wir anfangen, wäre natürlich für Blatttypen. Sie können also mit der rechten Maustaste auf Controller klicken, klicken Sie auf Controller hinzufügen. Und ich werde nur einen MVC-Controller mit Umleitungsoptionen machen. Gehen Sie weiter und fügen Sie es hinzu, und wir werden es Blatttypen Controller nennen. Also wissen Sie, dass der Controller erstellt wurde. Der erste Auftrag wäre, die Injektion einzurichten. Also wollen wir unseren I'll type Service injizieren und wir können natürlich weitergehen und alle fehlenden Referenzen hinzufügen. Also verlasse ich den Typdienst in unserem Controller null. Lassen Sie uns mit der einfachen beginnen, Ich werde sagen, die einfachsten Seiten, um aufstehen und laufen. Wie können wir mit der Indexseite beginnen. So einfache Möglichkeit, die Indexseite zu erstellen. Sie können einfach mit der rechten Maustaste klicken und auf Ansicht hinzufügen klicken. Und wir wollen ihren View-Index erhöhen. Wir wollen die Listenvorlage. Und dann sollte es eine Liste relativ zum Typ, Blatttyp der VM sein. Sie können also voran gehen und das hinzufügen. Sobald du das getan hast, bekommst du diese Ansicht. Alles klar, also ist es nett und einfach. Und wenn Sie an MVC gewöhnt sind, dann ist dies keine echte Aufgabe für Sie. Du weißt also, was das ist. Und weil wir kein EOF verwenden, unser Domain-Objekt, bestimmte Dinge, die wir lieben, Geld zu überweisen, ob in diesem Abschnitt, in dem es nach dem Primärschlüssel fragt, also sagen Sie item dot ID. Deshalb verwenden wir die Blatttyp-VM, die alle Felder im Gegensatz zum Ersteller hat, die anderen, weil wir definitiv die ID für diesen Zweck benötigen und diese Links aktualisieren, so dass die Details und das Löschen bearbeitet werden. Wissen Sie, woher Sie die ID bekommen, wenn wir navigieren müssen. Wenn Sie die Benutzeroberfläche von Nein aufheben möchten, Sie können auch die ID-Felder entfernen, weil Sie und ich wissen, dass wir nicht unbedingt diejenigen in den täglichen Operationen der Anzeige von Daten benötigen. Wissen Sie, dass die Schnittstelle erstellt wird. Natürlich müssen wir die Schnittstelle N4 lassen, von der sie ihre Daten erhält. Also dieser Aufruf wird ziemlich einfach sein, wo alles, was wir sehen werden, ist VAR-Modell gleich Gewicht ist. Die Leaf Type Repository Git-Blatt-Typen, wofür wir uns gerade die Implementierung angesehen haben. Also nennt es es es verlassen Typen, die dann API verursacht und die moppte Version zurückgibt. Also wieder, wir fördern hier schlanke Controller weil es die gesamte Logik hier tun wollte, wissen Sie, den API-Aufruf zu tun, die Zuordnung durchzuführen und dann in der Ansicht zurückzukehren. Wir wollen das alles woanders anbauen. Also weiß der Controller nur, rufen Sie diese Methode auf, holen Sie die Daten und führen Sie dann mit dem Leben fort. Diese rote Linie liegt daran, dass wir diese Methode zu einer Option machen müssen. Das ist eine Aufgabe und ein Waschbecken, oder? Also, wenn Sie eigentlich wollen, gehen Sie einfach durch und machen Sie alle diese, weil sie alle asynchrone Aufrufe machen werden. Also, nur um die Wahrscheinlichkeit zu reduzieren, diese Pfeile zu erhalten, gehen Sie einfach vor und ändern Sie alles in ein AsyncTask of Action Ergebnis. Und dann ist es für den Index. Also lassen Sie uns das noch schlimmer machen, bevor ich es tue, lassen Sie mich zum Layout gehen und eine URL dafür hinzufügen. Also füge ich nur ein neues Menüelement hinzu, das besagt, dass B-Dash-Controller-Blatttypen die Aktion ist Index und es ist Def-Typen. Also lasst uns laufen und sehen. Es tut mir leid, bevor Sie laufen, bevor Sie laufen, habe ich nicht erwähnt, dass wir sowohl den Client als auch den API-Pfeil und gleichzeitig lassen müssen . Was Sie also tun müssen, ist mit der rechten Maustaste auf diese Lösung und gehen Sie zu Eigenschaften. Und dann würden Sie zum Startprojekt gehen und es in mehrere Start-up-Projekte ändern. Also brauchen wir die APA, um anfangen zu können. Wir brauchen MVC, um auch Start zu haben. Wenn du willst, dass ich mit unserem Debugging beginne. Es dauert also, Sie brauchen eine kürzere Zeit, um loszulegen. Secant ist los und klicken Sie auf Start. Jetzt ist unsere App aktiviert, sie läuft und alles, was wir jetzt tun müssen, ist zu springen, um Typen zu verlassen. Und es gibt unsere Daten, die direkt aus unserer Datenbank stammen. Nun, wir wissen es nicht. Uns ist egal, wo es herkommt. Wir wissen nur, wo eine API aufgerufen wird, sie nach den Daten fragt und sie, wir zeigen sie hier an. Also passiert alles aus der Box, richtig? Natürlich kennen wir im Hintergrund als API-Entwickler alle Wörter, die wir mit einem Handler und alles, damit wir wissen, woher die Daten kommen. Beides weiß unser Klient nicht. In Ordnung, also als nächstes wollen wir in der Lage sein, zu schaffen. Also müssen wir unsere abgeschrägte erstellen, die Sicht schafft. Um dies zu tun, noch einmal, alles, was wir tun müssen, ist zu Ansicht gehen, klicken Sie mit der rechten Maustaste auf Ansicht hinzufügen, Rasiermesser Ansicht. Und dann wollen wir Vorlagen erstellen. Und das Modell hier wäre die Create leave type VM, und dann gehen Sie voran und fügen Sie das hinzu. Sobald Sie also die Ansicht hinzugefügt haben und Sie die physische Datei erhalten, ist der Code, den wir hier schreiben müssen, zweifach. Also eins für den Get, wir brauchen keinen Code, weil wir nur das Formular laden, richtig? Also ist es bereits, es ist bereits dieses Formular erstellt, zu wissen, dass es relativ zu den Feldern sein sollte, die hier sind. Also haben wir das Feld für den Namen des fetalen für die Standardtage. Wir brauchen nichts anderes zu tun. Also, es sei denn, du hast etwas Besonderes, das ist in Ordnung. Aber auf der Grundstufe ist nichts anderes erforderlich. Aber auf Post, das ist, wo die Magie passieren muss. Was wir jetzt tun müssen, ist unser Gewicht, unser Aufruf an die Blatttyp-Operation. Und nun, bevor wir überhaupt dort sind, müssen wir sicherstellen, dass wir uns den richtigen Datentyp ansehen, richtig? Also werde ich dies erstellen Blatt zu VM aufrufen und Typ verlassen. Gehen Sie weiter und fügen Sie alle fehlenden Referenzen ein. Erstellen Sie also Leaf to VM Leaf Type. Wir werden versuchen, eine Antwort von dem Blatt zu erhalten, das Repository-Punkt Blatttyp erstellen. Und dann, wenn unsere Operation erfolgreich ist, können wir zum Index umleiten. In Ordnung, also sieh dir diesen Nullpunkt an. Wenn wir diesen Anruf machen, wenn es ein Erfolg war, dann können wir funktionieren, als wäre es ein Erfolg. Was passiert, wenn es gescheitert ist? Wenn es also fehlschlägt, möchten wir natürlich unsere Validierungsfehler zur Benutzeroberfläche hinzufügen. Also wären die Pfeile mit der Antwort zurückgekommen. Sie können also Modellzustände, Modellfehler, Antwort-Validierungsfehler sagen. Und am Ende von all dem, wir einfach die Ansicht zurück. Also werden wir es ändern einen Haken, um die Ansicht nicht zurückzugeben, hat eine Verwirrungtatsache Ich werde den Fang ändern, den Fang eine tatsächliche Ausnahme, und dann können wir diese Ausnahme hinzufügen. Das liegt also in Ihrem Ermessen. Dies hängt natürlich von der Erfahrung ab, die Ihr Benutzer haben soll, da Sie möglicherweise nicht unbedingt möchten, dass sie die Details dieser Ausnahme sehen. Sie könnten wahrscheinlich einfach etwas einfügen, das besagt, dass etwas schief gelaufen ist Wenden Sie sich bitte an Ihren Administrator. Am Ende dieses Vorgangs möchten Sie jedoch die Ansicht zurückgeben. Und Sie können sogar die Blatttypdaten zurücksetzen, die gerade übermittelt wurden. Um die Ansicht, so dass es hat, was für den Benutzer angezeigt werden. Also lassen Sie uns das für einen Spin Art nehmen, damit wir die Anwendung ausführen können, springen Sie zu unserem Erstellen. Und ich werde mitfühlend mit der Standardnummer dieser Sten erstellen. Nun, sagen wir, ich habe einen Fehler gemacht und ich habe zu viele Nullen eingegeben. Und dann klicke ich auf Erstellen. Sie werden hier sehen, dass wir unsere Validierungsnachricht zurückerhalten. Und ich bin sicher, dass diese Nachricht sehr vertraut aussieht. Ich habe diese Nachricht nicht eingegeben, seit ich diese Benutzeroberfläche erstellt habe. Dies kommt direkt von der API. So ist dies nur, um Ihnen zu zeigen, wie die Informationen von der API reiste und wie wir an den Benutzer aufgeteilt werden könnten, dass die APIC, Dies ist illegal. Jetzt haben Sie zwei Möglichkeiten, wenn es um die Validierung geht. Sie können sich auf die API für alle Ihre Validierung und Ihre Nachrichten verlassen und so weiter. Aber dann ist die Sache, dass Sie bei einer API pro Aufruf berechnet werden. In dieser Situation, in der Sie wahrscheinlich auf einer API aufbauen, dass Sie nicht zu viel Traffic wünschen oder die API-Benutzer sagen, dass Sie bei zu viel Traffic oder Ihrem begrenzten oder etwas getan haben. Nun, Sie könnten die Dokumentation von der API verwenden und die Validierung von der Client-Seite erzwingen. Diese Nachricht kommt also direkt von der API. Sicher. Was dann bedeutet, dass ein API-Aufruf durchgeführt wurde, ein Prozess wurde durchgeführt, und es schoss mit dieser Nachricht. All das hätte vermieden werden können, wenn ich die Dokumentation als Clientanwendungsentwickler durchgelesen und meine eigenen Validierungsregeln von der Clientseite einrichtete. Dann würde dies nie einmal zum API-Aufruf kommen , bis dies von den Clientstandards gültig ist. Jetzt gibt es Mikrofone. Basierend auf Ihrer Intuition müssen Sie es auf die eine oder andere Weise tun. Aber vorerst lassen wir die API die Validierung durchführen. Und dann denke ich, dass es immer gut ist, eine Validierung in der API zu erstellen, denn das ist die letzte Verteidigungslinie vor, oder zumindest in den Hunderten eher, das ist die letzte Verteidigungslinie, bevor es die Datenbank bekommt. Also genau dort möchten Sie sicherstellen, dass nur gültige Sachen die Datenbank erhalten. Sie könnten jedoch Ihre API-Verbraucher dazu ermutigen, die Validierungsregeln zu befolgen. So Verbrennung bei der Standardnummer dieser 10 con, weiterhin mit der Schöpfung und schauen Sie sich das an. Wir haben eine brandneue Blatttypen, so dass die Erstellung funktionierte und dann eine geladene, neu geladene Index-Seite und wir sind wieder hier. Mach den Ausweis nicht aus. Einige Experimente gingen weiter. Buck in beiden zumindest sind wir zuversichtlich, dass dies funktioniert. Jemand kam zurück und sagte, dass mitfühlend 15 Tage dauern sollten. Und alles, was wir brauchen, um weiterzumachen und zu bearbeiten. Und der erste Schritt besteht darin, die Ansicht tatsächlich zu erstellen. Also direkt bei der Ansichtsbearbeitung anzeigen. Und wir wissen, dass wir die Bearbeitung und die Blatttyp-VM verwenden. Und dann, wenn Sie all das an Ort und Stelle haben, können Sie voran gehen und hinzufügen. Und dann in der Bearbeitung, die Sie bemerken, wie bei create, haben wir zwei Methoden. Wir haben die Post und wir haben die bekommen, wissen die Get. Es bedeutet, dass es das erforderliche erhalten muss, um bearbeitet zu werden. Nun, wie bekommen wir diese Platte? Wir wissen bereits, wie man eine Liste von Datensätzen bekommt. Wir haben uns noch einen Datensatz angesehen, aber was auch immer cool wir das Recht haben, den einen Datensatz hier zu bekommen, ist so ziemlich das gleiche cool, um schreiben zu müssen, um den einen Datensatz hier zu bekommen. Also, was wir tun werden, ist sagen, var Modell ist gleich 08 Blatttyp Repository dot bekommen Blatttyp Details. Details würden also alle Felder aufrufen, die für einen Bearbeitungsvorgang benötigt werden. Die ID, die, wissen Sie, die Felder alle Felder, der Name der Namen der Felder entziehen Marino, aber wir erhalten alle Details für den Blatttyp, der er gerade bearbeitet wird, dann sind wir die Ansicht mit diesen Daten zurückgeben. Also, während ich dieses Jahr für die Bearbeitungen getan habe, werde ich es wirklich einfach wieder für die Details tun, weil es das Gleiche ist. Details. Wir kriegen die Details. Wir kommen zur ID, geben sie weiter, und dann geben wir die Ansicht mit diesen Daten zurück. In Ordnung, also gehen wir weiter und machen das, bearbeiten für das Get. Und dann für den Beitrag wird ein bisschen ähnlich wie unsere Create aussehen , außer unsere Parameter sollten die int ID haben und Typ VM verlassen. In Ordnung, also ID Blatt Typ VM und sie versuchten , eine Antwort von unserem Update-Blatt-Typ zu bekommen. Und dann übergeben wir die ID und das zu bearbeitende Objekt. Und wenn es erfolgreich war, kehrten wir zum Index zurück. Ansonsten haben wir im Grunde nur Daisy Chain und alle Validierungsfehler, genau wie wir es mit dem Create getan haben. Und dann geben wir die Ansicht mit den Daten zurück, die übermittelt wurden. Also lassen Sie uns den Bearbeitungsvorgang starten und aus dem Bus sehen Sie, dass es einige Gebühren gibt, die wir nicht brauchen. Zum Beispiel müssen wir definitiv nicht die ID auf diese Weise anzeigen, in einer additiven Art und Weise für den Benutzer Das wird nicht einmal funktionieren. Oder API würde das ganz ablehnen. Die Datenbank würde ablehnen, um den Namen zu verteilen. Standardanzahl von Tagen. Das ist alles, was wir gesagt haben. Wir mussten die 15 ändern und ich bin nur neugierig zu sehen, was genau passieren wird, wenn ich dies versuche, wenn ich auf Speichern klicke, Alles klar, also bekomme ich diese Mrs. von Wert kann nicht null sein. Der Wert darf nicht null sein. Ok? Lassen Sie mich das auf 10 ändern und klicken Sie auf Speichern. Alles klar, so hat das aber funktioniert. Lassen Sie mich nochmals aufgreifen, was diese Botschaft bedeutete. Wenn die Daten ungültig sind. Denken Sie daran, dass unser Handler, der sich mit dem Update beschäftigt, richtig? Nein, es war oder wurde zumindest ursprünglich entwickelt, um die Validierungsausnahme auszulösen, wenn die Daten ungültig waren. Also, zurück zu diesem Handler zu springen, macht IQ und sehen, was ich meinte. Wir haben nichts zurückgebracht. Es war nur die Einheit oder an der wir erklärt haben, war nur etwas zu sagen. Alles ist in Ordnung. Aber dann, als das Validierungsergebnis ungültig war, haben wir eine neue Validierungsausnahme ausgelöst. Jetzt wurde diese Validierungsausnahme nicht behandelt. Wir haben kein echtes Zitat geschrieben, um zu behandeln, was passiert, wenn unser Handler eine Ausnahme auslöst, halten Sie die API damit befasst und wie alles andere herunterkommt. Also zwischen dem Handler, der die Ausnahme auslöst, der AICPA und der automatischen globalen Fehlerbehandlung, um zu wissen, welche Art von Antworten in Buck. Und dann ist der Service Grant nicht in der Lage zu erkennen, welche Art von Antwort das ist, dann bekommen wir diese Art von Fehler. Technisch gesehen würden Sie nicht unbedingt alles, was Sie überhaupt nicht verwenden wollten, um einen Fehler wie diesen zu sehen. Dies ist tatsächlich der Fehler, der von diesem gesamten try catch zurückkommt und die Ausnahmemeldung in die Modellstatusüberprüfung zurückgeworfen wird. Du würdest es nicht unbedingt benutzen wollen, um das zu sehen. Aber später, wenn wir uns die globale Ausnahmebehandlung ansehen, wird sehen, wie wir besser oder besseres Feedback geben können, wenn Ausnahmen durch den Handler oder über die API den ganzen Weg zurück zur Benutzeroberfläche geworfen werden , ohne dass wir , um zu viele Szenarien zu kompensieren. Alles klar, aber für ein alles, was wir tatsächlich sehen, dass die Validierung zu einem gewissen Grad funktioniert , scheitert es, denn wenn ich einen Haltepunkt hier in diesen Handler setze und dann wieder auf Speichern klicke, Oh, Nüsse im Debug-Modus. Oder wir können das später tun, aber Sie können versuchen, dass ein Haltepunkt in den Handler setzt. Versuchen Sie das, sehen Sie, ob Sie sehen würden, dass es die Validierung nicht da ist. Entschuldigung, die Validierung ist falsch. Und dann wird es den Ausnahmebock werfen. Und wenn Sie Schritt durch und folgen Sie es auf der Linie, werden Sie sehen, warum all dies nur eine sehr vage Botschaft ist. Wir sehen jedoch, dass die Bearbeitung ordnungsgemäß funktioniert. Und der nächste Stopp weiter. Wir haben uns das Detail bereits angesehen, damit Sie die Detailansicht generieren können. Ich habe meine bereits, und Sie werden sehen, dass Sie zwischen dem Code, den wir gerade in den Controller gesetzt haben, und Sie die Ansicht generieren, die Details anzeigen können. Der nächste wäre also löschen. Kennen Sie für das Löschen normalerweise in einem Zweifachschritt in MVC-Anwendungen gespeichert, oder? Normalerweise erhalten Sie den Datensatz und zeigen ihn dem Benutzer wie in einer Detailansicht an und sagen: Sind Sie sicher, dass Sie diesen Datensatz entfernen möchten? Und dann würden sie ja sagen, und dann sendet es im Grunde ein Formular. Dies ist also ein sehr sicherer Weg oder der bessere Weg, dies zu tun. Lassen Sie es das Formular absenden. Also ein Port es durch die Anti-Fälschung Tolkien und es würde über diesen Löschvorgang übertragen. Nein, was ich tun würde, oder es gibt viele Möglichkeiten, dies anzugehen. Aber was ich mehrmals getan habe, ist, anstatt sowohl die gute als auch die Post zu verwenden, ich habe nur die Post, richtig? So sieht meine Löschmethode aus. Und wenn Sie es betrachten, Sie sehen, dass es sieht sehr ähnlich wie die, alles andere, dass der Editor und der Schöpfer andere. Also versuchen wir, wir bekommen die Antwort. Wenn es erfolgreich ist, leiten wir auf die Indexseite um und dann gebe ich nur eine Byte-Anfragen zurück. Also der Strand, die Anwendung würde sich nur fühlen, aber wir werden uns anschauen, wie man das später umgeht, wenn wir unsere Modifikationen für null betrachten, aber auf der Indexseite, was ich tun würde, ist, anstatt diesen Axon-Link zu haben, Ich würde diese in eine Farm einwickeln. Wieder einmal gibt es viele Möglichkeiten, dies zu tun, weil einige Leute die Form haben, die durch und durch. Einige Benutzer haben ein Formular und verwenden JavaScript, um es anzuzeigen, wenn Sie auf die Schaltfläche Löschen klicken und dann die Farm löschen. Aber im Moment werde ich es einfach genug halten, um das durchzustehen. Dies ist also ein Lösch-Button. In Ordnung, also wollte ich dich nicht mit meinem Tippen langweilen, also ging ich voran und beendete die Spitze. So sieht unser Formular in etwa so aus, wobei Form Option ist, Löschen ist B Bindestrich, Route ID ist item.name. Verwenden Sie das am Zeichen für Benutzerfreundlichkeit. Und Methode ist gleich posten. Also zwischen diesen drei wird wissen, dass es die Post-Methode des Namens axon zielen und diese ID übergeben sollte . Dann weiß es Post und Löschen mit dieser ID. Und dann müssten wir in den Aufwärtspfad setzen. Also Button Typ senden und ich gab ihm die Klasse btn, btn gestrichelte Linie. Es sieht also aus wie die anderen beiden Links, also sieht es einheitlich aus. Niemand würde jemals wissen, dass es abbricht und es sei denn, sie gehen wirklich in den Code, um zu sehen. Und dann onclick kehren wir nach festem Fenster zurück. Sind Sie sicher, dass Sie löschen möchten? Und dann übergeben wir das Wort löschen. Werfen wir einen Blick darauf, was das macht. Alles klar, das ist es, was wir nicht ganz aufgereiht bekommen. Wir können das später beheben, aber der Punkt ist, dass wir diesen Löschknopf bekommen. Also habe ich hier eine sehr zufällige. Ich glaube, jemand hat versucht, das System zu täuschen und sie betreten das, also ist das in Ordnung. Lassen Sie es uns löschen. Möchten Sie diesen Datensatz wirklich löschen? Ok. Und dann siehst du, dass alles passiert ist. Diese Aufzeichnung ist nicht mehr da. Das bedeutet also, dass unser Löschvorgang erfolgreich funktioniert hat. Und damit haben wir soeben die Menge für unsere Blatttypen über unsere Benutzeroberfläche abgeschlossen. Also, wenn wir zurückkommen, schauen wir uns an, wie wir die anderen spezifischen Operationen mit den Urlaubsanfragen und den Urlaubsanweisungen abschließen können . 31. Json Web Token (JWT) Authentication zur API: Hey Leute, willkommen zurück. In dieser Lektion werden wir über Authentifizierung sprechen. Nun wäre der nächste logische Schritt nach oder Einstellung der Blatttyp-Benutzeroberfläche gewesen , die Blattzuweisung zu begleichen und Anforderungs-UIs zu verlassen. Aber dann ist der gesprochene Plan, dass wir Benutzer oder Mitarbeiter brauchen, um Urlaub oder Anfragen zuzuweisen. Die einzige Möglichkeit, dass der Mitarbeiter das System sieht, ist, wenn eingeloggt hat und wir wissen, wer sie sind, das ist seine Frau. Die Authentifizierung muss vor diesen beiden anderen Funktionen stehen. Also habe ich irgendwie vorangegangen und implementiert, weil es ziemlich viel Code zu schreiben gibt und ich will dich nicht langweilen damit, mir beim Tippen zuzusehen. Also natürlich werde ich es sehr langsam durchgehen, damit Sie alles pausieren, replizieren und erklären können , was da ist, was verstanden werden muss. Nein. Außerhalb davon habe ich Swagger, wo ich JWT-Authentifizierung implementiert habe, also habe ich es einfach so, dass Sie eine Vorschau davon erhalten können, was JWT-Authentifizierung wirklich ist, falls Sie damit nicht sehr vertraut sind. Also lassen Sie uns J, W und T sind kurz für JSON Web Token. Und was sie sind, ist wie ein Paket, nur eine flache Zeichenfolge, die codiert ist. Aber innerhalb dieser codierten Zeichenfolge sind, was Sie Bits von Informationen nennen sind Ansprüche, die den D-Akkord erlauben und wissen, wer der Benutzer ist. Kein JWT wird in der API-Bruderschaft häufig als Standard für die Sicherheit verwendet , da es eine zustandslose Authentifizierung ermöglicht. Das heißt, wenn Sie sich anmelden, Sie sich nicht wirklich bei einer API-Schicht an, die auf die API zugreift. Aber wenn es viel Knochen oder geschützt ist und Sie sich auf der API authentifizieren und sie identifizieren im Grunde, wer Sie sind und senden Sie dieses Token mit allen Informationen darüber, wer Sie sind. So muss die Client-Anwendung jetzt jederzeit sehen, wenn ich die Client-Anwendung verwende und ich Daten von der API anfordere, sie muss dieses Token mit meinen Informationen enthalten , damit jedes Mal, wenn die API aufgerufen wird, wenn sie sieht dieses Token, es wird es dekodieren, überprüfen, ob diese Person gültig ist und dann in der Lage sein, auf der Anfrage auszuführen. Also nur eine kurze Demonstration hier, ich werde versuchen, mich anzumelden. Also habe ich bereits Swagger geändert, ich habe die API bereits mit den Anmelde- und Registrierungsendpunkten geändert und wir werden das durchgehen. Aber ich habe auch einige Beispielbenutzer eingefügt. Und ich werde nur voran gehen und zeigen, wie das Token aussieht. Also führe ich eine Anmeldeanfrage mit einem meiner Benutzer aus. Und Sie sehen hier, dass es eine 200 mit dieser Token-Antwort zurückgibt, richtig? Also bekomme ich die ID des Benutzers, den Benutzernamen, die E-Mail. Und das ist JWT oder Token, richtig? Dies ist also im Grunde ein Fahrzeug mit allen Informationen, die benötigt werden, um mich zu identifizieren. Also, nur um Ihnen zu zeigen, was in diesem Token kommt, werde ich zu JWT dot IO springen, das ein cooles kostenloses Tool ist, mit dem Sie einfach Ihre Tolkien hier einfügen können. Es ist codierte Form und dann rechts wird es im Wesentlichen alles, was in diesem Token ist. Betreff, das ist die E-Mail-Adresse, GTI, das ist die JWT-ID. Ja, die E-Mail, Sie haben, die Benutzer-ID, die Rollen, die den Zeitstempel erkunden, der Aussteller und das Publikum. So können Sie mehr Dinge hineinlegen. Dies sind nur grundlegende Dinge, die dieses Token, das wir generieren, haben wird. Aber in Zukunft können Sie mehr Dinge einfügen und alle Informationen einfügen, die Sie für notwendig halten, damit Ihre Anwendung oder Ihre API funktioniert. Lassen Sie uns jetzt in unserer Code-Kunst beginnen. Also erstens werde ich Ihre Aufmerksamkeit auf, und ich werde nur alles zusammenbrechen, was nicht unbedingt notwendig ist, um das Gespräch zur Hand, so dass es weniger verwirrend ist. In unserem Anwendungsprojekt möchten Sie also einen neuen Ordner im Models-Ordner namens identity hinzufügen. Wissen Sie, wenn Sie diesen Ordner hinzufügen, der besagt, dass ich die E-Mail- und E-Mail-Einstellungen in einen Ordner für sich selbst legen sollte , aber wir können das später tun. Legen Sie sie in einen Ordner namens E-Mail oder Mail, so etwas. Aber für eine alle Modelle Identität und dann haben wir diese neuen Dateien. Also haben wir Auth Anfrage, die im Grunde nur E-Mail und Passwort ist. Wir haben gerade gesehen, dass wir, wenn wir uns über Swagger einloggen , die E-Mail eingegeben, das Passwort eingegeben und dann senden wir es. Das ist also, wofür die Authentifizierungsanfrage ist. Auth Antwort ist, was wir Buck durch Swagger, die ID, den Benutzernamen, die E-Mail und die Token-Zeichenfolge bekommen haben. In Ordnung, die JWT-Einstellungen, dies muss tun, es ist ähnlich wie die E-Mail-Einstellungen. Denken Sie daran, dass wir die E-Mail-Einstellungen des Teils der Up settings.js ON-Datei möchten , der uns alle für die E-Mail erforderlichen Einstellungen gegeben hat. Nun, das wird mit den JWT-Einstellungen passieren. Wir werden also ein Schlüsselproblem oder eine Zielgruppe und eine Dauer in Minuten haben, die alle in der UP-Einstellungsdatei in unserer API referenziert werden. Jetzt wie alle, die wir die Authentifizierungsanfrage haben, werden wir die Registrierungsanfrage haben. So oft ist kurz für die Authentifizierung, ich habe es nur gekürzt, aber Sie können explizit sein und Authentifizierung sagen. Registrierungsanforderung erfordert jedoch den Vornamen, den Nachnamen, die E-Mail-Adresse, den Benutzernamen sowie das Passwort. Jeder, der sich auf der Spitze registriert und der neue Mitarbeiter, der in das Unternehmen kommt, wird es ihnen sagen, Sie noch weiter rühren können. Sie müssen diese Informationen angeben. Und dann wird die Umverteilung Antwort wirklich nur mit der Benutzer-ID zurückschieben. Nachdem sich diese Person dort im System registriert hat, senden wir einfach die Benutzer-ID. Das ist alles, was nötig ist. Nein, außerhalb davon wollen wir auch einen neuen Ordner in unserem Vertragsordner, und ich nenne es Identität. Und wir wollen, dass ich den Dienst auth. Also werden wir einen neuen Dienst haben, wo wir Aufgabe Autor Antwort Login haben. Und es nimmt dieses Anforderungsobjekt der Auth Anfrage. Und dann haben wir eine für den Vertrieb, die uns die Antwort auf die Registrierung gibt. Und es hat eine Umverteilung Quest. Und das ist wirklich alles, was für die Anwendung benötigt wird. So können Sie voran gehen und überprüfen, wenn Sie müssen. Natürlich sollten Sie während des Vorgangs anhalten, um sicherzustellen, dass Sie alle diese Dateien und die erforderlichen Felder erhalten. Beachten Sie die Validierungsattribute, die sich auf der Registrierungsanforderung befinden , da wir sicherstellen möchten , dass wir Mindeststandards erfüllen. Auch unsere nächste Aufgabe wird es uns nicht geben, ein brandneues Projekt zum IKT-Infrastrukturordner namens Identity Art hinzuzufügen . Also HR-Management-Punkt identifiziert den Namen, und wir würden wollen, dass dieser ein Punkt darin ist, fünf. Also werde ich das erklären. Ja, wir verwenden dotnet Standard für die meisten Klassenbibliotheken. Aber in diesem Fall werden wir bestimmte Bibliotheken benötigen , die einfach nicht mit einer dominanten Standardbibliothek arbeiten können. Also wollen wir dotnet fire, so dass wir 0 Kompatibilitätsprobleme haben. Und natürlich würde dies auch in zukünftigen Versionen davon weitergehen. So können Sie voran gehen und das neue Projekt hinzufügen. Ich habe es schon hier. Und in diesem neuen Projekt werden wir ein paar neue Ordner haben. Wir werden Konfigurationen, Migrationen, Modelle und Services haben . Wir haben neue Dateien, in denen wir die Identity Services Umverteilung haben. Wir sind damit vertraut, wo wir von dieser Registrierungsdatei sitzen , die von der API aufgerufen werden soll. Und wir haben auch unseren eigenen DB-Kontext. Also werde ich mit einem DB-Kontext beginnen, weil dies wahrscheinlich der einfachste ist. Im DB-Kontext haben wir also öffentliche Klasse verlassen Management-ID, Identität, DVI-Kontexte, die vom Identitäts-DB-Kontext erben. Beachten Sie hier, dass wir den Identitäts-DB-Kontext eingeben. Also hätte ich das tun können, aber ich habe eine spezielle Override-Klasse für meine Benutzer. Im Allgemeinen hat der Identitätsbenutzer keine zusätzlichen Gebühren wie Vorname und Nachname. Also habe ich diese Anwendungsbenutzerklasse, die ich im Models-Ordner erstellt habe. Und es erbt von Identitätsbenutzer. Also dann hat es zwei Felder. Vorname, Nachname. In Ihrer Situation benötigen Sie möglicherweise weitere Informationen zu diesen Vornamen, Nachnamen und E-Mails. Und so wollen Sie vielleicht Geburtsdatum, Sie wollen andere Felder. Sie können alle diese direkt hier hinzufügen. Solange Sie jedoch von Identitätsbenutzer-Anwendung erben, kann der Benutzer verwendet werden, um Identitätsbenutzer und benutzerbezogene Vorgänge zu ersetzen. Diese geben Ihnen Zugang zu allen notwendigen Feldern. also zurück zum DB-Kontext springen, haben wir die gleiche Art von Konstruktor, den Sie von unserem vorherigen DB-Kontext gesehen hätten, wo wir die DB-Kontextoptionen übernehmen und das wird Passah über die API Projekt in der Aufregung wieder. Und dann haben wir das auf Modell erstellen. Also diesmal mache ich das nicht, bekommt Montage. Ich rufe die Bienen auf Modellierung an. Und dann nenne ich sie eins nach dem anderen. In der Praktikabilität ist wirklich nicht einmal wichtig. Also lasst uns einfach weitermachen. So haben wir die Regelkonfiguration, die Benutzerkonfiguration und Benutzerrollenkonfiguration. Hier seete ich diese Datenbits, wenn ich diese Datenbank generiere. Also denken Sie daran, dass ich sagte, dass Benutzer vor generiert. Wenn wir also zum Konfigurationsordner gehen, sehen Sie die Rollenkonfiguration, in der ich Regelkonfiguration habe, die von der I-Entitätstyp-Konfigurationsidentitätsrolle erbt wird. Jetzt ist dieser so eingerichtet, dass er neue Regeln konfiguriert. Wir haben die ID, den Namen der Regel und normalisierte Namen-ID. Dies muss nur gut sein, damit Sie gehen und unseren zufälligen guten Dino bekommen können, generieren Sie einen online, es ist in Ordnung. Du kannst es dort benutzen. Du musst nicht dasselbe benutzen. Ich habe gekauft. Die müssen gut sein. Unsere Identitätstabellen verwenden also keine Ganzzahlen als ihre IDs. Nachdem Sie mit den Rollen fertig sind, sollten Sie sich um die Benutzer kümmern. Also Benutzer, es gibt ein bisschen mehr, aber es ist wirklich nur ein bisschen mehr, weil es mehr zu füllen gibt, aber es ist praktisch das gleiche Konzept, Benutzerkonfiguration, die von einer Entitätstypkonfiguration relativ erbt an den Anwendungsbenutzer. Und dann in unserer Konfigurationsmethode, wir haben var Hampshire ist gleich neues Passwort Hampshire, relevant relativ, sorry für Anwendung Benutzer. Dies wird also verwendet, um das Passwort zu hash. So füllen wir die Anwendung Benutzer wieder ein gutes, wir geben diesem die E-Mail und E-Mail und normalisierte E-Mail und Benutzername, unnormalisierte Benutzername, sie sind alle gleich. Der einzige Unterschied besteht darin, dass die normalisierten Versionen alle Großbuchstaben haben. Wenn Sie mit Identitätsbenutzer vertraut sind, dann werde ich nicht, ich möchte Sie nicht langweilen, aber Sie sehen irgendwie, dass ich alle Felder entsprechend ausfülle. Und dann für den Passwort-Hash verwende ich HobShare, um das Kennwort null für den ersten Parameter zu hash. Wir müssen den Anwendungsbenutzer nicht übergeben. Offensichtlich können wir das nicht, weil wir nur einen erschaffen. Aber wir werden das Passwort hash, richtig? Also verwende ich nur mein spezielles Standardpasswort, das normalerweise die Mindestanforderungen erfüllt , um unseren Benutzer in der Identität zu erstellen. Also haben wir das für den Admin und dann haben wir einen anderen für einen normalen Benutzer. Also, nachdem wir unsere beiden Benutzer unter zwei Regeln haben, habe ich Benutzer oder Konfiguration, was ziemlich viel ist, dass ich Entitätstyp Konfiguration bei Entitätsbenutzer-Rolle. Und dann übergeben Sie diese Eingabe für eine Zeichenfolge. Sehr wichtig. Und dann haben wir zwei neue Identitätsbenutzerrollen. Wir haben die Rollen-ID auf die Benutzer-ID, Regel-ID auf die Benutzer-ID. Das ist also eine sehende Rolle, ich denke, dies ist die Mitarbeiterrolle für den Benutzer, der angeblich der Mitarbeiter und dann die Rollen-ID zur Benutzer-ID war . Also, weil diese Art von passieren muss, damit wir die Regel brauchen wir verwenden müssen, sind alle bevor der Benutzer oder wird generiert. Also denke ich, deshalb habe ich die Konfigurationen explizit so angegeben. Also würde es diesen Lauf nicht ausführen, der dann das läuft. Nun, bevor ich noch weiter gehe, wollte nur 0 Songs die Bibliotheken, die Sie in diesen Projekten benötigen , nur so dass Sie oben so viele rote Linien haben. Also wollen wir sicherstellen, dass wir eine Geschwindigkeit dotnet Core Authentication, JWT Bearer, wir wollen eine Kernidentität, Identität Entity Framework, Core Entity Framework, Core dot SQL, die Tools, die Erweiterungen für die Konfigurationen Newton Punkt JSON und system.out.print Stadtmodell, Tolkiens JWT. Daher haben Sie wahrscheinlich bereits einige davon aufgenommen, da beim Einrichten des DB-Kontextes und einiger anderer Dateien Sie beim Einrichten des DB-Kontextes und einiger anderer Dateienaufgefordert wurden, bestimmte Bibliotheken zu benötigen. Also, wenn Sie das bereits haben, ist das in Ordnung, aber das sind die Bibliotheken, die Sie insgesamt benötigen. Während Sie weitergehen, können Sie einfach die fehlenden Anweisungen und Referenzen entsprechend einschließen . Lassen Sie uns also zur Implementierung unseres Auth Service springen. Also haben wir den Authentifizierungsdienst im Ordner Verträge. Jetzt haben wir die Implementierung. Wir sind an die Wirbelsäule gewöhnt. In Ordnung, also haben wir drei Felder sind, nun, fangen wir mit dem Konstruktor an und wie wir den Benutzer-Manager injizieren. Wir injizieren den Anmeldemanager und wir suchen nach Optionen für den Abschnitt namens JWTs-Einstellungen. So können Sie einfach voran gehen und diese drei Felder erstellen. Und dann haben wir in unseren Implementierungen Login und registrieren, und wir haben ein paar private Methoden, aber wir werden sie einfach einzeln durchgehen. Also in unserem Login, wo die Authentifizierungsanfrage genommen wird, so dass sie unvergesslich sind, dass dies tatsächlich von der API aufgerufen wird. Also, wenn jemand den Anmelde-Endpunkt trifft oder wenn ich den Anmelde-Endpunkt trage, wissen Sie, dass die API wirklich einfach diese Methode aufruft, die dann die Prüfungen durchführte und die Antwortkunst zurückgab. Also versuchen wir, den Benutzer zu bekommen, wenn der Benutzer nicht existieren muss, werfen wir eine neue Ausnahme, also verwenden wir hier später Ausnahmen, werden wir uns die richtige Ausnahmebehandlung, globale Ausnahmebehandlung für die API ansehen . Aber für jetzt werden wir nur die Ausnahmen verwenden und wir werden verfeinern, wie wir weitergehen. Also, wenn der Benutzer nicht gefunden wird, werfen wir eine Ausnahme, konnte diesen Benutzer nicht finden. Wenn der Benutzer Telefon ist, ist das in Ordnung. Aber dann haben wir versucht, sie anzumelden. Wenn sie nicht in gespeichert werden konnten, ist das nur eine weitere Ausnahme. Wenn sie alle Schecks bestehen, wäre das nächste, wenn wir ihre Tolkien generieren. Und da kommt diese private Methode ins Spiel, Generate Token. Also werde ich einfach zu dieser Methode springen, damit du genau sehen kannst, worum es bei dieser ganzen Tolkien-Generation geht. Also werden wir JWT-Sicherheitstoolkit zurückgeben, das in der Bibliothek für Identitätsmodell Tolkiens JWT kommt , richtig? So können Sie, wie ich bereits sagte, alle using-Anweisungen einschließen, sobald Sie Ihr Spinnen kaum haben. Visual Studio-Eingabeaufforderung. Heute müssen Sie die Effektbibliothek referenzieren. Also generieren wir die Tolkien oder wir analysieren den Anwendungsbenutzer, der angerufen wurde. In Ordnung, also war der Benutzer hier gefallen und konnte sich anmelden. Also übergeben wir diesen Benutzer. Wissen Sie, wir bekommen die Ansprüche. So können Ansprüche in der Datenbank gespeichert werden. Spiele, wieder, sind Bits von Informationen über den Benutzer. Sie können im Grunde alles speichern, da ich den Benutzer in ein wenig Informationen säubere , die Sie für die Ausführung Ihrer Anwendung benötigen Sie können sie zu den Benutzerschreien hinzufügen. Das ist außerhalb des Geltungsbereichs dieses Kurses, aber ich gebe Ihnen nur eine Vorstellung davon, was ein Anspruch wirklich ist. Es sind also keine Informationen über den Benutzer in der Datenbank. Lass es uns rollen. Wir wollen alle Regeln, weil ein Benutzer mehrere Rosa-Benutzer möglicherweise ein Mitarbeiter und ein Administrator sein könnte. Wie wenn ich ein Vorgesetzter bin, muss ich vielleicht ein Supervisor unten auch ein Mitarbeiter sein , damit ich Urlaubsanträge genehmigen kann. Vielleicht kann ich auch Urlaubsanfragen stellen, weil ich beide recht habe, So Rollen können mehrere Rollen für unseren Benutzer haben, bekommt alle Regeln. Dann werden wir jetzt einfach eine neue Liste von Ansprüchen erstellen. Und dann werden wir alle Regeln zur Anspruchsliste hinzufügen. Also sehen Sie, wir fügen nur neuen Anspruch namens Regeln zu Rollen hinzu, gibt es, lassen Sie mich diese magische Zeichenfolge loswerden, weil es tatsächlich eine Konstante gibt , die wir verwenden können, um sicherzustellen, dass wir den Warenkorb-Regeltyp Nino zu Vermeiden Sie Tippfehler, die wir bereits besprochen haben, warum wir keine magischen Strings wollen , oder? So kann ich die Anspruchstypen Punkt Rolle hinzufügen und beanspruchte Typen ist nur eine Konstante, die verschiedene Arten von Ansprüchen hat, die in erster Linie überall verwendet werden. In Ordnung, so können Sie immer Ihren eigenen Namen für sauber geben, aber dann gibt es bestimmte Standardnamen, die Sie immer suchen können und Sie können einfach durchschauen und sehen, welcher relevant ist. Aber in diesem Fall fügen wir Rollen hinzu. Also werde ich den Anspruchstyp für Rolle verwenden. Ordnung, dann werde ich eine weitere IRI von Ansprüchen aufbauen , bei denen ich sehe, dass Nucleon unserem neuen Anspruch entspricht, ist JWT registrierte beanspruchte Namen. Sie haben also Typen im Vergleich zu JWT registrierten Ansprüchen beansprucht. Also hat JWT Ansprüche so ziemlich registriert. Dies sind JWT-spezifische Ansprüche, die im Allgemeinen für Anwendungen verwendet werden. In Ordnung. Das sind also direkte DWT-Standards im Vergleich zu Cremetypen, die nicht unbedingt JWT-verwandt sind, was diese Benutzer verwandt haben. So können Sie sie kombinieren, weil sie alle auf den gleichen Anspruchstyp fallen. Wir haben also die Rollen und fügen DWT registrierte saubere Namen hinzu. Seife. Seife ist kurz für Thema. Ordnung? Und das ist im Allgemeinen, die Benutzer, der Benutzername oder ihre E-Mail, was auch immer einzigartig ist. Sie sehen GTA, was normalerweise nur diese gute Zeichenfolge ist, und dann die E-Mail, die selbsterklärend ist. Dann füge ich hier meinen eigenen Anspruch hinzu, wo ich die UID oder Benutzer-ID aufrufe, die der tatsächliche ID-Wert aus der Datenbank ist. So sehen Sie, dass Sie Ihre Ansprüche aufbauen können. Sie können so viele Ansprüche eingeben, Sie können Ihre benutzerdefinierten Namen eingeben, wenn Sie möchten. Aber selbst wenn ich hier eine magische Zeichenfolge habe, würde ich vorschlagen, dass, wenn Sie mehrere benutzerdefinierte Ansprüche haben, die Sie hinzufügen müssen, nicht die magischen Strings hinzufügen, sie in eine andere Konstante setzen. Klassenkameraden ist, wie Sie die Konstanten hier sehen und sie dann entsprechend referenzieren. Sie hätten also Ihre Konstante wie benutzerdefinierte saubere Typen, Punkt-Benutzer-ID, so etwas. Und er WER, nachdem wir diesen Bereich gebaut haben, werden wir nur die Vereinigung der Benutzer behauptet aus der Datenbank und den Rollenansprüchen, und dann ist alles jetzt in diesem IRI. also ein bisschen mehr nach unten gehen, müssen wir unseren Signaturschlüssel codieren. Wenn wir also zu den JWT-Einstellungen kommen, werden Sie sehen, dass es einen Schlüssel gibt, der für Ihre Anwendung eindeutig wäre. Und es gibt viele Möglichkeiten, die Benutzer verwenden, um den Schlüssel in dieser Einstellung zu speichern. Wir werden nur settings.js, Sonne, einige Leute speichern es als Umgebungsvariable. Ich habe das in meinem ultimativen API-Entwicklungskurs gemacht. Sie werden also mehrere Möglichkeiten sehen, dies zu tun. Also alles, was wir hier wirklich tun, ist es zu unterschreiben. Und was wir auch tun wollen, ist es zu verwenden, um die Anmeldedaten zu bestimmen. In Ordnung, zwischen diesen beiden Zeilen haben wir die Anmeldedaten. Also dieses bisschen Code-Rauschen, wo wir tatsächlich unser Sicherheitstoken generieren. So ist JWT-Sicherheitstoken gleich dem neuen Sicherheitstoken-Aussteller. Und das kommt von unserem JWT Settings Publikum. Das kommt auch aus unseren Einstellungen und Behauptungen, die wir gerade an uns selbst gebaut haben, läuft ab. Wir konvertieren von Datum-Zeit wissen, wo das Hinzufügen der Minuten aus den JWT-Einstellungen kommen. Wieder mal. Und dann fügen wir die Anmeldedaten hinzu, die wir gerade hier mit diesem Signaturschlüssel bestimmt haben. Und dann geben wir das Tolkien zurück. Wenn wir also dieses Tolkien zurückgeben, sehen Sie viel, wenn es in dieser Methode getan wird. Nachdem wir das Tolkien gedreht haben, erstellen wir unsere Autorenantwort, die die Benutzer-ID hat, das Token, das wir gerade erstellt haben. Und notieren Sie den Akkord hier, neue JWT Sicherheitstoken Handler Punkt rechts Tolkien und JWT Sicherheit Tolkien und die E-Mail und den Benutzernamen, und dann geben wir diese Antwort zurück. Das war also die Antwort, die wir von Swagger mit der ID, dem Tolkien, der E-Mail und dem Benutzernamen bekommen haben. Also, jetzt, da wir all das schwere Heben zwischen den Diensten gemacht haben, und oder, wissen Sie, all diesen Code, der zu den Identitätsdiensten oder zu einer Distributionsdatei überspringt , in der wir die Identitätsdienste konfigurieren. So wie wir es in früheren Zeiten getan haben, werden wir die KI Service Collection und I Konfiguration benötigen. Und wenn wir nach unten gehen, werden wir die verschiedenen Abschnitte sehen. So konfigurieren Sie Dienste relativ zu JWT-Einstellungen. Wir suchen in der Konfiguration, um den Abschnitt namens JWT-Einstellungen zu erhalten. Wir fügen RDB-Kontexte hinzu, die wir damit vertraut sind. Sie könnten also diesen Code einfach kopieren, einfügen, einfach sicherstellen, dass Sie auf die richtige DB-Kontextdatei verweisen. Es ist also verlassen Management Identity DB-Kontexte, die wir gerade für dieses bestimmte Projekt erstellt haben. Und wir fügen SQL Server hinzu. Lassen Sie mich die Quote senken. Sie können sehen, dass es ein bisschen leichter ist. Optionen, die SQL Server verwenden, erhalten eine Verbindungszeichenfolge, und das nenne ich die Verbindungszeichenfolge verlassen Management Identity Verbindungszeichenfolge. Nun ist das coole daran, dass Sie tatsächlich zwei völlig unterschiedliche Datenspeicher haben können. Wenn Sie einen Datenspeicher für Ihre Anwendungen benötigen, der für Ihre Benutzer von einem Datenspeicher getrennt ist. Dann ist das, Es ist so einfach, sie zu trennen weil alles, was Sie brauchen, ist eine Verbindungszeichenfolge für eine Datenbank und eine andere für eine andere. Wir referenzieren die andere Verbindungszeichenfolge. Also werde ich tatsächlich diese Datenspeicher trennen und Sie werden das in ein paar Minuten in den App-Einstellungen sehen. Wenn Sie also für beide dieselbe Datenbank verwenden möchten, benötigen Sie nur die gleiche Verbindungszeichenfolge. Kein Trubel. Wir geben auch an, dass sich die Migrations-Assembly in der gleichen Assembly wie der DB-Kontext befindet, weshalb wir diesen Migrationsordner haben. Wir haben auch Dienste, die Identität hinzufügen, wobei wir sehen, dass Identität, die wir hinzufügen, Anwendungsbenutzer für die Identitätsbenutzerklasse und Identitätsrolle ist . Wir fügen das Framework hinzu, den Entity Framework-Store zu unserem DB-Kontext, der gerade oben initialisiert wurde. Und wir fügen Standard-Token-Anbieter hinzu. Dies fügt Token-Anbieter hinzu, die für das Zurücksetzen von Passwörtern G und Gmail verwenden, all diese Dinge. Alles klar, also alle, wenn Sie dieses Tool tun müssen, bestätigen, per E-Mail oder Passwort zurücksetzen, diese Art von Zeug. Diese Bibliothek, wir werden diese Tolkien-Anbieter für Sie erleichtern. Wir sind bei den Diensten und ich füge diese als vorübergehend hinzu weil wir jedes Mal einen neuen Authentifizierungsdienst wünschen, wenn eine Anfrage eingeht. Also ist es diesmal nicht umfassend. Es hat mir jedes Mal einen neuen gegeben. Und wir sind nur verbindlich oder, oder Abstraktion oder Implementierung. Und dann kommen wir zu den Diensten, die Authentifizierung hinzufügen. Also hier geben wir Optionen, wo wir Optionen haben nicht Standard-Authentifizierungsschema JWT Bier Standard Authentifizierungsschema und Standard Challenge Schema ist die gleiche Sache. In Ordnung, so sagen wir dem Authentifizierungsschema, JWT zu verwenden. Danach fügen wir die JWT-Bieroptionen hinzu, bei denen ich sehe, dass die Tolkien-Validierungsparameter als solche sind. In früheren Kursen, in denen ich durch WTI gegangen bin, war schmaler Bezirk, aber noch einmal bestimmt der Kontext Ihre Implementierung. Also für unsere Tolkien-Validierungsparameter muss ich unseren Signaturschlüssel, den Aussteller, das Publikum, die Lebensdauer, die Uhrschiefe überprüfen , was unsere Sets die Uhr erhält, wenn eine Validierungszeit angewendet wird. Also, relativ zu dem, wo Sie sind, wie wenden wir es an? Validierungszeit, Validierung der EC sorry, geteilter Aussteller ist in der Konfiguration für die JWT-Einstellungen Doppelpunkt Aussteller gefunden. Dies ist also eine schöne schnelle Möglichkeit, einen bestimmten Wert aus unserem Einstellungsbereich in einer App-Einstellungsdatei zu erhalten . In Ordnung, also holen wir den Aussteller und die Zielgruppe sowohl aus dem JWT-Einstellungsbereich der Konfiguration und dann unserem Signaturschlüssel des Ausstellers. Und wir sahen so etwas, bevor wir die symmetrischen Sicherheitsschlüssel signieren für diesen Schlüssel, der auch in den JWT-Einstellungen unter dem Namensschlüssel gefunden wird, dann geben wir die Dienste zurück. Ordnung, nicht das, aber jetzt, wo wir all das in unserer Identität getan haben, können wir es wissen, mit der API verdrahtet werden. Also in der API werde ich mit unserer App-Einstellungsdatei beginnen. Also noch einmal, wir haben zwei Verbindungszeichenfolgen. Ich habe zwei Verbindungszeichenfolgen. Du könntest einen haben, wenn du willst. Kein Problem. Aber ich habe eine namens HR verlassen Management DB, die gewohnt waren. Ich füge dann 14 hinzu, die Identität, die ich gerade an die quadratische Identität angehängt habe, oder? Es ist also wirklich nicht so groß, je nach Ihren geschäftlichen Anforderungen müssen Sie sie möglicherweise trennen. Ein Fall, wenn Sie sie trennen möchten, wäre, wenn wir mehrere Anwendungen haben , die denselben Benutzerspeicher verwenden. In dieser Situation möchten Sie möglicherweise eine eigenständige Datenbank ausschließlich für Benutzerinformationen. Und dann sind die verschiedenen Datenbanken relativ zu den verschiedenen Apps. Aber alle Ops könnten den einen Benutzerspeicher abonnieren und dieselbe Identitätsbibliothek verwenden , die ich gerade eingerichtet habe und die gleichen Verbindungszeichenfolgen abgewickelt haben. Jede Anwendung könnte es ganz einfach nutzen. Es wäre agnostisch, wer tatsächlich damit interagiert. Also haben wir unsere Verbindungszeichenfolge und später nicht in der Datei, ich habe den Abschnitt JWT-Einstellungen. Also hier habe ich nur einen Schlüssel. Noch einmal, dieser Schlüssel könnte alles sein, es könnte ein Wort sein, es könnte so etwas wie ein Passwort sein, aber es ist nicht etwas, das jemand leicht erraten soll weil dann Leute Ihre Tolkien täuschen könnten, wenn sie Ihren Schlüssel kennen. Deshalb habe ich gesagt, dass die Leute es manchmal nicht in den gegenteiligen Dingen aufbewahren. Sie speichern es als Umgebungsvariable oder als Anwendungsgeheimnis, etwas anderes. Aber vorerst lege ich es hier, weil es unsere Anwendung ist, aber Sie wissen, wie man es speichert. Mehr Sicherheit muss unser Emittent sein. Ich sehe nur unsere Lead-Management und das Publikum wäre HR verlassen Management-Benutzer. Und die Dauer beträgt 60 Minuten, was bedeutet, dass dieser Token genau eine Stunde lang gültig ist. Nach einer Stunde benötigen Sie einen neuen Token, Sie müssen sich erneut anmelden. Es liegt also in Ihrer Diskretion, dass Sie diesmal sitzen. Manche Leute würden es für Tage festlegen, hängt von Ihnen und Ihrer Sicherheitsrichtlinie ab. Jetzt springen wir zu den Kegel Controller im Doppelpunkt Controller Ich injiziere den Augenauth-Dienst. Und Sie können sehen, dass es ein wirklich einfacher Controller ist. Denk dran, dünner Gonzalez, das ist unser Ziel, richtig? Es gibt also eigentlich nichts, keine Logik, keine ernsthafte Operation hier. Wir implementieren nur Ergebnisse für Maßnahmen. Eine, die Autorenantwort zurückgibt obwohl eine, die zurückgibt, oder eine Verteilung auf Antwort. Und dann kehren wir so ziemlich einfach zurück. Okay, ich werde 18 das Ergebnis der Login-Anfrage. Wieder einmal, in unserem OSS-Dienst geschult, werfen wir Ausnahmen. Später schauen wir uns an, wie wir diese Ausnahmen messen und entsprechende Rücksendenachrichten haben, wenn unsere Client-Anwendung anruft. Aber im Moment ist das alles, was wir brauchen, um sich einzuloggen und zu registrieren. Und dann in unserer Startdatei, die das zweite bis letzte Bit ist, auf das wir wirklich achten müssen. Entsprechend haben wir ein paar Änderungen. Daher möchten wir, dass Sie unsere Identitätsdienste konfigurieren. Und um dies zu tun, müssen wir auf die Identitätsprojekte verweisen, richtig? Sie werden also aufgefordert, oder wenn Sie nicht aufgefordert werden, fügen Sie es zumindest als Projektabhängigkeit hinzu, wenn Sie die Chance erhalten, und dann steht Ihnen das zur Verfügung. Also, nachdem wir unsere Identitätsdienste und andere Änderungen konfiguriert haben , die ich darauf hinweisen möchte, ist zu swagger. Also habe ich dies in eine Methode geändert, die den Swagger konfigurieren wird , weil es wenige Dinge gibt, die anders sein werden. Wie Sie bemerken, war mein Fußball-Doc etwas anders die ersten paar Male, in denen wir es benutzt haben. Und das ist der Grund. Bevor wir also zu dieser Methode kommen, in der Konfiguration für die Middlewares möchten Sie in der Konfiguration für die Middlewares die Twees-Authentifizierung addieren und überprüfen, ob Sie Berechtigungen verwendet haben. Also wollen Sie sicherstellen, dass Sie diese beiden haben. Wenn nichts anderes. Innerhalb dieser Konfiguration ist alles, was Sie unverändert bleiben müssen. Kennen Sie die Änderungen am Swagger-Dokument, und dies ist nur die private Methode, die unten implementiert wurde. Wenn ich diese beiden zusammenbreche, siehst du das Fußballdock der Arabischen Liga. Es dauert, ich diene als Sammlung. Also in dem Methodenaufruf übergeben wir die Dienste und in diesem, Nein, wir erweitern, was nur die Dienste waren, die Fußball hatten, Jen. Also nein, wir erstellen eine Konfiguration auf Blut , wo wir AD-Sicherheitsdefinition für Träger sehen. Das bedeutet also, dass wir Swagger sagen, dass, wenn etwas autorisiert ist und wir zum Autorisierungs-Zitat einen Teil der API unquote bekommen. Was, wenn ein Endpunkt autorisiert ist, dann benötigen Sie ein Inhaber-Token. Das ist unser Sicherheitsschema für Tests, die den erforderlichen Endpunkt autorisieren. Wir geben ihm nur die kleine Beschreibung über die einige Verbiage Shuttle, den Benutzer, das ist, was Sie tun müssen. Autorisierung des Namens. In der Umkreisposition befindet sich die Kopfzeile. Was auch immer wir hineinlegen, was ein Bier ist, geht in die Kopfzeile der Anfrage. Und der Typ ist ein API-Schlüssel, und das Schema ist ein Spiegel. Alles klar, das ist also nur so schlitzender Swagger. Wissen Sie, dass, wenn ein Endpunkt autorisiert ist , noch einmal, erfordern ein Bier Tolkien, und das ist, wie es behandelt werden sollte. Dann fügen wir die Sicherheitsanforderungen hinzu, wo wir neue Öffnungen sehen. Eine offene API-Sicherheitsschema-Referenz-API, Open API-Referenztyp ist ein Referenztyp Sicherheitsschema namens bearer schema off to name bear. So werden Sie eine Menge der Dinge sehen, die sich wiederholen. Also gehen Sie einfach voran und fügen Sie diesen Abschnitt hinzu. Und dann haben wir den gleichen Swagger Doc-Abschnitt, in dem wir Version eins sagen. Und der Typ ist HR, verlassen Management, EPA und ein wenig Platz dort. In Ordnung. Das ist also so ziemlich es. Also, wenn ich zu autorisieren und lebhaft, so haben Sie gesehen, dass ich die API verwenden. Sie sahen mich authentifizieren, aber Sie sahen mich nicht autorisieren und testen. Das ist also alles, was Sie wirklich brauchen, um die API wissen zu lassen , dass sie alles in diesem Controller sperren sollte. Wenn Sie es nicht auf dem gesamten Controller möchten, können Sie es über die spezifischen Aktionen übertragen. Wenn Sie also die Blatttypen nicht benötigen, um sich anzumelden, dann ist das in Ordnung. Wenn das Erstellen der Blatttypen jedoch jemand sich anmelden musste und Sie es dann direkt über diesen Beitrag oder den PUT usw. ablegen Nein, wir sind fast fertig mit der Einrichtung unserer Identitätsdienste. Und an dieser Stelle müssen wir nur die Datenbank tatsächlich existieren lassen und sie mit den relevanten Daten aktualisieren lassen, richtig? Also gehe ich in die Package Manager-Konsole und stelle sicher, dass Ihr Startprojekt API ist und dass das Standardprojekt, auf das hier verwiesen wird, das Identitätsprojekt ist. Alles klar, der erste Befehl, den Sie ausführen müssen, ist die Anzeigenmigration für die neuen Identitäts-BB-Kontexte. Also werden wir sagen, fügen Sie Bindestrich Migration. Was haben wir Migrationsname ist, aber dann gebe ich an, welche Kontexte diese Spezifikation Sie möglicherweise einen Fehler sehen können, dass es mehrere Kontexte gibt und es nicht weiß, welche zu verwenden ist. Also, um unser eigenes zu bekommen, dass Sie nur niederländischen Kontext und den tatsächlichen Namen des Kontextes sagen. Sobald Sie dies tun, erhalten Sie diese Migrationsdatei generiert. Außerdem werden die zu erstellenden Tabellen sowie die neuen Daten für die Rollen, die Benutzer und die Benutzerrollenzuweisungen vordefiniert. Ordnung? Nachdem Sie das getan haben, möchten Sie eine Update-Datenbank durchführen. So wird die Datenbank in dem Sinne ähnlich aussehen, dass wir angeben müssen, welche Kontexte wir aktualisieren. Also sagen Sie einfach aktualisieren Dash-Datenbank, niederländischen Kontext und setzen Sie in diese Identität DVI-Kontexte. Und mit all dem nicht hättest du die Datenbank erstellt. Ich kann überspringen und Ihnen zeigen, dass HR Management Identity DB verlassen, mit allen Tabellen, die erstellt worden wären. Wieder einmal habe ich die Anwendungsdatenbank vom Benutzerspeicher getrennt. Ordnung, also lasst uns diese Autorisierung testen und dann können wir diese Aktivität ein für allemal beenden. Also werden wir sagen, autorisiert über die Get-Liste oder erhalten Liste der Blatttypen und Punkt. Und dann werden wir über zu Swagger springen und einloggen einige Login als einer der Meer, dass Benutzer haben die Tolkien. Und wenn ich dann den ganzen Weg nach unten scrolle, wird jemand , der nicht autorisiert ist, nur richtig. Schauen wir uns also die get by IDs an, damit ich sie in id1 aufteilen und ausführen kann. Und Sie sehen, ich bekomme meine Antwort, keine Authentifizierung erforderlich. Nun, wenn ich die Blatttypen testen wollte, kann auf das Vorhängeschloss klicken. Also lass mich einfach von vorne anfangen. Wenn das Vorhängeschloss wird es mir die Anweisungen geben, die wir angegeben haben. So heißt es, stellen Sie sicher, dass Sie Träger und Raum als Ihre Tolkien eingeben. So sieht es eigentlich so aus, als würde man über den Draht gehen, schreiben Sie das Wort Spiegel. Und das Tolkien, das ich gerade von der Antwort aus dem Login kopiert habe. Und wenn ich auf Autorisieren klicke, kann ich die Kleidung notieren. Soweit Fußball betroffen ist, alle Anfragen, die er senden wird, wenn wir auf Ausführen klicken, dieses Inhaber-Token in der Kopfzeile enthalten. Also, wenn ich an dieser Stelle auf Ausführen klicke, dann sehen wir unsere Antwort. Also lass es mich nochmal mit dem Barista versuchen. Wenn ich auf Abmelden klicke, löscht es den Bearer-Header und ich klicke auf Ausführen. Und ich bekomme das für einen, ich bin nicht autorisiert, ich bin nicht authentifiziert. Richtig? Dann lassen Sie es mich noch einmal versuchen. Der Potluck Wert ist das Wort Träger. Die Tolkien autorisieren, schließen, ausführen, und da gehen wir. Also haben wir unsere gesamte API gesichert, oder zumindest stellen wir die Fähigkeit, das EPI zu sichern und zukünftig zu sichern, natürlich können wir diese Art von Sicherheitsrichtlinien jetzt auf unsere Client-Anwendung replizieren. 32. Authentizität im Webprojekt: In Ordnung, also kommen wir von den Fersen, einige schwere Modifikations-Store-API zu tun , um die Authentifizierung und Autorisierung zu einem gewissen Grad zu erleichtern. Jetzt alles, was wir brauchen, um diese Bemühungen in unserer Benutzeroberfläche zu replizieren , wo wir in der Lage sein müssen, Benutzer anmelden zu können. Und basierend auf ihrer Rolle, sollten sie in der Lage sein, bestimmte Dinge nicht zu sehen. Also hier melde ich mich als Admin-Benutzer an und Sie können sehen, dass ich einige Änderungen an dem Menü vorgenommen habe , wo ich bestimmte Elemente sehen kann, die ich vorher nicht konnte. Also lassen Sie uns schauen, was getan wurde. Noch einmal, ich kann die Arbeit nicht schon erledigen und ich werde Sie durch sie führen, weil ich Sie nicht langweilen möchte, wenn Sie mir beim Tippen zusehen. Also Schritt Nummer eins, lassen Sie uns unseren Ende Swag generierten Code aktualisieren, weil wir es oder API ändern. Infolgedessen wurde unsere Dokumentation modifiziert. Daher benötigen wir einen neuen Satz von Code, um den aktuellen Zustand der API darzustellen. Also noch einmal, wir werden in Swag gehen oder Runtime ist um fünf fertig. Wir setzen unsere URL voraus und erstellen eine lokale Kopie. Und so ziemlich replizieren wir alle Einstellungen den gleichen Namespace. Wir stellen sicher, dass alle Optionen angekreuzt sind, injizieren, die Schnittstelle generieren und sicherstellen, dass Sie die Details und die Klassentypen generieren. Und wenn all das erledigt ist, stellen Sie sicher, dass der Dateipfad korrekt ist und dann regeneriert wird. Wissen Sie, das ist etwas, das wir mehrere Male auf einem wahrscheinlich tun sollte Ihnen dies früher gezeigt haben, aber Sie können tatsächlich zur Datei gehen und einfach diesen Arbeitsbereich speichern , so dass Sie nicht schwer, jedes Mal von Grund auf neu zu beginnen. In Ordnung, also werde ich das einfach retten. Und wenn wir zurückkommen, können wir es immer wieder öffnen und dann einfach innerhalb des Projekts speichern. Sie können es überall speichern. Das ist in Ordnung. Lassen Sie uns jedoch fortfahren und mit unserem neu generierten Code fortfahren, der wissen sollte, dass die Aufgaben oder die und, oder die Anforderungs- und Antwortobjekte für unsere Login-und Registeroperationen haben . In Ordnung, jetzt, da wir all das haben, lassen Sie uns unsere lokalen Authentifizierungsdienste einrichten. In unseren Verträgen werden wir eine neue Schnittstelle haben, ich Authentifizierungsdienst. Und wir werden drei Methoden haben. Eins zum Authentifizieren, eins zum Registrieren von 12 Logos. Dies könnte leicht als Login bezeichnet werden, spielt keine Rolle, aber das ist für die Anmeldung, dies ist für die Verteilung, und dies wäre gezwungen, sich abzumelden. Und natürlich für immer Verträge, gibt es eine Umsetzung. Also in den Diensten habe ich diese Implementierung in Form eines Authentifizierungsdienstes , der sowohl vom Basis-HTTP-Dienst als auch vom Vertrag erben wird. Jetzt ist ziemlich viel los in dieser Methode und ich werde Sie Schritt für Schritt wie gewohnt durch sie führen. Also zuerst muss ich meinen HTTP-Kontext-Accessor injizieren. Und ich werde ein privates Feld für den JWT-Sicherheitstoken-Handler haben , der einige dieser Klassen kennt und Sie hochladen. Ich habe diese Klasse tatsächlich von der API gesehen oder mit ihr beschäftigt, Sie benötigen zusätzliche Bibliotheken. Wenn Sie aufgefordert werden, die Bibliotheken zu installieren, machen Sie dies und fügen Sie die using-Anweisungen ein. In unserem Konstruktor injiziere ich, wie wir bereits gesehen haben, wie wir bereits gesehen haben,die Symbole, den lokalen Speicher und den HTTP-Kontext-Accessor , der hier initialisiert wird. Wir geben das auch an die BCE oder den Client weiter und den Speicher an die VCE. Wir initialisieren Handbücher, so dass diese Token-Handler nicht injiziert werden, aber wir initialisieren es zu einer neuen Instanz des JWT-Sicherheitstoken-Handlers. Wissen Sie für die Implementierungen, weil es natürlich nach dieser Vererbung wirklich die Implementierung benötigen würde. So können Sie voran gehen und generieren diese Methoden Stubs und lassen Sie uns wissen, schauen Sie zusammen, was in jedem gehen muss. Also für die Authentifizierung, nehmen E-Mail-Passwort und ich habe alles in einem Versuch fangen eingewickelt. Was wir versuchen, ist eine Authentifizierungsanfrage zu generieren. Also erhalten wir die E-Mail und den Parser von den Parametern. Und ich weiß nicht, ob ich Ihnen das schon einmal gezeigt habe, aber in dieser Karriere, in dieser neuesten Version von C sharp, können Sie tatsächlich ein neues Objekt initialisieren, indem nur sehen, dass der Datentyp Objektname gleich neu ist, und dann haben Sie einfach Haben Sie Ihre Werte, oder? Das ist alles, was ich da mache. Dann sehe ich die var Authentifizierungsantwort ist gleich, um den Clientaufruf zur Anmeldung asynchron zu warten , der in dieser Authentifizierungsanforderung übergeben wird. Nun, wenn der Anforderungspunkt Tolkien nicht gleich dem String Punkt ist leeren Server ohne das Anforderungsobjekt enthält ein paar Dinge. Es hat die ID des Benutzers, die, Ich denke, die E-Mail-Adresse zu anderen Dingen, kam ein paar Dinge dazu, was das einzige, was wir wirklich daran interessiert sind, ein Token ist , weil das alles ist, was die Anwendung verwenden muss, um dies zu sehen ist, wer der Benutzer ist. Wenn der Token also nicht leer ist, dann wollen wir den Tolkien-Inhalt bekommen. Ich sehe var Tolkien-Inhalt ist gleich dem Token-Handler, der hier oben initialisiert wurde. Lesen Sie JWT, Token. Und dann gehen wir an der Schnur vorbei. Dies ist also tatsächlich ein starker Typ namens JWT-Sicherheitstoken. In Ordnung, dann wollen wir die Ansprüche von den Tolkien. Denken Sie daran, die Informationen, die E-Mail, die ID, alles, was gesendet wurde, Bucky, und das Token, das uns sagt, wer dieser Benutzer ist, wir brauchen all das. Also werde ich nur die Ansprüche aus dem Token analysieren. Jetzt ist dies eine Methode, die ich Putin habe und es ist hier unten, wo es nur die Liste der Ansprüche zurückgibt. Also denken Sie daran, wenn wir das Werkzeug einrichten kann sich erinnern, wir kompilieren die Liste der Gliedmaßen und kompostieren es und legte es, codiert es und steckte es in Tolkien nirgends Decodierung, so dass wir die Liste der Ansprüche kennen. Also in dieser Methode sagen wir im Grunde var Behauptungen ist gleich Token-Inhalt dot Ansprüche Punkt zwei Listen. Dieses gesamte Token-Inhaltsobjekt ermöglicht es uns, die Ansprüche eher als eine Liste von Strings oder einer Liste von Ansprüchen zurückzubekommen . Und dann werden wir explizit hinzufügen. Der Name der Anspruchstypen ist Tolkien Punkt Themen. Vielleicht gab es irgendwelche, vielleicht gab es es keine. Ich mache es explizit. Ich zeige es dir nur, weil du vielleicht nicht weißt, was du manchmal wieder in Tolkien kommst. Also, wenn Sie explizit sein wollen, können Sie immer Ihre eigenen sauber mit Ihrem eigenen Namen hinzufügen, genau wie wir zuvor gesehen haben. Und Sie setzen in welchen Wert es haben sollte. Nachdem wir all das getan haben, geben wir die Liste der Ansprüche zurück. Alles klar, jetzt haben wir die Reinigungen. Ich muss einen Benutzer für meinen aktuellen Aufstieg erstellen. Also sehe ich var Benutzer gleich Ansprüche Prinzip und Träume Prinzipien werden eine neue Ansprüche Ed Entität mit den Behauptungen haben , die gerade aus den Tolkien genommen wurden. Und wir verwenden die Cookie-Authentifizierung. Sobald diese Person erstellt wird, speichern wir diesen Benutzerdatensatz oder die Sitzung dieses Benutzers, die Schriftart, dass es kein Benutzer derzeit im System als Cookie. So werden wir sehen, wie das später beim Start eingerichtet wird. Aber das ist es, was wir tun. Und dann werden wir eine Anmeldung machen, indem wir HDTP-Kontexte Accessors sehen. Dies ist also unsere wirklich coole Bibliothek für den Fall, dass Sie damit nicht sehr vertraut sind, mit der Sie tatsächlich auf den Kontext der HTTP-Anfragen zugreifen können. Alles passiert also, wenn ein Benutzer Daten anfordert oder Daten sendet, was auch immer er tut, alles geschieht im Kontext einer HTTP-Anfrage. Also verwendet diese Bibliothek tatsächlich direkten Zugriff auf diese aktuelle Anforderungspipeline und ermöglicht es uns, HTTP-Kontexte zu manipulieren und es ist injizierbar, so dass wir es nicht von den Steuerelementen aus tun müssen, kann von irgendwo anders sein. Also kann ich sagen, geben Sie mir den HTTP-Kontext, in dem wir uns befinden, und gehen Sie weiter und signieren Sie diesen Benutzer mit dem Cookie-Authentifizierungsschema. Und wir werden das Tolkien zur Verwahrung in einem lokalen Lager aufbewahren. Denken Sie also daran, dass wir den kostengünstigen Speicher haben, der von unserer Bearer-Token-Methode aufgerufen wird, wenn wir einen Anruf ausführen. Deshalb müssen wir es speichern, sobald Sie es bekommen haben, und dann werden wir nur wahr zurückkehren. Wenn die Person also authentifiziert ist, machen wir das alles. Ich kehre wahr zurück. Wenn wir falsch zurückgeben, können wir etwas anderes tun. Und das wirst du in ein paar Minuten sehen. Das ist also ziemlich genau das, was Authenticate tut. Und wenn es einen Fehler in diesem try-catch gab, dann gibt es nur false zurück. Es ist ein Fehler aufgetreten, oder? Das ist also authentifizieren. Und schauen wir uns das Register an, was wirklich viel einfacher ist. Wir werden nur diese Registrierungsanfragen auf der Grundlage aller Parameter formulieren , die übergeben worden wären. Und das hätte wirklich leicht ein Objekt sein können, aber das ist in Ordnung. Darauf können Sie später zurückgreifen, wenn wir die Registrierungsanfrage entsprechend erstellen. Und dann übergeben wir diesen registrierten Async-HTTP-Aufruf mit dieser Anfrage. Und dann, wenn wir MCI Benutzer-ID oder Problem flach erfolgreich erhalten, sonst war es nicht. Wissen Sie in unserem Logo, wir tun zwei Dinge wirklich waren nur die Speicherung von Tolkien-Werten, die da waren. Und wir melden uns auch ab und zerstören implizit jeden Benutzer. B sind Cookies, die während der Unterzeichnung EC erstellt wurden. Das ist so ziemlich alles, was der Loggürtel tut. Alles klar, das war's für unseren Authentifizierungsdienst. Nicht zu kompliziert, oder? Als nächstes brauchen wir die Benutzeroberfläche oder Schnittstellen, die wir diese Seele nennen werden. Ich habe zu einem Controller namens Benutzer Controller erstellt. Und hier injizieren wir I Authentifizierungsdienst und haben zwei Optionen, eine für Login und 14 Login mit unserem Post Art. Also loggen Sie sich ein, es wird nur eine Ansicht zurückgeben und wir können damit eine Ansicht ganz einfach generieren. Also, nun, lassen Sie mich zurückverfolgen. Ich verwende tatsächlich die Login-VM-Site, erstellt eine Login-VM. Da gehen wir, die einige Validierungen erzwingt sind mehr, aber ich werde sagen, Sie wissen, wir können immer die Validierung von einem Client erzwingen sagte, ich muss nicht unbedingt auf die API verlassen. So etwas wie das Einloggen. Sie sollten nicht in der Lage sein, sich anzumelden, ohne dass die E-Mail, die ich parser, ausgefüllt wird. Ich habe auch ein Feld namens Rückgabe-URL. Also, wenn Sie versuchen, sich anzumelden, werden wir verlangen, dass Sie ein E-Mail-Passwort haben und wo validiert auch die Datentypen mit diesen? Und dann in der Option, werden wir eine Ansicht zu generieren. Und ich habe gerade gesagt, dass Sie sich anmelden. Ich benutze die Vorlagen erstellen, weil wir sein werden, wir brauchen eine Farm. Und dann verwenden wir die Login-VM für diese Generation oder so, nachdem wir all das getan haben, klicken wir auf Hinzufügen, wir bekommen unsere einfach nicht Ansicht, dass wir in unserem Benutzerordner zu sehen gewohnt sind . Und es ist wirklich nur das Login-Formular, richtig? Ich habe die Rückgabe-URL als versteckte. Und wir haben ein Textfeld für unsere E-Mail 14 Passwort, das ich angegeben, der Typ ist Passwort, also ist das die Bande der Zeichen, natürlich. Und dann die Schaltfläche sagt Login, wissen, wenn dieses Formular gesendet wird, wir nehmen die Login-VM und Rückgabe-URL. Also Rückgabe-URL geht entweder zu Gesundheitsinhalt oder Standard-URL-Inhaltsstammverzeichnis. Und wir werden eine Flagge haben, die besagt, dass angemeldet ist, die nach unserer Gewichtung ein Aufruf an den Auth Service Punkt authentifizieren, wo Richtlinie in der Login Punkt E-Mail und Login Passwort gesetzt wird. Und wenn wir einen Boolean erhalten, dann können wir eine Weiterleitung an die Rückgabe-URL zurückgeben. In Ordnung? Andernfalls werden wir einen Modellstatusfehler hinzufügen, um zu sagen, dass der Login-Versuch fehlgeschlagen ist, diesen Drachen und wir geben einfach die Ansicht mit dem Login zurück. Also denken Sie daran, dass, sobald es dies verursacht hat und dies blockieren kann, was als wahr zurückkommt. Das heißt, Sie hätten bereits ein Cookie erstellt, das diesen Benutzerdatensatz oder diese Benutzersitzung bereits erstellt hat. Und dann, wenn wir umleiten, wäre der Benutzer angemeldet gewesen. Nun springen wir zu unserem Layout und sehen einige der Änderungen, die wir vorgenommen haben. Also in unserem Layout hatten wir unsere Blatttypen, Link oder URL direkt hier in diesem Menübereich. Also habe ich das entfernt und ich habe es durch dieses schöne ersetzt, es ist ein Codeblock. Und ich habe auch in diesem Teil namens Login teilweise gestellt. Aber schauen wir uns ein wenig Code an, den ich eingefügt habe. Also in dieser UL oder ungeordnete Liste, wo wir alle unsere nav Elemente haben in einer if-Anweisung gesetzt, die sagt, ob Benutzer, also Benutzer mit einem Kapital U standardmäßig auf die Ansprüche Prinzipien zu schauen, denken Sie daran, dass das ist, was wir gerade in diesem Authentifizierungsdienst, richtig? Also, wenn diese Benutzer-Punkt-Add-Entität authentifiziert ist, dann wollen wir dies tun. Einige Hühnerbenutzer.name ist registriert. Also denken Sie daran, dass wir die Regel sauber geschickt haben, oder? So können wir user.email mineral sehen, suchen Sie nach der Rolle Administrator. Und wenn der Benutzer in dieser Regel ist, dann zeigen wir diese vielen Elemente an. Also habe ich nur ein anderes Navigationselement mit einer Klasse namens Drop-down-Liste und einem Anker-Tag, das Manage sagt. Und ich werde nicht durch jeden einzelnen Charakter gehen. Ich werde nur langsam genug hindurchblättern, damit Sie alles sehen können, was in diesen Anker-Tag geht. Ordnung. Und dann unten haben wir ein div, das die Dropdown-Menüelemente hat. So können Sie einfach Pause drücken und das bei Bedarf replizieren. Also, so haben wir das Dropdown-Listenelement im Menü bekommen. Zumindest wenn Sie Bootstrap 4 verwenden, was standardmäßig kommt, wenn Sie oder.net-Dateiprädikation im Login-Teil kennen, war alles, was sie getan haben, eine neue Rasieransicht zu erstellen, keine modularen und Finger und Leerer von Ihnen gab es ein Name unterstreichen teilweise Niedrigkeit, wo normalerweise darauf hinweist, dass es sowieso teilweise ist. Und dann haben wir dieses bisschen Code, wo ich eine andere URL mit Klasse navbar habe. Und dann innerhalb dieser avenue Anweisung wird der Benutzer authentifiziert. Dann wollen wir ein Listenelement, das den Benutzer Punkt Identität Punktnamen zeigt. Also erinnern Sie sich an den Namen behaupten, dass wir ausdrücklich gesagt haben. Das war Kunst. Also das ist gut, ich benutze eine Zwischengeschwindigkeit in der Navigationsleiste. Also bei diesem Display genau da, und dann haben wir einen Logo-Button. Die Schaltfläche Laden ist also tatsächlich ein Formular, das die Aktion Logos im Controller des Benutzers aufrufen wird. Und ich habe gerade diese Rückgabe-URL direkt dort eingefügt. Und dann der Knopf, der Logos sagt. Wenn der Benutzer also authentifiziert ist, zeigt er das sonst an. Wir möchten den Link für eine Schwester und einen Link für einen Login zeigen. Unkompliziert genug verletzt. Wenn sie also nicht eingeloggt sind, möchten wir, dass sie sich anmelden oder registrieren können, andernfalls zeigen sie ihren Namen. So können Sie voran gehen und diese Zeilen replizieren. Obwohl große Modifikation, die gemacht werden musste, war unser Startup. So können Sie hier sehen, dass einiges passiert ist. Das letzte Mal, als wir hier waren. Ich glaube, wir hätten bis zu diesem Punkt gehabt. Jetzt haben wir das ganze Verfahren. Es ist richtig. Erstens müssen wir es wissen lassen, dass wir den HTTP-Kontext-Accessor hinzufügen möchten, was bedeutet, dass wir es in jede andere Klasse injizierbar sein möchten, also verwenden wir es im Auth-Dienst. Erlaubt uns diese Einrichtung. In Ordnung, dann möchte ich die Cookie-Richtlinienoptionen einrichten, richtig? So werden Dienste konfiguriert Cookie-Richtlinienoptionen sind nirgendwo in der minimalen Seite verantwortlich. Sorry, minimale Sicht scheint festgelegt Politik. Es scheint, dass mehr als eine. Ordnung. Also noch einmal, dies ist eine ziemlich einfache App. Ich bin nicht bereit, alle mit der Sicherheit, Sie können unterschiedliche Sicherheitsbedürfnisse haben, unsere eigenen Ihre Cookies und Ihre Richtlinien. Aber auf einer grundlegenden Ebene, das ist, worauf wir sitzen. Und dann werde ich sagen, Dienste dot hinzufügen Authentifizierung. Und wir fügen das Cookie-Authentifizierungs-Standardauthentifizierungsschema hinzu. Und wir fügen nur Cookie hinzu. Dann füge ich Transient hinzu oder füge einen Transienten oder eine Distribution für unseren Authentifizierungsdienst mit seiner Implementierung hinzu, alles ist, bleibt in dieser Services-Konfigurationsmethode ziemlich gleich. Aber dann in unserem Konfigurieren, wollen wir auch sicherstellen, dass wir Authentifizierung hinzufügen und dass wir ADD oder verwenden Autorisierung dort auch. Sie wollen also sicherstellen, dass diese beiden Linien Gefängnisse sind. Und bevor ich vorwärts gehe, wollen wir auch sicherstellen, dass Cookie-Richtlinien dort. Also die drei Dinge tatsächlich, Cookie-Richtlinie, verwenden Sie Authentifizierung und verwenden Sie Autorisierung. Nun, eine andere Sache, die Sie tun möchten, ist, Ihre Dienste zu ändern. Also wissen Sie, dass wir wissen, dass wir das Inhaber-Token an bestimmte Service-Anrufe angeschlossen haben müssen. Wir können jetzt zu einem Dienst gehen. So haben Sie den Blatttyp-Service bereits in Betrieb und läuft. Und dann können wir die Add-Bearer-Token-Methode innerhalb jeder dieser Methoden aufrufen. Also, kurz bevor wir diesen Kundenanruf tatsächlich erfüllen, möchten wir Träger-Token hinzufügen. Und genau wie ein Refresher am Bearer-Token im Grunde sagt, wenn das Token existiert, dann gehen Sie weiter und fügen Sie es der Autorisierung hinzu. Alles klar, besorgen Sie es als Bier. Also denken Sie daran, wenn wir testen, würde es stolpern. Als wir den gesicherten Endpunkt testen mussten, wohin wir gehen und den Bearer-Space sehen sollten, das Token Das ist alles, was das tut, nur die Authentifizierungs-Header-Werte Bier zu sehen. Und wir fügen diesen Token hinzu. Und Autorisierung ist der Standard-Header, richtig? Also, das ist der Header und es fügt Träger hinzu. Das ist falsch genannt. Wenn wir eine Barriere setzen, beschleunigt Tolkien für uns. Wenn wir das tun, fügen wir es diesem Kunden hinzu. Zu dem Zeitpunkt, zu dem der Client den Anruf ausführt, ist das Inhaber-Token vorhanden, und dann kann alles andere fließen. Sie können also einfach voran gehen und diesen Träger Token hinzufügen, weil wir nicht wissen, wann etwas gesichert wird, sind sie nicht. Wir wissen nicht, welcher Endpunkt auf der API gesichert wird. Nun, es spielt keine Rolle. Tatsache ist, dass wir wissen, dass wir Spiegelsicherheit brauchen. Und mehr als wahrscheinlich würden Sie Ihre API besitzen oder eine API wäre Sperren, die nicht vollständig für jemanden gelten, der sich nicht einloggt, sich zu registrieren versuchen. Sobald Sie eingeloggt sind, wird erwartet, dass Sie Ihre Tolkien zu sagen haben, hier bin ich diese für die Informationen. Nun als Test, was wir tun werden, ist, zurück zu unserem Blatttypen-Controller in der API zu springen und über den gesamten Controller zu übertragen und zu autorisieren, was bedeutet, dass Sie nicht in der Lage sein sollten, zu einem dieser Endpunkte mit all Ihrem Inhaber-Token, sollten Sie eine 40 1 erhalten, was bedeutet, auf autorisierten oder nicht autorisierten, auf authentifiziert. Stattdessen, wenn Sie versuchen, von der API aus zu einem dieser Endpunkte zu wechseln. Ordnung? Denken Sie also daran, zu testen, Sie möchten sicherstellen, dass Sie mehrere Projekte, mehrere Start-up-Projekte haben , gehen Sie zu Lösungseigenschaften und lassen Sie die API starten. Ich beginne mit o Debugging, sagen wir, kommt schneller und MVC, Sie können auch ohne Debugging beginnen, wenn Sie nicht Zeile für Zeile gehen müssen. Also lasst uns voran gehen und das testen. Also haben wir unsere MVC-Anwendung, wir werden versuchen, sich anzumelden. Also lassen Sie mich setzen, aber Versuche. Ich weiß, dass der Benutzer diese Anmeldung nicht denkt und Ihnen ein paar gibt, und dann springt es oben, wenn der Anmeldeversuch fehlgeschlagen ist. Bitte versuchen Sie es erneut. In Ordnung. Richtig vermerkt. Lassen Sie uns eine versuchen, die wir kennen, und versuchen Sie es dann noch einmal. Und dann dieses Mal sind wir jetzt angemeldet worden so umgeleitet uns auf unsere Homepage und keine ISI, dass Menüpunkt verwalten, die uns diese Optionen gibt, weil wir in als Admin sind. Und wenn ich gehe, um Typen zu verlassen, lädt alles. Warum? Weil mein Token vorhanden ist. Sie weiß, dass ich Zugang zu Informationen habe, die angefordert werden. Oh, wenn ich viel liebe. Und lassen Sie mich versuchen, mich wieder als normaler Benutzer anzumelden, dann wird die Anmeldung in Ordnung sein, aber es gibt keine Verwaltung jetzt. Was ist, wenn dieser Benutzer über der Admin-Schulter stand und sah, dass ich das tun kann, um zu den Blatttypen zu gelangen und meinen eigenen Blatttyp zu erstellen. Ich werde versuchen, dorthin zu kommen. Es wird dorthin gehen, oder? Also ändern Sie das zu korrigieren. Wir haben ein paar Angriffspunkte, und wieder einmal sind wir Optionen. Implementieren Sie diejenige, die für Ihre Situation am besten ist. Aber von der clientseitigen Anwendung sollten wir wissen, dass bestimmte Dinge für Administratoren reserviert sind, unsichere Dinge für Benutzer oder vielleicht nicht reservierte Bücher reserviert sind. Benutzer sollten nicht auf bestimmte Dinge zugreifen können, die Administratoren können. In unserem Blatttypen-Controller reicht es wahrscheinlich nicht aus, nur zu sagen autorisieren, weil dies bedeutet, dass Sie angemeldet sein müssen. Ich könnte auch sehen, autorisieren mit dem Rollen-Administrator. Das bedeutet, dass nur Administratoren in der Lage sein sollten, in diesen eigentlichen Teil der Anwendung zu gelangen. Alles klar, das würde mir wirklich viel Zeit auf der Client-Seite sparen , um herauszufinden, okay, was sind die Anrufe? Krieg sie was auch immer, weil diese Autorisierung tatsächlich für mich kümmert. In Ordnung. Jetzt, da ich nur Administratoren autorisiert habe , auf den Blatttypen-Controller zugreifen zu können. Wenn ich als Benutzer eingeloggt bin und versuche, Typen manuell zu verlassen. einmal reicht es nicht, den Link einfach zu verbergen denn wenn ich ihn auswendig lerne, kann ich dreiegeln. Nun, Sie sehen, dass der Zugriff verweigert wird und auf eine Adresse verweist, die nicht existiert. Nun, das ist in Ordnung. Was es uns sagt, dass der Zugriff verweigert wird, oder, weißt du, es berichtet, dass wir nicht dorthin kommen können. Wenn ich jedoch als Admin angemeldet war, könnte ich leicht dorthin navigieren, weil ich die Anforderungen erfüllte. Das ist also eine nette Möglichkeit, Ihre Anwendung vom Client zu sichern. Sagte jetzt, dass gesagt, Sie könnten es auch von der API sichern, sagte weil die gleiche Weise, wie Sie festlegen können, dass Überschwemmung über die Blatttypen Controller im Client up oder welche Art von App Sie verwenden, ob es sich um einen MVC-Blazer oder eckig handelt, wo immer Sie sitzen, die Authentifizierung in denen, die Sie unsere Autorisierung eher könnten, könnten Sie auch diese Autorisierung auf der API festlegen. Der API-Entwickler kann also auch strenge Bestimmungen haben, wer auf meinen Controller zugreifen kann, denn wenn er nicht von oben erzwungen wird, und dann könnten wir immer noch zur API übergehen. Als API-Entwickler könnten Sie auch sehr streng sein und sehen, dass nur Administratoren autorisiert sind, diesen gesamten Endpunkt zu heizen, dieses gesamte Verhalten, oder? Oder eine Reihe von Verhaltensweisen. Wie gesagt, es gibt nur wenige Optionen und Sie können es immer aus verschiedenen Blickwinkeln angreifen. Alles klar, also schließen wir diese ganze Aktivität mit ein paar weiteren Modifikationen ab und dann sind wir zumindest vorerst frei zu Hause. Ordnung, also in unserem Benutzercontroller, in unserer App, möchte ich hier eine Modifikation vornehmen, bei der ich überprüfe, ob das Modell Steve gültig ist. Wenn Sie also MVC und all diese verwendet werden, können Sie nicht fortfahren, solange sie Validierungsfehler sind und nicht in Logan VM, wir haben einige Validierungen. Wir wollen sicherstellen, dass diese in Schach sind und nicht gefallen haben, das ist alles, was wir diese Validierung erzwingen, bevor wir überhaupt diesen API-Aufruf versuchen. Alles klar, sonst wird es nur das neue, diesen statischen Fehler hinzufügen und die Ansicht mit den Daten und den Fehlern zurückgeben. Kein Problem, nein für die Registrierung. Lasst uns voran gehen und das hier abhauen. Also gehen wir einfach zu Ansicht, Neue Ansicht, Rasiermesser Ansicht. Wir wollen sich mit unserer Create-Vorlage registrieren und unsere Klasse wäre Register v0 m Ordnung, also bin ich mir nicht sicher, ob ich Ihnen das Register gezeigt habe, VM registrieren, aber es sieht so ziemlich wie die Registrierungsanfrage aus. Registrierung, Anfragen, Vorname, Nachname, E-Mail, Benutzername und Passwort Alles klar, und wenn Sie Putin aufstellen wollten, bestätigen Sie das Passwort, aber im Moment ist das alles, was wir haben. Und wir haben auch diese Attribute, um sicherzustellen, dass sie benötigt werden. Sie werden das also verwenden, um die Ansicht zu generieren. Und dann in der, in der Post, was wir haben werden, ist die Annahme der Registrierung oder gibt es VM? Wissen Sie, ich habe eine Änderung an der Registermethode vorgenommen und das hat ein paar Schritte durchlaufen. Eine im Mapping-Profil des hinzugefügten Profils für den Radius der VM und Registrierungsanfragen um sich zu merken oder auf Anfrage zu verteilen, ist eines dieser generierten Modelle mit freundlicher Genehmigung von n swag, richtig? Also wische ich das den Punkt, weil ich es geschrieben habe, aber ich mochte es nicht. Dann wieder einmal, wenn Sie sich entwickeln, manchmal tun Sie etwas auf eine Weise und dann später Pflege. Ich hätte das Zentrum des Bits besser sein können und es wird Probleme mit dem Refactoring haben, richtig? Also in der Register-Methode notiere ich unseren Register-VM-Parameter und ich habe auch aktualisiert oder ich Authentifizierungsdienst, um das zu widerspiegeln. Alles klar, also null, es braucht das ganze Objekt statt sechs Parameter. Das ist also eine andere Sache mit soliden Prinzipien. Sie möchten nicht in viele Parameter in eine Methode übergeben. Wenn Sie also feststellen, dass Sie wahrscheinlich drei oder vier überschreiten, erstellen Sie ein Objekt. Also in diesem Fall hatten wir nur zwei. Ich wollte nicht, dass es das umgestaltet, aber dann hatte dieser etwa fünf oder sechs. Also habe ich es umgestellt, um nur das Registrierungsobjekt zu übergeben. Und dann ist unsere Registrierungsanfrage nein, nur eine Zuordnung zwischen der Registrierungsanfrage und unserer Registrierung oder registrieren VM. Richtig. Also musste ich natürlich Herbst oben in diese injizieren, um das zum Laufen zu bringen. Und dann bleibt alles andere gleich. Also zurück zum Controller. Ich kenne POS in diesem Registeranruf, ich überprüfe, ob es erstellt wurde? Und dann, wenn es erstellt wird, dann leiten wir um. Also hier sitze ich nur die URL, um dein Inhalt zu sein. Ich sitze nicht, es ist spezifisch und wir leiten weiter. Andernfalls haben wir eine Nachricht und geben die Ansicht mit den Daten zurück. Und es würde alle Validierungsfehler entsprechend anzeigen. Lassen Sie uns also auch unseren Auth Service auf API-Ebene ändern , weil wir möchten Mitarbeiter registrieren, damit wir wissen müssen, dass ihre Mitarbeiter, so dass sie sich zu diesem Zeitpunkt registrieren, basierend auf unserem Angebot ist Setup no, dass wären nur Benutzer. Es wird keinerlei Rollenzuweisung geben. Wir müssen also sicherstellen, dass wir, wenn sie sich registrieren, ihre Mitarbeiter kennen. Also in unserem Auth Service, wieder einmal, in unserem Identitätsprojekt über die Infrastruktur, richtig, OT Service, müssen wir sehen, ob das Ergebnis für den Create-Benutzer erfolgreich war. Dann müssen wir sie der Regel zuweisen. Also werden wir nur diese Zeile hinzufügen, nachdem ein Ergebnispunkt erfolgreich war. Wir sagen nur, ich werde warten, um einen Manager hinzufügen, um asynchrone Benutzer zu regeln, Mitarbeiter. Also lassen Sie uns die Registrierung für eine Spin bleiben. Also werde ich auf Register klicken und das ausfüllen. Jetzt eine Sache, die ich zeigen wollte O, wir tun uns für die E-Mail und den Benutzernamen. Wieder einmal sind Kontexte in unserem Kontext anders, ich verwende den gleichen Wert für E-Mail und Benutzername. Und dann würde man sagen, er könnte von lebensfähig gesagt werden. Sie werden nach beidem gefragt. Warum nicht nur nach einem gefragt und es im Bucket zuweisen, was überprüfbare Argumente sind, richtig? In Ihrer Situation benötigen Sie sie möglicherweise getrennt, und sie müssen möglicherweise zwei verschiedene Dinge sein. Kein Problem, Ihnen nur das Framework zu geben. Also, bevor ich sogar eine richtige Verteilung mache und Sie können sehen, dass die Validierung tatsächlich aktiv funktioniert. Ich kann nicht fortfahren, was an Ort und Stelle ist, oder? Also lassen Sie mich die Werte setzen und dann gehen und Register drücken. Und ich wurde hierher umgeleitet. Du hast also noch einen, den du weißt, ich rede immer über die Optionen, weil ich jetzt registriert bin, aber ich weiß es nicht. Es gibt keinen Hinweis darauf, dass es erfolgreich war. Ich ging gerade zurück auf die Homepage. Natürlich kann ich mich anmelden, wenn ich versuche, mich anzumelden, aber der Benutzer weiß es nicht. Also im Allgemeinen, oder manchmal, was Sie sehen würden, ist, dass sie tatsächlich melden Sie sich nach einer erfolgreichen oder Verteilung. So können wir eine einfache Modifikation vornehmen, damit dies geschieht. Das ist eine einfache Änderung ist Kunst zu nennen oder zu authentifizieren. Also gingen wir durch ihre Verteilung, wir bekamen eine Antwort, wenn es nicht leer ist und wir würden wahr zurückgeben. Bevor wir true zurückgeben, wollen wir nur authenticate aufrufen, was wir wissen, was es tut. Es löst tatsächlich diese gesamte Anmeldeprozedur aus, und dann geben wir true zurück. Dann könnten wir in unserem Controller einfach nur eine Umleitung zu sehen haben, anstatt zurück zur Homepage zu gehen, könnten wir tatsächlich unsere beiden IP-Adressen lesen. Sie werden erfolgreich lieben Banner, einige freundliche Nachricht an den Benutzer, so dass sie genau wissen, was passiert ist. Alles klar, das ist es wirklich für null, zumindest später haben wir die Verschönerung wird einige Modifikationen haben, denn selbst auf dem Nullpunkt konzentrieren wir uns nicht oder kompensieren für bestimmte Pfeile, die würden von der API zurückkommen. So weiter. Wir haben gesagt, dass globale Fehlerbehandlung zu kümmern, aber später werden wir uns damit beschäftigen, richtig? Nein, wir konzentrieren uns nur darauf, diese Funktionen zu implementieren und alles gut zusammenzuarbeiten. 33. Einrichten: Also, jetzt, wo wir oder Authentifizierung eingerichtet haben, haben wir unsere Benutzer, oder zumindest unsere Benutzer haben die Möglichkeit, sich selbst zu registrieren und als Mitarbeiter eingerichtet zu werden. Und alles, was wir brauchen, um in die Funktion, die Administratoren erlaubt die Ds zuweisen, um Mitarbeiter zu sitzen. Das beginnt also mit denen, die unsere Domain-Objekte für die Urlaubszuweisung ändern , wo wir die Mitarbeiter-ID hinzufügen werden, da wir wissen müssen, wem die Anzahl der Tage für diesen Blatttyp für diesen Zeitraum zugewiesen wurde. Also müssen wir das hinzufügen. Und danach führen wir eine Migration durch. Sie daran, dass wir unser Startprojekt auf die API und das Standardprojekt auf das Persistenzprojekt setzen müssen. Und oder fügen Sie Bindestrich Migration Anweisung wird so aussehen. Ich habe meine Added Employee ID benannt, um die Zuweisung zu verlassen , und die Kontexte würden Management DB-Kontext verlassen. Und danach führen wir dieses Update im selben Kontext aus. Das ist also unsere Migrationsdatei. Sie machen einfach die Update-Datenbank und einen Boden, den er fertig ist, und wir können vorwärts gehen. Das nächste, was wir tun möchten, ist eine Vertragsdatei oder eine Schnittstelle in unserer Anwendungsschicht unter dem Identitätsordner zu erstellen , ich rufe es an, ich benutze einen Dienst. Also werden wir irgendwelche spezialisierten Benutzeroperationen in diesem haben, ich benutze einen Dienst, der von unseren Handlern verwendet werden kann. Also werde ich diesen eine Liste vom Typ Mitarbeiter zurückgeben und es heißt die get Mitarbeiter, weil wir nur zuweisen wollen. Dies sind die Mitarbeiter wissen, die HR-Abteilung sagte, dass alles, was sie wirklich brauchen für diese Funktion ist die Fähigkeit, auf die Seite zu gehen und klicken Sie auf zuweisen, und dann bekommen wir alle Mitarbeiter und zuweisen. Der Standardwert ist für den Zeitraum, der in diesem Jahr liegt. Natürlich möchten wir keiner Stelle, die nicht in der Mitarbeiterrolle ist, etwas zuweisen . Also müssen wir sicherstellen, dass wir Mitarbeiter bekommen. Mitarbeiter ist ein Modell, das innerhalb des Identitätsordners erstellt wurde. Und alles, was es wirklich hat, ist die ID, die E-Mail, der Vorname, Nachname und nichts zu viel, nicht zu viel kommt aus der Datenbank nur in einem Wald und alle, wer dieser Mitarbeiter sein könnte. Danke, wir haben unsere Implementierung, die im Identitätsprojekt lebt, und es verwendet nur Dienst unter dem Dienstordner. Und es erbt vom Vertrag. Und es injiziert den Benutzer-Manager relativ zum Anwendungsbenutzer. Und dann suchte unsere Methode, um die Liste der Mitarbeiter zu erhalten, nur im Benutzer-Manager, bekommen Benutzer asynchron registriert und wir übergeben in dieser Rolle. Das garantiert uns, dass wir jeden in der Datenbank bekommen , war ein Benutzer, der Mitarbeiterrolle hat. Und dann geben wir die Liste der Typ Mitarbeiter zurück. Also, wo ist dies eine Liste von Anwendungsbenutzern? Also sagen wir, wählen Sie aus dieser Liste in neue Objekte vom Typ Mitarbeiter. Und sie haben nur die Werte entsprechend neu zugeteilt. Und dann beenden wir es mit einer To-Do-Liste alle in dieser Rückkehr. Sobald dieser Dienst aufgerufen wird, werden wir diese Methode verwenden, um alle Mitarbeiter zu bekommen. Dann in unserer Identitätsdienste-Registrierungsmethode, natürlich müssen wir es hinzufügen I User Service. Also gehen wir einfach voran und registrieren es entsprechend. Nun wird dies durch einige Änderungen an unserem ich verlasse Allokation Repository folgen. Also springen Sie zurück zu den Verträgen und finden Sie unser Original. Ich verlasse das Allokations-Repository. Ursprünglich hätten wir neben diesen beiden benutzerdefinierten Methoden die Implementierung für die vollen aktuellen Möglichkeiten der Leave Allocation geschrieben . Aber dann haben HR, wieder einmal, Art von Änderungsregeln es für uns einfacher gemacht, sono Problem, aber wir brauchen einige weitere benutzerdefinierte Methoden, um zu erreichen, was HR im Sinn hatte. Also richtig, nein, ich habe eine Aufgabe, wir geben einen Booleschen Wert zurück, der überprüft, ob die Zuordnung existiert. So erhalten wir die Benutzer-ID, Blatttyp-ID und den Zeitraum. Und dann haben wir eine andere Aufgabe, bei der ich bei Zuteilungen sehe. Sie werden also sehen, warum ich bei Allokationen habe, obwohl wir bereits die generische Add-Methode haben, weiß der Zustand, dass dieser eine Liste der Urlaubsanweisung als Parameter nimmt und die Implementierung kennt. Dass du siehst, was hier passiert. Also lassen Sie uns mit der Anwendung beginnen existiert. Wieder einmal Aufgabe, die einen Boolean zurückgibt, überprüfen, ob es existiert, erhalten wir diese drei Parameter, so dass wir nur DB-Kontext Punkt verlassen Zuordnungen, die jede asynchrone, wo wir überprüfen, ob die Mitarbeiter-ID mit der Benutzer-ID übereinstimmt dünn zu sein. Wenn die Blatttyp-ID viel ein übergeben wird und der Zeitraum ähnlich wie die Periode. Also sind wir nur zurück, ja, dass Zuteilung existiert, sind bekannt für unsere Zuweisungen waren etwas anderes hier als mit der regulären Anzeige zu tun. Denn was passiert, ist, wenn wir es ihr erlauben einfach zu gehen und auf Zuweisungen hinzufügen zu klicken und 100 Personen dort sind. Was wir nicht tun wollen, ist die Add-Funktion 100 Mal aufzurufen. Also hat EF Core uns tatsächlich eine Anzeigenbereichsmethode gegeben, wir einfach eine ganze Liste von Datensätzen hinzufügen können. Und es wird es in die effizienteste SQL-Anweisung zu packen möglich, um die Änderungen zu speichern. Also, deshalb habe ich hier diese angepasste Methode geschrieben. Also fügen wir Bereich hinzu, anstatt hinzuzufügen. Alles klar, jetzt, wo wir unser Repository haben, ist bis zu kratzen, lasst uns zu unserem Handler springen und sehen, welche Änderungen dort drüben benötigt werden. Ordnung, also in unserem Handler hatte auskommentiert diese Zeilen sind nur unkommentieren sie wissen, dass wir hier sind. Also injizieren wir unseren Benutzerdienst in unseren Befehl oder erstellen die Zuweisung. Wissen Sie, dass ein paar andere Änderungen erforderlich sein werden, weil unser erstellen Detail nach zu vielen Informationen verlangt, basierend auf dem, was wir gesagt haben. Die neue Operation oder das neue Ziel ist. Das kommen wir in ein paar. Aber Netzhaut möchte sich darauf konzentrieren, was Handler tut, nachdem es ist, hat es die Daten validiert, die kamen, richtig. Nach der Überprüfung, was in der DTO ist, fahren wir dann fort, zu versuchen, die Liste der Zuweisungen zu kompilieren, die an die Datenbank gesendet werden sollen. Mal sehen, was hier passiert. Erstens erhalten wir den Blatttyp, der zugewiesen wird, oder? Also würden wir tun, ich GET Anfragen unter diesem Repository, das bereits mit freundlicher Genehmigung von der Fatah injiziert wurde. Wir brauchten es für den Validator. In Ordnung, also lassen Sie diesen Repository-Punkt GET-Anforderung Punkt naive Zuteilung Detail die elif-Typ-ID. Wir erhalten alle Mitarbeiter mit freundlicher Genehmigung unseres Nutzerdienstes. Auch in diesem Jahr haben wir den Zeitraum festgelegt. Und dann initialisieren wir eine Liste von Urlaubsanweisungen. Dann prüfen wir für jeden Mitarbeiter, der sich im System befindet, ob die Zuordnung existiert. Wir machen einfach weiter. Andernfalls möchten wir einen neuen Allokationsdatensatz hinzufügen, bei dem die Mitarbeiter-ID gleich EMP Punkt-ID ist und dy durch dt gleich dem Blatttyp, aber ID und der Anzahl der Tage ist. Und der Zeitraum ist der richtige Zeitraum? Ich bin nicht streng nach Geschäftsregeln. Einige Geschäftsregeln würden sagen, dass auf der Grundlage des Punktes im Jahr dieser Standort anders sein sollte, was vollkommen plausibel ist. Was auch immer Masi tun soll, Sie wenden diese Mathematik gegen die Standardtage an und Sie haben angewendet. Aber der Punkt ist, dass Sie die Tage an den Mitarbeiter zu diesem Zeitpunkt zuweisen. Natürlich, wenn du den Grendel holen wolltest, dann würdest du es auf einer Eins-zu-Eins-Basis tun wollen, im Gegensatz zu einer Massenoperation für alle für einen ganzen Zeitraum von einem Jahr, richtig? So kannst du ein bisschen damit herumspielen. Aber im Moment haben wir es nur mit einer Massenoperation zu tun. Nachdem wir also alle diese Zuordnungsdatensätze zu dieser Liste hinzugefügt haben, warten wir nur auf unseren Aufruf an die Zuordnungen in unserem Repository, das über die Liste und EF Core sendet, werden wir den Rest erledigen. Und dann können wir sehen, dass die Antwort wahr ist, Erfolg ist eher wahr, und die Botschaft ist Schöpfung oder Zuweisung erfolgreich, was auch immer Sie bevorzugen. Wissen Sie für unsere erstellt Zuordnung DTO, wir fragen nach der Anzahl dieser. Und wir haben für den Zeitraum gefragt, weil zumindest im alten System, die in der Lage sind, direkt auf einen Mitarbeiter klicken und die Anzahl der Blätter, die wir Geld wild zuweisen. Und die Zeit, für die wir es reservieren, wie HR sagte, sie brauchen das irgendwie nicht oder wollen nicht, richtig? Nein, also ist das in Ordnung. Wir können unsere DTL immer ändern, sie etwas zurückskalieren. Und natürlich würde das einige wellige Effekte mit der ganzen Vererbung der Allokationsdetails haben. Das bedeutet also, dass wir mehr ändern müssen als nur die Felder, oder? Also müsste ich diese Vererbung und die Notiz entfernen, um auch den Validator zu ändern, um nicht alle Regeln relativ zur Schnittstelle einzuschließen , sind es OF, um dieses Ganze zu entfernen , schließen Sie Andon aus, nachdem Sie die Regel nur für die Erstellt. Also habe ich gerade diese Regel umgeschrieben, bei der wir validieren , dass die Blatttyp-ID, für die angewendet wird, zugewiesen wird, wir stellen sicher, dass sie größer als 0 ist und wir überprüfen, ob sie auch existiert. Nun springen wir zu unserer API und lassen Sie sie wissen, dass es auch die Antwort des Basisbefehls zurückgeben sollte. Wenn du das noch nicht getan hast. Stellen Sie sicher, dass Sie dies tun, damit das Swagger-Dokument mit den aktuellen und dann zwei Änderungen von unserem neuen Service-Client in der Anwendung berücksichtigt werden muss. Denn zum einen ändern wir die Parameter für den DTO. Nein, Sie benötigen nur einen Parameter. Und wir müssen auch den Server wissen lassen, dass er die Antwort des Basisbefehls erwarten sollte. Also, jetzt, da wir diese Änderungen vorgenommen haben, Lassen Sie uns in Swag verwenden, um diese Service-Client-Code zu regenerieren. Denken Sie immer daran, dass es am besten ist, das Projekt zu starten. Und dann, selbst wenn Sie es bereits gespeichert haben, weil ich gerade meine gespeicherte Version dieser Vorlage geöffnet habe. Selbst wenn Sie es gespeichert haben, ist es am besten, das Projekt erneut zu öffnen, die lokale Kopie neu und dann Ihren C-Sharp-Code neu zu generieren. Also jetzt springen wir zu unserer Client-Anwendung, wo wir unseren Vertrag einrichten werden, Es ist Implementierungen und natürlich die Benutzeroberfläche. Also im Moment haben wir alle unseren Vertrag. Ich werde Allokationsdienst verlassen und es sagt uns, dass es Rückgabeantwort mit dem Typ int gibt. Und es wird kreativ Berufe genannt werden, und es braucht nur eine Blatttyp-ID. einmal hat HR es für uns vereinfacht. Also, wenn Sie alle VMs erstellt hätten und so weiter, das ist ich, das wäre Overkill auf der Grundlage der neuen Anforderungen gewesen, aber das ist in Ordnung. Alles, was wir wirklich brauchen, ist eine IV Zuteilungen zu erstellen. Und dann in der Implementierung, die wir in den Dienstordner setzen, wissen wir natürlich, dass wir vom Basis-HTTP-Dienst und der ID des Zuweisungsdienstes erben, ähnlich wie das, was wir getan haben, die Blatttypen, wir injizieren auch oder Low-Cost -Speicher und AAE-Client in diesen Dienst. Und dann in unserer Methode, das ist seine Kreatinin-Urlaub Zuteilungen, alles, was wir haben unsere Antwortart, die Antwort relativ zum Typ int ist. Wir erstellen unser Detail, das in dieser Situation wirklich nur das Detail zu sehen ist. Blatttyp hat diesen Wert. Alles klar, also wissen wir, dass die Create, Leave, Create Leave Allocation Detail jetzt aktualisiert wird, um nur diesen Wert zu wollen, da wir unsere Dokumentation und den resultierenden Code durch und Slug aktualisiert haben, fügen wir zu unserem Inhaber-Token hinzu und wir sind Weizen Anruf. In Ordnung, also bin ich nicht einmal die wahre Möglichkeit, wir können immer verdoppeln und sicherstellen, dass der API-Endpunkt nur für Administratoren geschützt ist. Und wir können diese Vorhersage auch von unserer Anwendungsseite aus machen, oder? Also ist das Träger-Token definitiv wichtig, sich daran zu erinnern. Es wird immer wichtig für die apec Kommunikation sein. Nachdem wir das getan haben, überprüfen wir, ob Ihr Erfolg dann setzen wir es auf wahr, da keine echten Daten zurückkommen, weil es nur die Antwort des B zurückgegeben hat. Wir geben keinen Ausweis zurück oder so. Also muss ich die Antwortdaten nicht so einstellen, dass sie wirklich einen Wert haben. Und dann haben wir Compilerfehler Antwort zurückgegeben. Irrtümer berühren. Wie ich bereits sagte, stellen Sie sicher, dass Sie es im Startup-Punkt-CSS registriert haben. Also machen Sie einfach keine Kugeln oder die startup.js. Und wenn er die Zeilen geschrieben hatte, kommentiert sie, dann entkommentieren, wenn nicht, dann fühlen Sie sich frei zu wissen, setzen Sie diese Zeile. Lassen Sie uns nun Änderungen oder Benutzeroberfläche vornehmen. Also der beste Ort, den ich vermutet habe, um diese Funktion für eine Massenzuweisung von Blatttypen zu setzen , ist auf dem Blatttyp LR. Also auf dieser Seite habe ich gerade ein neues Formular hinzugefügt, wo wir mit der gleichen Art von Route ID Visum Jungs befürworten , um ihn zu sehen suchen Formel zu löschen. Also hier wiederholen wir das Formular. Wie ich bereits erwähnt habe, würde manchmal Piepton, anstatt mehrere Formulare zu haben, anstatt mehrere Formulare zu haben,eine haben und dann JavaScript verwenden, um das eine Formular auszulösen. Aber das ist okay in dieser Situation, alles, was ich wissen will, ist, dass es richtig funktioniert? Also haben wir die ASB tatsächlich und zuweisen. Es dauert die gleiche Route ID und wir haben eine Schaltfläche, die sagt zuweisen. Und dieser hier sagt nur: Sind Sie sicher, dass Sie alle Mitarbeiter zuweisen wollen? Das ist die Aufforderung, die Sie bekommen würden. Jetzt haben wir eine Post-Methode in unserem Blatttypen-Controller namens Hello Kate. Also habe ich das einfach unter den Löschvorgang gelegt, richtig? Also in unserem Fall versuchen wir, die Antwort von Urlaub Allokation Service zu bekommen. Also sagte Unterpunkt, dass wir das in unseren Controller injizieren müssen. In Ordnung, also haben wir versucht, die Antwort zu bekommen. Ich benutze nur Control M und O, beachte nur, dass du den Code irgendwie zusammenklappen kannst, damit du ihn für B-Code-Dateien verwenden kannst. Unsere Allocate-Methode wird also Allokation-Dienst aufrufen, Auseinandersetzungen erstellen diese ID übergeben. Und dann, wenn es erfolgreich zur Aktion auf den Index umgeleitet wird. Und nun, ich werde nur schlechte Anfrage hier zurückgeben, nur für den Fall, dass es nicht erfolgreich war. Also wissen wir, dass sie es nicht war. Später können Sie etwas jQuery oder etwas hinzufügen, um den Rückgabetyp besser zu behandeln, aber richtig, nein, wir priorisieren das nicht. Wir wollen nur sicherstellen, dass wir all die Dinge und das Fundament schaffen, richtig? Also lassen Sie uns das eigentlich für eine Spin nehmen. Lassen Sie uns versuchen, zuzuteilen. Denken Sie daran, mehrere Start-up-Projekte anzulegen. Und nachdem wir uns als Admin-Benutzer angemeldet haben, navigieren wir zu unseren Blatttypen und versuchen dann zuzuweisen. Also noch unsere Aufforderung Sind Sie sicher, dass wir auf OK klicken, und wir erhalten einen Fehler. Wir erhalten einen Fehler, HTTP-Fehler 400. Dies deutet also darauf hin, dass eine schlechte Anfrage ist. In Ordnung, also ist etwas definitiv schief gelaufen. Also, nachdem er diesen Fehler verfolgt und verfolgt hatte, landete er genau hier im Validator. Was passiert, ist, dass, wenn wir erstellen, es nicht als gültig, dass erstellen Urlaub Allokation V2 nicht gültig ist. Das liegt daran, dass ein Blatttyp nicht existiert. Jetzt wissen wir, dass das unmöglich ist, weil wir gerade auf den Blatttyp geklickt haben. Es ist in der gleichen Zeile. Wir wissen, dass es existiert und der Pfeil ist genau hier. Also das ist mein, äh, aber so hätte ich Unit-Tests wahrscheinlich erwischt, dass wir jemals in Unittest geschrieben haben. Also müssen wir Zeit damit verbringen, diese Dinge nicht zu verfolgen. Aber der Punkt ist, dass Wir zurückkehren sollten, wenn es existiert, weil wir sehen, ob es existiert oder wahr ist. Es muss also existieren. Das muss also wahr sein. Also sollte ich nicht zurückkehren, zurückkehren nicht wahr oder nicht belüftet. Das ist also ein Fehler meinerseits. Also wegen dieses Fehlers muss tatsächlich zu jedem Validator gehen, nur um gesund zu sein. Stellen Sie also sicher, dass keiner dieser Validatoren denselben Fehler macht. Nun, das Gute ist, dass wir irgendwie zentrale geschaffen haben. Also haben wir nicht viele, viele Änderungen an mir. Also diejenigen, die nicht abmelden, die Blatt-Typ existiert, überprüfen und wir sollten gut zu gehen sein. In Ordnung, also lasst uns das noch mal versuchen. Lassen Sie uns versuchen, die Zuweisungen zu tun. In Ordnung, also sind wir zurück und lassen Sie uns versuchen, wieder zuzuteilen. Wir kommen zu unserer Aufforderung, es tut seine Sache, und die Seite wird aktualisiert, so dass es keine Indikatoren gibt, richtig? Wir könnten natürlich, zitieren einige Nachrichten zu sagen, Sie wissen, diese Aktion wird diejenigen bezeichnen erfolgreich abgeschlossen. Aber die Tatsache, dass es die Seite gemäß unserem Code wirklich aktualisiert hat. Wenn es erfolgreich ist, dann leiten Sie zum Index des aktuellen Strandes, was gut ist. Es war erfolglos so in Butter Anfrage. So wissen wir zumindest, dass unsere Zuteilung funktioniert. Lassen Sie uns in der Datenbank überprüfen, um zu sehen, was unsere Standorte erstellt wurden. Und wir sehen hier, dass wir Zuteilungen für Blatttyp 1 für den Zeitraum von 2021 und den Mitarbeiter haben, dem es zugewiesen ist. Also haben wir drei Mitarbeiter im System oder IL-3 Mitarbeiter in meinem System, wir sehen wahrscheinlich nur ein oder zwei, wenn Sie den vordefinierten Benutzer haben und er einen Benutzer erstellt hat seitdem. Aber der Punkt ist, dass wir so viele Mitarbeiter im System haben, würden Sie diese Zuteilungen haben. Also, wenn ich das wieder mit Sicherheit mache, die id2 ist, klicken Sie auf, ich finde, klicken Sie auf OK und macht seine Sache. Wenn ich diese Daten aktualisiere, sehen wir jetzt Zuweisungen für Krankheitsurlaub für alle Mitarbeiter. So funktioniert div Allokation nicht. Das ist es, was HR Artwork, das ist, was sie bekommen. Also später sehen Sie die der Stiftung, um dies zu erweitern, wenn Sie einen dedizierten Bildschirm geben wollten, müssten Sie den Mitarbeiter angeln gehen, ihnen erlauben, die Zuteilung des Geldes Tal zu bearbeiten. Und dann, wissen Sie, um Ihren Handler und Ihren API-Endpunkt so einzurichten, dass er dafür spezifisch ist. werden wir jetzt nicht detailliert bekommen. Wir wollen nur die Basisfunktionen erledigen. Und bis jetzt sind wir mit der Urlaubszuweisung fertig. 34. Einweisung von angehenden Antrag: Alles klar, Leute, also wickeln wir uns durch Nestle und wir bewegen uns zum nächsten Modul, das unser Urlaubsanforderungsmodul sein wird. Unsere Reise hier beginnt also mit einer Änderung eines Urlaubsanforderungs-Domänenobjekts , wo wir die anfordernde Mitarbeiter-ID hinzufügen, okay, denn wer immer eingeloggt ist, ist derjenige, der die Anfrage stellen wird. Also müssen wir in der Lage sein zu sagen, dass diese Anfrage von diesem Benutzer kam. Wie üblich haben wir nach einer Änderung unserer Domain-Objekte unseren Migrationsbefehl und dann haben wir unseren Update-Datenbankbefehl. Also kannst du voran gehen und diese beiden machen. Und sobald Sie das erfolgreich abgeschlossen haben, können wir mit unserer nächsten Aktivität fortfahren. Lassen Sie uns unsere Details zum Erstellen von Urlaubsanfragen überprüfen. Also sagten wir, dass die Quest D2 muss das Datum haben würde Start- und Enddatum, die Blattart, für die beantragt wird, sowie fordert Kommentare. Beachten Sie, dass es nichts Schreckliches die Benutzer-ID, richtig? Also fragen Sie sich wahrscheinlich, okay, woher wissen wir also, welcher Benutzer gleichzeitig eingeloggt ist? Denken Sie also daran, dass wir Tolkien-Authentifizierung verwenden, was bedeutet, dass wir zwischen dem MVC auf der API auf verschiedene Informationsbits von den Tolkien zugreifen können. Ein Bit an Informationen im Token wäre die ID des Benutzers. Ich möchte jedoch von keinem dieser Orte darauf zugreifen da ich nicht darauf zugreifen muss, bis ich wirklich eine Urlaubsanforderung erstelle. Und wir haben den Handler hier, der genommen wird, dieser Befehl Anfragen oder Befehle Objekt. Und dann geht es voran und validiert es und erstellt dann, dass die Anforderung, wenn sie gültig ist, und übergibt es dann die Datenbank. Das bedeutet also, dass wir zwischen diesen beiden Schritten sicherstellen müssen, dass wir diese neuen Mitarbeiter-ID-Daten eingeben. Denken Sie also daran, dass wir den Kontext-Accessor Buck verwendet hatten , als wir die Authentifizierung in der MVC-Anwendung durchgeführt haben. Das coole daran ist, dass wir diesen Kontext-Accessor ganz hier in unserer Anwendungsebene, in unseren Befehlen verwenden können. Also werden wir auf den HTTP-Kontext der API aus dem Handler zugreifen. Auf diese Weise müssen wir nicht darauf zugreifen, bis es absolut notwendig ist. Also in der API-Startdatei werde ich den services.js HTTP-Kontext-Accessor beschreibbar hinzufügen, den swat Swagger doc-Methodenaufruf. Dies ermöglicht mir dann, meinen HTTP-Kontext-Accessor in den Befehl zu injizieren. Und ich kann das Feld initialisieren, aber ich brauche eine Bibliothek dafür, und das ist die Microsoft dot ASP NET Core-Abstraktion. Also gehen Sie weiter und installieren Sie die neueste Version. Ich benutze NuGet, benennen Sie unser Feld gemäß unserer Namenskonvention um. Und dann innerhalb des Handlers kann ich leicht speichern var Benutzer-ID ist gleich meinem HTTP-Kontext-Accessor dot HTTP-Kontexte, dot user dot behauptet Standard erster Ordnung. Es ist also ein Hauch voll, aber lassen Sie uns einfach beurteilen, was hier vor sich geht. Bis zu diesem Zeitpunkt haben wir das Anspruchsprinzip erhalten. Dieses Anspruchsprinzip ist das gleiche Prinzip, das wir in der Lage sind, in der Mandantenanwendung aufgrund der Tolkien zu bauen , in Ordnung, also, weil das Token von unserem Client zur API kommt, können wir auf die Token-Informationen zugreifen aus dem Handler mit freundlicher Genehmigung der API. Und dann können wir auf diesen Benutzer zugreifen, schauen Sie in die Liste der Ansprüche und finden Sie die erste Etage Standard, die den gleichen Namen Typ Schlüssel hat. Sie möchten jedoch beurteilen, dass das, was ein Typ hier mit dem beanspruchten Namen übereinstimmt, den wir ihm für Benutzer-ID gegeben hätten. Das ist ein weiterer Grund, warum ich vorschlagen würde, die magischen Strings nicht zu verwenden weil ein Rechtschreibfehler hier die ganze Sache wegwerfen könnte. Was wir das später in der Bereinigungsaktivität tun können. Aber im Moment bekommen wir die Claim-UID, die wir manuell sitzen. Und dann verwende ich nur den Standard oder vier, wenn er klein ist, bekommen wir keine weitere Ausnahme, aber ich bekomme wirklich den Wert. Alles klar, so bekomme ich die Benutzer-ID. Jetzt, da ich diese Benutzer-ID habe, kann ich später sehen, dass der Urlaubsanforderungspunkt die Mitarbeiter-ID anfordert. Jetzt habe ich es den ganzen Weg hier oben gemacht, weil ich später diese Benutzer-ID und eine weitere Operation verwenden möchte . Also behalte ich es nur hier. Und eine andere Sache, die wir interessieren könnte, ist die E-Mail-Adresse. Also nicht hier, wir bekommen die E-Mail auf eine etwas andere Art und Weise. Wir sehen, E-Mail-Adresse ist gleich seinem GTP-Kontext-Accessor, alle diese user.name zuerst finden. Und dann suchen wir nach dem genauen E-Mail-Anspruch nach seinem Typ. Da es eine andere Technik tut als das, was wir hier oben getan haben. Und wir bekommen diesen Wert. So können Sie mehrere Ansätze ergreifen, um dies zu erhalten. Diese Informationen, weil er nur das Anspruchsprinzip in einem Sweep bekommen hätte und dann das Find First Gesetz verwenden könnte , das erste Gesetz Standard danach, um die Informationen zu erhalten, die Sie wollen. Kein Problem, aber zumindest wissen Sie oder wissen , wie Sie die E-Mail-Adresse zu bekommen, so können wir wissen, sagen zu dieser E-Mail-Adresse und senden Sie unsere E-Mail zum richtigen Zeitpunkt. Nun, bevor wir von diesem speziellen Handler dort weitergehen andere Housekeeping up Operationen, die ich durchführen möchte, bevor wir einem Benutzer erlauben, mit einer Urlaubsanfrage fortzufahren. Und so lassen Sie uns darüber nachdenken, was genau während dieses Prozesses passieren muss. Auf ein Benutzer muss angeben, dass er während eines bestimmten Zeitraums einen bestimmten Blatttyp haben möchte . Sie können zusätzliche Kommentare hinzufügen, wenn sie möchten. Und dann unterbreiten sie das. Sie können diese Anfrage nur erhalten, wenn sie die Zuteilung haben. Das bedeutet, dass wir es nicht einmal in das System stecken. Wenn das, was sie angefordert haben, ihre aktuelle Zuteilung überschreitet. Wenn sie es anfordern und ihre Zuteilung vorhanden ist, dann ist das in Ordnung. Später, wenn ein Administrator dies genehmigt, dann gehen wir voran und machen einige Abzüge, um sicherzustellen, dass, wenn sie fünf Tage angefordert haben, die 5D weniger in ihrer Zuteilung ist. Das sind also die Dinge, an denen wir interessiert sein wollen. Nun ist dies ein, dies ist die komplizierteste der Module. Also gibt es hier einiges zu tun. Lassen Sie uns also mit der Überprüfung für die Zuweisung beginnen, denn wenn sie nicht über die Zuteilung verfügen, können sie künftig keine gültige Operation haben, richtig? Also lassen Sie uns voran und injizieren oder ich lasse Allokation-Repository in das System. Und dann, was wir tun wollen, ist in der Lage, die Zuteilung für diesen bestimmten Mitarbeiter zu suchen , was eine Methode ist, die wir nicht R. Also lassen Sie uns zu dieser Geschichte springen und das umsetzen. Also erstellen wir eine Aufgabe, die die Urlaubszuweisung zurückgibt, ich rufe GetUser Allocations auf und nehme diese String-Benutzer-ID sowie die Verlassen-ID, richtig, also werden wir hier rüber springen und voran gehen und die Schnittstelle in der Implementierungs-Repository-Klasse. Und dann, was wir hier tun werden, ist ein Lookup zu machen und unseren DB-Kontext suchen verlassen Allokationen suchen, die erste Ordnung zu finden, wo die Mitarbeiter-ID mit der Benutzer-ID übereinstimmt und die Blatttyp-ID mit dem Blatt übereinstimmt. Kein Buckeln des Handlers. Ich kann voran gehen und diese Zuweisung erhalten, indem ich Leave Allocation Repository Git-Benutzerzuweisungen aufruft , die Benutzer-ID und diese Anforderung Dot verlassen, Anfrage Detail Punkt Blatttyp ID. Ich werde jetzt die Anzahl der angeforderten Tage berechnen. Also mache ich nur einen schnellen Kaukasier zwischen dem Enddatum und dem Startdatum, um die Gesamtzahl der Tage zu erhalten. Und ich sorge dafür, dass ich es bekomme, aber als Ganzzahl. Und dann werde ich sagen, ob die Anzahl der angeforderten Tage größer ist als die Anzahl der Tage in Ihrem Allokationsdatensatz. Ich werde diesen Validierungsfehler hinzufügen. Also könnte dieses Unternehmen hier passieren, genau wie wir sehen, ich mache es Handler und ich verwende das fließende Validierungsergebnis, um das hinzuzufügen, denn falls es nicht gültig ist, möchte ich sicherstellen, dass diese Validierung auch anwesend. Und wenn es mit den Fehlern zurückgegeben wird, die auch da sein werden. Nein, ich mache das im Handler, aber ich hätte das auch im Validator leicht machen können. Aber dann hätte ich natürlich all dies injizieren müssen und eine benutzerdefinierte Validierung für die NDA erstellen müssen, um sicherzustellen, dass ich diese Berechnung und alles mache. Also gebe ich dir nur die Optionen, die auf deiner Situation basieren. Vielleicht möchten Sie all diese Dinge in den Validatoren behalten. Möglicherweise verwenden Sie nicht einmal den Validator. Also könnten Sie all diese Validierung direkt hier durchführen. Es hängt davon ab, wie Sie Ihren Anwendungscode auslegen möchten. Also jetzt können wir einfach weitermachen und alles andere in diesem Handler aufräumen, wir müssen möglicherweise Daten erneut besuchen, aber zumindest schauen wir uns an, wie wir unseren Handler erweitern und anfangen, einige andere Dinge in ihr Leben zu setzen HTTP, Kontext, Handler es, Zugriff oder andere, sorry. Wenn wir fortfahren, können Sie alle kleinen Nachrichten auf dem Weg bereinigen und sicherstellen, dass Ihr Code kompiliert werden kann. Also nur ein schneller Build. Lasst uns jetzt schnell zu unserer App vorwärts gehen. Wir wollen die Funktion erhalten, in der ein Mitarbeiter in erster Linie Urlaub beantragen kann , bevor wir andere administrative Funktionen und irgendetwas, richtig? Also möchte ich, dass wir sicherstellen, dass wir dieses Ansichtsmodell haben. Ich hätte es vorher gezeigt, aber lassen Sie Anfragen VM und laden Sie alle Ansichtsmodelle hier hoch. Und diese Ansichtsmodelle kommen wirklich aus dem vorhandenen Code weitgehend. Also die Create leave Requests, VM, und das nimmt das Startdatum, das Enddatum, die Zeit, die Blatt-ID und einen Bereich für Kommentare. Nein, ich würde über den Vertrag für den Ich lasse Anfragen Service springen , wo wir ein paar Methoden haben, die wir noch nicht alle implementieren, wir haben es mit einem Kredit zu tun, damit Sie gehen und sie alle in. Und erstellen Sie die passende Service-Implementierung und erlauben Sie ihr, sie alle zu implementieren. Aber wenn wir uns auf die Create-Methode konzentrieren, haben wir einen ähnlich aussehenden Kern zu dem, was wir mit den Blatttypen gemacht haben. Sie würden jedoch bemerken, dass ich eine rote Linie unter dem Teil habe , in dem ich um eine Antwort bitte. Denn was KI-Dienst, Client oder Code betrifft, suchen wir immer noch nur nach einer Aufgabe. Das liegt daran, dass ich in der API zwei Dinge tun muss. Ich muss die Dokumentation oder das auf Post lassen, es sollte die Basisbefehlsantwort nehmen. Denken Sie daran, dass wir alle unsere Handler ausgestattet hatten, um dies zurückzugeben. Und das ist wichtig, denn wenn wir n swag zum Regenerieren oder Code verwenden, was ich gerade tun werde, dann wird es wissen, dass es diesen Antworttyp erwarten sollte. Noch einmal, erstellen Sie die neueste lokale Kopie, gehen Sie weiter und generieren Sie und wissen, dass das getan wird, wenn ich zurück zu meinem Code springe, gibt es keine roten Linien, weil jetzt weiß es, dass es die Basisbefehlsantwort zurückgibt. Also ist alles gut. Alles klar, das ist im Grunde das, was wir tun, um die Blattanforderung zu erstellen. Lassen Sie uns nun auf die Einrichtung des Controllers und des unterstützenden Codes konzentrieren. Ich ging voran und erstellte einen Controller mit Lese-Schreib-Operationen, wissen Sie, um das zu tun, Nein. Und ich habe den Blatttyp-Service injiziert und Anfragen Service verlassen. Also fragen Sie sich wahrscheinlich, okay, warum brauche ich den Blatttyp und verlassen Anfragen Service wenn ich nur Urlaubsanfragen erstelle, na ja, die Sache ist, dass die Ansicht, die ich bereits erstellt habe einen Drop- unten für die Blatttypen, denn wenn jemand kommt, um Urlaub zu beantragen, basiert es auf Ihrem Fluss. Aber die Art und Weise, wie wir es bauen, kommen sie zur Anforderung, lassen Sie das aus, um aus einer Dropdown-Liste auszuwählen, für welche verlassen sie auswählen, das Startdatum, das Enddatum. Und dann sind sie in der Lage, ihre Kommentare einzugeben, bevor sie weitergehen und eine Anfrage auswählen. Okay, das ist im Grunde das, was ich tue , und das ist die Ansicht, die vom alten System kommt. Also habe ich diese Ansicht buchstäblich aus dem alten System kopiert und eingefügt. Das einzige Update war, dass wir das Modell ändern , um das neue Modell zu sein, im Gegensatz zu jeder neuen Spezies dort. Aber ich zeige dir nur, dass es die gleiche Klasse ist. So können Sie immer die Codedatei abrufen und einfach kopieren und einfügen. Und Sie sollten bis zu kratzen als Mengen von Alpha. Deswegen ist das hier. Ich benutze keine Datumsauswahl. Ich kompliziere die Schnittstelle noch nicht. Also entferne ich das. Haben Becker Freunde Unsere nur mit Eingabetyp Perlen abhängig von der Default Datum Picker uns vom Browser gegeben. Also Buck im Controller, wir müssen diese Dropdown-Liste vor dem Laden der Schnittstelle vorbereiten. Also statt vier, erhalten Sie Create-Methode, was ich habe, ist ein Aufruf an den Blatttyp-Service, um alle Blatttypen zu erhalten, sie in dieser Variablen zu speichern. Und dann habe ich Blatttyp-Elemente, bei denen ich eine neue Auswahlliste mit Blatttypen erstelle und ID und Name als Schlüssel und die Textfelder verwende. Und dann erstelle ich das neue Modell, bei dem ich Blatttypen als Blatttypelement übergebe. Das Erinnern schafft Urlaubsanfragen. Wir hatten das öffentliche Auge unzählige wählen Sie diese Elementeigenschaft, und dies könnte leicht Auswahlliste gewesen sein. Ordnung? Also, was auch immer man funktioniert, aber lässt uns mit wählen Sie dies aus, weil es tatsächlich einfacher ist, bei der Arbeit mit zu tippen. Das ist also alles, was hier passiert. Und dann geben wir die Ansicht zurück, die das Modell zeigt. die Post-Methode kennen, folgen wir so ziemlich dem gleichen Verfahren, wenn der Modellstatus gültig ist. Denn denken Sie daran, dass wir in unserem Ansichtsmodell einige Validierungsregel haben, also möchten wir sicherstellen, dass alles erfüllt ist, bevor wir fortfahren können. In der Tat erkenne ich nur, dass ich eine Validierungsregel über die Blatttyp-ID selbst vermisse . Sie müssen also eine Blatttyp-ID auswählen, bevor sie fortfahren können. Okay, lass mich einfach alle aufstellen, damit du alles sehen kannst. Da gehen wir. Also, wenn der Modellstatus gültig ist, dann gehen Sie voran und Breite auf die Antwort von der Arbeit des Urlaubsanforderungsdienstes, die versuchen wird, eine Urlaubsanforderung zu erstellen. Und wenn es erfolgreich ist, dann können wir zum Index umleiten. Es gibt hier noch keine Indexseite, aber das ist kein Problem. Und dann können wir jedes Modell hinzufügen, Modellstatuspfeile , die von unseren Antwort-Validierungsfehlern kommen. Aber wenn die Seite neu geladen werden muss, müssen wir die Auswahlliste der Blatttypen tatsächlich neu laden, richtig? Also eine Sache mit Dropdown-Listen für den Fall, dass Sie nicht so vertraut mit ihnen. Jedes Mal, wenn Sie die Seite laden, müssen Sie diese Liste laden. Also haben wir die Seite erste Ebene geladen, wo diese Liste geladen dann das Modell zurückgeben. Wir müssen das Gleiche tun. Was haben wir bereits die Daten aus dem Modell? Daher müssen wir nur die Daten der neu geladenen Auswahlliste zuweisen bevor wir den pH-Wert neben allen Fehlern zurückgeben, die angezeigt werden müssen. Ich wette, autorisieren Sie die Rede, die an dieser Stelle ziemlich Standard ist. Und in unserer Layoutdatei haben wir ein paar Änderungen. Also habe ich die Links dort nur für Mitarbeiter gesetzt, um unsere Sicht zu schaffen. Mein Blatt, ich habe meinen Urlaub noch nicht gemacht, aber hier sind unsere Links, richtig? Also im gleichen Das ist es überprüft, ob der Benutzer authentifiziert ist. Ich sehe, ob es sich um einen Mitarbeiter handelt, der angemeldet ist , weil Administratoren keine Zuweisungen haben, also müssen sie nicht gehen und Anfragen gehen, richtig? Also, wenn es ein Mitarbeiter ist, der eingeloggt ist, dann können sie sehen, zwei neue NovaLink Schwan gehen Anfragen und erstellen. Und da steht, dass Anfragen weitergehen, obwohl ich gehen werde, was wir noch nicht getan haben, aber wir kommen langsam aber sicher dorthin, richtig? Also, nachdem wir all das getan haben, lassen Sie uns voran und setzen oder mehrere Starter-Projekte noch einmal und testen Sie dies aus. Also jetzt werde ich mich als Benutzer Admin anmelden, aber der Mitarbeiter. Und wenn ich das mache, sehe ich meine beiden Links in der Navigationsleiste. Wenn ich also zu Anfragen gehe, bekomme ich diesen Fehler. Es ist ein 403 Fehler und ich sehe es und ich weiß genau warum. Also habe ich erwähnt, dass wir noch alle Ausnahmen kompensieren , die über die API ausgelöst werden könnten. Das ist einer von ihnen. Dies ist eine 43, die eine nicht autorisierte Ausnahme ist. Das Problem ist, dass wir damals, als wir das Hotel Lot Spender testen, autorisierten Administrator auf den gesamten Blatttypen Controller gesetzt hatten. Also wissen Sie, dass dieser Mitarbeiter die Liste der Blatttypen für ihn anzeigen muss. Die Anwendung stellt diese Anforderung für diesen Endpunkt, aber er ist kein Administrator. Also, was wir hier tun können, ist t der Autor ist aus oder zumindest die Rollen Bestimmung aus der autorisierten und nur diejenigen autorisieren, die die Daten erweitern, so dass der Beitrag PUT und löschen Sie diese Anpassungen vorgenommen. Wir können diesen Vorgang noch einmal versuchen. Und voila, also nein, wir können sicher dort als Angestellter navigieren. Lassen Sie uns also versuchen, sich für Urlaubsblätter zu bewerben. Also ich glaube, dass diese Überschrift, Sie können sehen, dass es den ganzen Weg zurück zum Januar, ich denke, der Anfang der Zeit, können wir immer Standardwerte setzen, weil Sie wahrscheinlich nicht wollen, dass die Weite der Zeit. Aber das werden wir nicht tun. Farnell, was ich tun werde, ist einfach den ersten Januar bis zum 5. Januar auszuwählen und zu bemerken, dass es Monat ist, das Jahr. Das ist das Format, das es verwendet. All das ist anpassbar, aber wir kommen nicht in das ganze Original. Also Urlaub Urlaub. Und wenn ich dann möchte, bekomme ich einen weiteren Fehler. Dieser Fehler sagt also, dass der Parameter nicht null sein kann. Also vermute ich, dass dies ein Pfeil ist von unserer API zurückkommt, der nicht noch einmal behandelt wird, aber lassen Sie uns in den Debugging-Modus gehen und genau sehen, was das Problem ist. Und hier ist der Täter. Der coole Teil ist auf uns versuchen, die E-Mail-Adresse zu bekommen. Also lassen Sie mich ein wenig zurückverfolgen. Wir haben den Benutzer, wir haben die Ansprüche. Und wenn Sie da reinschauen, haben wir die E-Mail-Adresse Anspruch. In Ordnung. So ist die E-Mail-Adresse vorhanden. Ich glaube jedoch, dass ich hier den falschen Anspruchswert verwende. Sagen Sie, wenn ich zu dem generierten JWT zurückgehe , der sich im Authentifizierungsdienst befindet. Ich habe den gleichen Anspruchsnamen verwendet, der einfach E-Mail war. Richtig. Wenn ich also mit der rechten Maustaste oder bei gedrückter Ctrl-Taste klicke, werden Sie sehen, dass es nur eine statische Text-E-Mail ist. Im Gegensatz dazu ist es tatsächlich zu sehen, dass sauber mit einem anderen Schlüssel. Und dieser Schlüssel passt besser zum XML-Soap-Schema. Und dieser Anspruchstyp würde tatsächlich, oder dieser Text wäre tatsächlich in sauberen Typen vorhanden. Also lassen Sie mich anhalten und gehen Sie weiter und ändern Sie das zu sauberen Typen dachte E-Mail. So ist es beim Abrufen der E-Mail-Adresse fehlgeschlagen und deshalb haben wir es nicht getan. Nun, du hast diesen Fehler, oder? Wenn wir also unsere Urlaubsanforderungstabelle überprüfen, bin ich mir ziemlich sicher, dass wir tatsächlich einige Daten sehen werden, oder? So sehen Sie hier, wir haben Urlaub und es ist daher jedes Mal, dass es gekauft wurde, richtig? So funktioniert es in der Tat. Es scheiterte nur beim Abrufen der E-Mail-Adresse. Mit diesem Fix sollten wir in der Lage sein, ungehindert weiterzumachen. Aber dann sehen Sie, dass etwas völlig anderes mit der Schlüsseloperation den Fehler verursacht hat, weshalb wir diesen ganzen Versuch versucht haben einfach die E-Mail zu senden, ohne alles andere zu belästigen. Nun, dann sehen wir, dass dies auch ein Scheitern ist. Zugegeben, wir haben es gerade repariert. Nun, wir könnten das theoretisch nehmen und es auch innerhalb des Try-Catches platzieren , so dass alles, was E-Mail betrifft, keinen Fehler auslöst. Jetzt, da wir den Anfrageprozess haben, lassen Sie uns keine Pause machen und wenn wir zurückkommen, schauen wir uns ihren Genehmigungsprozess an. 35. Einrichten: Nun, da wir unsere Urlaubsanfrage an den Angestellten haben, sagte: Nicht. Wir müssen tatsächlich einige andere Dinge einfügen, damit der Administrator die ausstehenden Anfragen tatsächlich sehen und genehmigen oder ablehnen kann. Nun, dies kommt mit einigen bahnbrechenden Änderungen, um die Handler und einige andere Anfragen zu lösen, einige der Details, einige Dinge, die wir bis zu diesem Punkt getan haben, aber wie üblich, werde ich Sie einfach durch alle Änderungen führen, die irgendwo benötigt werden, um zu beginnen dem Fett, das tatsächlich voran ging und erstellt wurde , dass Kostenkonstanten Klasse für die Anspruchstypen diskutiert werden. Entfernen der magischen Strings wie das Einfügen von UID Viele-Körper, richtig? Also habe ich eine benutzerdefinierte Anspruchstypen erstellt, nur eine öffentliche statische Klasse. Es ist in Konstanten unter dem Anwendungsprojekt. Und wir haben öffentliche Nachteile String UID gleich UID. Dies ermöglicht es uns nun im Auth Service, Kostüm-Phänotypen Punkt UID zu sagen und das in und überall sonst zu übergeben , wo wir möglicherweise auf diesen Küsten-Plain-Typ verweisen müssen , wie wir es in den anderen Handlern getan haben. Dann können wir einfach voran gehen und sagen, benutzerdefinierte Anspruchstypen dot UID. Kennen Sie eine andere Änderung, die ich mache, ist unser Benutzerdienst. Ich hatte eine Methode, dass alle Mitarbeiter jetzt eine andere haben, um nur einen Mitarbeiter basierend auf der Benutzer-ID zu erhalten. In Ordnung, also bei der Implementierung dieser Methode sage ich im Grunde nur, dass ich den Mitarbeiter nach ID finden und dann gebe ich ein neues Mitarbeiterobjekt mit den verschiedenen Feldern zurück. Wissen, dass ich auch unsere Urlaubsanforderungsliste, DTO, aktualisiert habe, und ich habe die Startzeitstartdaten hinzugefügt, und tatsächlich waren diese vorher nicht da, sowie das Mitarbeiterobjekt und die anfordernde Mitarbeiter-ID. Also wissen Sie, wenn der Administrator die Liste der Anfragen anzeigt, kann er sehen, was die Anfragen, die Start- und Enddaten der cetera Anfrage, sowie die Details der Person, die es angefordert hat, hätte eine ähnliche Änderungen an den Urlaubsanfragen, bei denen wir sichergestellt haben, dass Mitarbeiterinformationen enthalten. Nun, eine schnelle Änderung des Mappers und an dieser Stelle ist optional, weil ich möchte, dass Sie kritisch denken, nicht nur tun, was ich tue, sondern darüber nachdenken. Wir haben ein Feld namens Daten in den Urlaub Anfragen Domäne Objekte angefordert. Das wurde so erstellt, wie es vom vorherigen System modelliert wurde. Denken Sie nun daran, dass wir das System verfeinern und einige der Entlassungen und Zitate Schnecken loswerden. Und ich denke, das ist eines dieser Angebote läuft, weil das Datum Anfragen, die wirklich das Datum erstellt ist. Also erfassen wir bereits das Datum. Jeder Datensatz wird erstellt. Ich muss das angeforderte nicht erneut eingeben, und ehrlich gesagt haben wir das nicht in einem Handler getan, als die Anfrage einging. Was ich hier mache, ist, dass ich tatsächlich ein Mapping mache, unser benutzerdefiniertes Mapping für unsere bestimmten Felder. Ich sehe also, dass, wenn Sie vom Domänenobjekt zum DTO zuordnen, im Detail oder im Ziel suchen und das angeforderte Datumsfeld abrufen. Und dann möchte ich, dass das direkt auf das, was im kreativen Bereich ist, abgebildet wird und das Anforderungsdomänenobjekt belassen wird. In Ordnung, also noch einmal, das ist optional. Welche Aufrichtigkeit, wie die Gebühren, die ich Ihnen nur zeigen, die Macht des Herbst-oberen hilft uns, nur gewachsen, stellen Sie sicher, dass alle Daten da sind, es ist relevant und angemessen Ort. Jetzt gehen Sie zu unseren Handlern. Also habe ich einige Änderungen im Urlaubsanforderungs-Handler vorgenommen und Zuweisung und Verlust sowohl für die Liste als auch für das Detail belassen. Also werde ich mit der Liste beginnen, da diese, die ich denke, mehr Änderungen hat als nicht. Also eins, ich habe die Anfrage geändert, um dieses Flag zu sagen, ist im Benutzer angemeldet, was bedeutet, wir versuchen, die Liste der Urlaubsanfragen für den angemeldeten Benutzer für einen Administrator zu erhalten . Also in der Handler injiziere ich den HTTP-Kontext-Accessor ebenso wie ich ihn benutze. Glaub nicht, dass die vorher da sind. Ich weiß, dass einige sie injizieren und alles andere, was vorher nicht da war. Nein, fühlen Sie sich frei, weiterzumachen und sich zu replizieren. Aber dann innerhalb des Handlers, was ich anders mache, nein, ich initialisiere die Urlaubsanfragen dieses Top, Top. Und ich habe eine andere Liste für das Detail, das zurückgegeben wird, was in diesem Fall ist verlassen Anfragen Liste PTO. Dann überprüfe ich, ob die Anfrage sagt, dass es für den angemeldeten Benutzer ist oder nicht, richtig? Wenn es also für den angemeldeten Benutzer ist, möchte ich diese Benutzer-ID dort abrufen. Ich benutze meine Konstante, sehe, wie schön und sauber das aussieht. Alles klar, also bekomme ich die Benutzer-ID und dann habe ich tatsächlich eine andere Methode implementiert, um Urlaubsanforderungen mit Details relativ zur Benutzer-ID zu erhalten. Also lassen Sie uns zu dieser Methodenimplementierung gehen. Also hinterlasse ich im Vertrag Anfragen, dass ich Urlaubsanfragen mit Details bekommen muss, die ursprüngliche, die wir zusammen geschrieben haben und diese neue mit der String-Benutzer-ID. So dass man mit der Benutzer-ID grundsätzlich nur eine Bedingung hinzufügt , bei der die anfordernde ID im Datensatz gleich der übergebenen Benutzer-ID ist. Wir fügen immer noch die Blatttyp-Details hinzu und senden diese Liste zurück. Nachdem ich all das getan hatte, habe ich den Benutzerdienst verwendet, um den Mitarbeiter relativ zur Benutzer-ID zu erhalten, die dort ist. Und dann mache ich eine Zuordnung vom Domänenobjekt in unser Detail. Dann weisen wir für jedes Anforderungsobjekt in der Liste der Anfragen oder Details diesen Wert für die Mitarbeiter zu. Das wäre also noch einmal, wenn ich als Benutzer angemeldet bin und meine Liste der Anfragen sehen wollte. Das wird damit umgehen. Nun, wenn der Administrator es anfordert, ist es ziemlich dasselbe wie vorher, wo wir nur alle mit den Details bekommen. Und dann werden wir für jede Anfrage tatsächlich den Angestellten im laufenden Betrieb nachschlagen, oder? Also, während wir den Mitarbeiter kennen, weil ich der angemeldete Benutzer bin, so ist es nur einer von mir. Wir wissen nicht, dass es viele verschiedene Mitarbeiter gibt. Also für jede Anfrage werden wir diesen Mitarbeiter holen und ihn in das hineinlegen. Und am Ende des Tages geben wir die Anfragen zurück. Ebenso mache ich eine ähnliche Operation für die Urlaubsanweisungen, bei der ich alle Zuweisungen aus der Datenbank hole , haben eine ähnliche Methode und so ziemlich sieht dieser Code genauso aus. Alles klar, so wie wir die naive Zuteilung Urlaub Anfrage mit Details relativ zur Benutzer-ID hinzufügen . Es ist die gleiche Art und Weise implementierte Methode wie die für oder verlassen Zuordnungen, bei denen die Mitarbeiter-ID die Benutzer-ID ist und wir die gleiche if-Anweisung sind. Wir haben die gleiche Art von Überschwemmung zu unserer Bitte hinzugefügt, oder? Also fragen Sie uns, wer eingeloggt ist und dann haben wir die if-Anweisung. Wenn es eingeloggt ist, dann so ziemlich das gleiche Verfahren wie wir gerade gesehen haben. Relativ zu verlassenen Zuteilungen. Allerdings habe ich dann Urlaub Anfragen Detail bekommen. Also, das ist, wenn Sie wollen einen Urlaub Anfragen. Stellen Sie sich das vor. Wenn der Administrator die Liste der Urlaubsanfragen sieht, muss er auf diese Urlaubsanfrage klicken, um dann zu einem Bildschirm zu gehen, um zu sehen, ob es aussteht, ob es genehmigt ist oder Hunderte genehmigen oder abgelehnt werden können. Richtig. Also habe ich die Get-Anfragen mit Details geändert , wo ich in diese Zeile eingefügt habe, um die Mitarbeiterinformationen aufzunehmen. So ziemlich alle Modifikationen sind bisher nur in das Feuer geworfen, das wir in die Mitarbeiterinformationen setzen müssen. Da wir also diese Anforderungsklasse aktualisiert haben,müssen wir wissen, dass müssen wir wissen, unser Endpunkt oder unser Verhalten diesen neuen Parameter widerspiegelt, richtig? Also auf dem Weg, ich werde in einem Boolean passieren. Ist es der angemeldete Benutzer, nach dem wir suchen? Wenn es das ist, was ich in Stürze stecke, richtig? So können Sie einen Standardparameter einfügen, bei dem, wenn Sie keinen Wert angeben, falsch ist, richtig? Also, unabhängig von seinem Wert, werden wir es in das Anforderungsobjekt übergeben und dann wird der Handler die Entscheidung treffen, wie wir es gerade gesehen haben. Also habe ich dies sowohl in den Urlaubsanforderungen als auch in den Leave Requests Handler getan. Wie üblich, wenn Sie Ihre EPA aktualisieren, alles, was das Blau gedreht hat, um etwas im Controller zu haben, möchten Sie erneut ausführen und tauschen und eine neue Kopie dieses Client-Codes erhalten. Ich möchte nicht zurück zu unserer Client-Anwendung springen. Wir werden uns unseren Kontrast ansehen. Die nächsten paar, auf die ich unbedingt achten möchte, wären die Genehmigung der Anfrage und die Liste der Admin-Urlaubsanfragen. Okay, und wir müssen auch Urlaubsanfragen nach ID bekommen. Also müssen wenigstens diese drei jetzt umgesetzt werden. Also habe ich dort andere Methoden, und am Ende dieses Kurses werden sie implementiert. Aber ich werde nicht zu viel Zeitfenster auf dem Kaninchenloch verbringen zu versuchen, jedes einzelne Feature in. Für dieses Modul konzentrieren wir uns nur darauf, dass der Mitarbeiter um Urlaub bitten kann und dass der Administrator es genehmigen oder ablehnen kann. Nachdem Sie diese drei Methoden in den Vertrag aufgenommen haben, gehen wir zur Implementierung über. Also natürlich bin ich mir sicher, dass Sie Ihren Client-Code aktualisiert haben. Also sollte alles, was ich hier habe, für dich arbeiten. Also für die genehmigte Urlaubsanforderung, was wir tun, ist int id und das Flag oder das Boolean zu sehen, ist es genehmigt Ja oder nein. Dann werden wir zu formulieren oder Anfragen, wo wir setzen Änderung Urlaub Antrag Genehmigung Detail, und wir übergeben in, dass genehmigt und die ID. Und dann warten wir auf den Client, der die Änderungsgenehmigung async aufruft, wo er die ID und die Anfrage sendet. Unsere Erlaubnisanfrage ist ziemlich einfach. Es gibt nur Rückgabeanfragen Ansichtsmodell. Wir fügen natürlich unser Inhaber-Token hinzu, was wir auch in der genehmigen die Anfrage getan haben. Und dann gehen wir voran und versuchen Fitch von den Get-go verlassen Anfragen, erhalten eine Synchronisierung mit meiner ID und geben die gewickelte Version der Urlaubsanforderung in Form der Blattanforderung ViewModel zurück. Wir werden uns das noch einmal in ein paar ansehen. Nächste bemerkenswerte Methode wäre die get admin verlassen Anfragen pro Liste. Jetzt werde ich erklären, was ich in der ursprünglichen Anwendung auf das was wir getan hatten, war, dass wir alle Urlaubsanträge bekamen und wir versuchten, sie zu gruppieren und dann. Finden Sie heraus, ist es für die gesamte Urlaubsanträge, ist es für wie viele genehmigt werden ausstehend, et cetera, et cetera? Das ist genau das, was ich hier mache. Also bekomme ich alle Urlaubsanfragen und Notizen dieses Mal, wenn ich diesen Parameter in User Doppelpunkt false angemeldet habe. Ich benenne nur den Umfang. Dieser Teil ist eigentlich optional, aber ich finde es nützlich. Das ist, ich kann mich nicht erinnern, was der Wert wirklich in Bezug auf den Funktionsaufruf bedeutet. Aber ich übergebe Fälle, weil dies nicht der angemeldete Benutzer ist. Das ist der Admin, richtig? Also der Administrator erhält alle Urlaubsanfragen und dann erstelle ich nur dieses Modell Admin verlassen Anfragen Ansichtsmodell. Und wir übergeben die Gesamtzahl der Anfragen, wie viele genehmigt, abgelehnt und in der Liste der Urlaubsanfragen im Allgemeinen, und wir geben das Modell zurück. In Ordnung, also wieder einmal, alles passiert schweres Heben innerhalb des Dienstes? Nein, innerhalb unserer Mapping-Konfigurationen habe ich das aktualisiert, um einige der neuen Mappings wiederzugeben, die wir erwarten können. Also für einen Urlaub Anfrage Detail Anfrage VM zu verlassen, gibt es einen leichten Unterschied im Datentyp zwischen den Taten. In Ordnung, also auf der einen Seite haben wir Datetime, aber dann gibt uns das Detail, das über oder in Swag-Code generiert wird , tatsächlich einen Datetime-Offset. Ich bin mir nicht ganz sicher, warum es das tut, aber die Lösung wäre, dass wir beim Mapping nur vier Mitglieder ordentlich angefordert sagen, gehen Sie voran und ordnen Sie es von der angeforderten Punkt-Punkt-Zeit ab. Und wir tun das für das Startdatum, und wir tun das für das Enddatum. Und das wird sich tatsächlich um diesen Fehler kümmern. Wenn Sie dies nicht tun, wenn Sie es testen möchten, können Sie diese auskommentieren. Versuchen Sie, den Code auszuführen, für den eine Zuordnung erforderlich wäre. Und dann würden Sie sehen, dass der obere Herbstfehler sagt, dass die Zuordnung für die Beta-Felder fehlschlägt. In Ordnung, also können Sie das für die Urlaubsanforderungen tun, um Anfragen zu verlassen, VM, Anforderungslistendetails an die Urlaubsanforderungs-VM zu überlassen. Und dann habe ich neben diesen neuen auch eine hier für den Mitarbeiter, wo ich auch die Mitarbeiter-VM erstellt habe, die genau so aussieht, als ob der Mitarbeiter ETO innerhalb der Urlaubsanforderungsanforderungs-View-Modelldatei kennt. Lassen Sie uns nur einige der Ansichtsmodelle überprüfen, zumindest diejenigen, die absolut notwendig sind, um diese Aktivität abzuschließen. Also haben wir die Mitarbeiter-VM mit Mitarbeiter innerhalb dieser Ansichtsmodelle hinzugefügt, natürlich werden wir letztendlich zwei Eigenschaften mit dem gleichen Namen sehen. Es wird versuchen, sie zu kartieren, oder? Es wird also impliziert, dass der Mitarbeiter dem Mitarbeiter vom Detail bis zum ViewModel zuordnen wird, richtig? Wir haben auch die Admin-Anfrage ViewModel, die wir nicht unbedingt vorher gesucht haben, nein. Das ist also wie diese Felder und Gesamtanforderungen, genehmigte Anfragen, ausstehende Anfragen, abgelehnte Anfragen und die Liste der Urlaubsanforderungen. Sie können also fortfahren und sicherstellen, dass Sie eine Repräsentation für das ViewModel in Ihrem Code haben. Aber zurück zu unserem Urlaub Anfragen Controller ist C. Sie wissen, dass ich drei neue Aktionen sind 14, der Index, eine für die Details und eine um Anfragen zu genehmigen. Also Index, der Modell nehmen wird und dieses Modell vom Typ admin verlassen Anfragen View VM oder was nennt er den Urlaub Request Service dot get, admin Hebel, Questliste sind der Administrator wird diese Seite sehen , wo noch einmal Diese Statistiken und die Liste der ausstehenden Anfragen werden angezeigt. Unsere Detailmethode wird grundsätzlich da sein wenn sie die Liste sehen und sie auf eines der Elemente klicken. Und dann wollen wir gehen und holen, die Anfragen mit all seinen Details verlassen und die Ansicht entsprechend zurückgeben. Dann haben wir die Approve Requests, nicht genehmigen Anfragen werden im Grunde sehen gehen Sie voran und genehmigen Sie die Anfrage, es HTTP-Post. Also werden wir eine Farm auf dieser Seite setzen, wo wir das Übergeben dieser Urlaubsanforderungs-ID als auch, ob es genehmigt ist oder nicht. Also, wenn sie genehmigen oder ablehnen, wird es das passieren. Und dann sehen Sie, wie es zur API, zum Handler und was passiert, bevor wir diese Ansichten implementieren. Ich möchte jedoch nur, dass wir das volle Ausmaß verfolgen, was passiert, wenn es genehmigt wird. Also werde ich zu den Updates springen, zum Request-Handler, der auch einige Änderungen erfahren hat. Und ich führe Sie direkt durch. Es ist natürlich, dass Sie pausieren und replizieren, wie Sie müssen. Also wissen wir, dass das verlassen Qi Shun Repository zusätzlich zu allem anderen, was in diese Datei injiziert wurde. Und der Grund dafür ist, dass wir in der Lage sein müssen, die Zuteilung abzuziehen, wenn eine Genehmigung vorliegt. Was wir hier tun, ist, unsere behandelte Methode dafür neu zu gestalten. Also bekomme ich zuerst die Urlaubsanfragen, und dann sehe ich, ob wir es mit einem Urlaubsanforderungsdetail zu tun haben, als ich die Validierung ausführen möchte , weil was ursprünglich passiert ist oder wie wir den Code ursprünglich geschrieben haben, die Validierungscode ausgeführt wurde, unabhängig davon, dass dies null ist oder nicht. Wissen Sie, ob der Validierungstest, um unsere Null zu validieren, dann wird das auch einen Fehler werfen. Und schmeiß alles raus. Also validieren wir nur unsere Urlaubsanfrage DTO, wenn es vorhanden ist. Und dann, wenn alles in Ordnung ist, machen wir unsere Kartierung und unsere Updates. Jetzt. Andernfalls, wenn es die Änderung dv Anforderungsdetails ist, die nicht null ist, was in diesem Fall der Genehmigung es dann nicht ist, anstatt auf die verlassen Anforderungen Repository-Änderungsstatusmethode zu warten die in der Anforderung übergeben wird. Und das Fett, das wir wollten, unsere bewiesen. Dann werde ich sagen, wenn der Anforderungspunkt Genehmigungsdetails ändert, das genehmigt ist, Punktwert, wenn das wahr ist, richtig? Es ist alles, was wirklich gleichwertig mit wahr bewertet. Aber natürlich, wenn Sie mit Booleans zu tun haben, müssen Sie nicht unbedingt das Äquivalent zu true sehen. Wir können nur sehen, ob der Boolean, oder? Und wir müssen uns keine Sorgen um eine weitere Ausnahme machen, denn es sollte immer sein, es sollte immer einen Wert haben. Also, das ist ein anderes Objekt, das wir in Richtung Detail machen können weil ich jetzt denke, dass wir es nullable gemacht haben, was nein, wir denken, dass es falsch ist. Es sollte immer einen Wert haben, so sehr ich diesen Boolean entfernen werde und wir können unseren Swag-Client-Code entsprechend aktualisieren, aber später können wir das tun. Also aktualisiere ich dieses Detail, um immer entweder wahr oder falsch zu sein. Also, wenn es wahr ist, dann bekommen wir die Zuteilung für den Mitarbeiter. So var Zuteilung ist gleich, um Benutzeranwendungen zu erhalten. Dies ist eine neue Methode. Also diese neue Methode, wieder einmal, Sie setzen es in den Vertrag. Aber wenn Sie es implementieren, nimmt es im Grunde die Zeichenfolge mit der Benutzer-ID und der Blatttyp-ID. Also gehen wir und sagen, besorgen Sie mir die Blattzuweisung. Erstens, unsere Standardasynchronisierung, wobei die Mitarbeiter-ID viel die Benutzer-ID ist, die übergeben wird und die Blatttyp-ID mit der übergebenen übereinstimmt. Nachdem wir all das getan haben, geben wir den anfragenden Mitarbeiter neben den Urlaubsanfragen weiter. Also haben wir hier den Schaltwunsch. Wir haben den Mitarbeiter, der es angefordert hat und wir kennen den Blatttyp mit freundlicher Genehmigung der Anfrage noch einmal. Und dann sagen wir: Besorgen Sie mir die Anzahl der B's, richtig? So haben wir bereits gesehen, dass bei der Erstellung eher in der Anfrage sind, wie viele D's beantragt werden. In dieser Situation könnten Sie eine andere Entscheidung treffen. Sie könnten sich entscheiden, die Anzahl der Ds in der Datenbank von Anfang an zu speichern oder im laufenden Betrieb wie wir es tun, nein. Das liegt also an dir. So oder so bekommen wir die Anzahl der Biere, wir gehen voran und übernehmen die Anzahl dieser aus der d wird von der Anzahl der Tage für die Zuteilung angefordert. Und dann führen wir ein Update für diese Zuweisung aus, dann kehren wir zurück. Nein, in Bezug auf unsere Ansichten, dass viel unsere Controller, haben wir den Index erstellt und wir haben die Details erstellt. Wahrheit gesagt, der Index ist eine geteilte Kopie dessen, was aus dem alten Code kommt. Also, wenn Sie den gesamten Quellcode heruntergeladen haben oder Sie können einfach in Ordnung, Es ist auf GitHub. Sie können tatsächlich alles aus dieser übereinstimmenden Indexseite für Urlaubsanfragen nehmen und bitte hier habe ich nichts geändert. Alle Änderungen, die erforderlich sind, würden auf Benennungsunterschiede zurückzuführen sein. Zum Beispiel habe ich hier item.name Mitarbeiter anstelle von item.name, der Mitarbeiter anfordert. Außerhalb davon ist der Code jedoch ziemlich derselbe. Nun, für die Details, Ich habe einige Änderungen vorgenommen, weil wir im ursprünglichen Code, haben wir diesen Warnungsabschnitt auf dreimal wiederholt. Und was wir taten, war, dass wir sagten, wenn genehmigt, dann zeigen Sie diesen Alert-Code mit einem anderen Klassennamen an verschiedenen versteckten Text. Sonst, wenn es wahr ist, dann zeig es wieder mit Recht. Also, anstatt dies zu wiederholen und das ist ein weiterer Teil, trocken, wiederholen Sie sich nicht. Geben Sie also Faktor ein, Sie wollen immer sagen, nun, etwas muss irgendwann wiederholt werden, oder? Oder eine Operation muss erneut ausgeführt werden. Aber was kann ich mit dem geringsten Weg des Widerstands R wiederholen, was auf lange Sicht am einfachsten zu halten wäre. Also mein Refactoring dessen, was in den ursprünglichen Details pH gemacht wurde , wäre, dass ich hier zwei Variablen erstelle. Eine interessante, eine für Überschrift, Überschrift Text. Und dann, wenn die Genehmigung null ist, gebe ich ClassName und das Schlagen nimmt ihre Werte an. Wenn es wahr ist, Ich gebe ihnen verschiedene Werte, et cetera, für. Und dann lade ich das div mit dem anderen zu einer Zeit, wo ich diesen Klassennamen und Überschriften dynamisch übergebe, weil alles andere in dieser Warnung unabhängig davon gleich sein wird, richtig? Also sage ich Mitarbeiter Name und dann setze ich in Modell lot Mitarbeiter Vornamen und Nachnamen. Das angeforderte Datum ist, dass sie aufgefordert, aus dem Modell zurückzukommen. Und dann ist so ziemlich alles andere gleich bis zum letzten Teil, wo wir prüfen, ob es genehmigt ist oder nicht. Anstatt Schaltflächen zu verknüpfen, da der ursprüngliche Code sie jemals in Farmen oben hatte , wo sie diskutierten, warum Foren viel sicherer sind. Also für Methodenpost ist die Axon Beweis-Anforderung. Und in diesem habe ich die ID, die eine versteckte ist, und es hat einen Wert für die Modulus-Idee auch ein anderes versteckt, das den Namen genehmigt hat und der Wert wahr ist. Ich wiederhole diesen Feed für die Ablehnung, außer der Wert für die genehmigte ist falsch. Wenn sie also auf eine dieser Schaltflächen klicken, wird Approve Requests aufrufen, die dann ID und genehmigte Kosten erhalten, die nicht tun, haben wir einfach durchgegangen, was der Handler mit all diesen Informationen macht. Ordnung, also haben wir dieses Modul schon seit einiger Zeit, und das ist normalerweise das schwierigste und zeitaufwendigste Modul. Ich habe versucht, die Zeit so weit wie möglich zu reduzieren, aber dann gibt es noch viel mehr zu tun, aber zumindest haben Sie die grundlegenden Konzepte, damit Sie es nehmen und weitermachen können. Lassen Sie uns also nur eine Vorschau, wie diese Urlaubsanfragen aus Sicht des Admins aussehen wird. Und wöchentliche Spaltanfragen sehen die Liste der Urlaubsanfragen. Also habe ich bereits einen genehmigt und abgelehnt und so sieht dieser Code aus. Und das hier steht noch bevor und wir sehen das Startdatum, das Enddatum, den Urlaubsurlaubstyp, den Mitarbeiternamen, alles ist schön und, Sie wissen schon, spucken für uns. Also, wenn ich auf Überprüfung klicke, gehen wir zu der Seite, wo es sagt, ausstehende Genehmigung sie angefordert und dann kann ich genehmigen oder ablehnen. Wenn ich also auf Genehmigen klicke, wird es unter der Annahme umgeleitet, dass es keine Fehler gibt. Und tatsächlich gibt es einen Fehler. Alles klar, also das Problem hier ist, dass ich den Code aus dem Erstellen verwende, um die Berechnung durchzuführen, was völlig falsch ist, weil ich das Hebel-Anforderungsobjekt verwenden sollte und nicht Punkt verlassen Anfragen Details anfordern sollte, Richtig, lassen Sie mich das einfach aktualisieren und wir können diesen Vorgang wiederholen. In Ordnung, also versuchen wir es nochmal. Ich werde auf Genehmigen klicken. Und dort sehen wir, dass es nicht genehmigt ist. Wissen Sie, das Problem, das wir später ansprechen müssen ist die Tatsache, dass wir mehrere Operationen haben, die gegen mehrere Tabellen durchgeführt werden. Aber ratet mal, was passiert ist? Ein Teilnehmer und der andere Teil nicht, was bedeutet, dass dies genehmigt wurde, aber der Abzug passierte nicht, weil wir einen Fehler auf diesem See hatten. Richtig. Also haben wir die Genehmigung tatsächlich erfolgreich durchgeführt, aber dann ging der Abzugsteil nicht durch, so dass er nicht aktualisiert wurde. Und was wir tun wollen, ist, etwas wie unser Rollengeld zu tun, es sollte alles oder nichts sein. Also, wenn ein Teil Felder dann sollte alles fühlen. Hier kommt also die Arbeitseinheit ins Spiel oder auf Datenbankebene nennen wir sie Transaktionen. Später werden wir uns all diese Haushaltsprobleme mit unserer Anwendung ansehen. Immer wenn eine Anwendung so groß ist, müssen Sie auf diese Dinge achten. 36. Einheit für Chargen.: In dieser Lektion werden wir eine globale Ausnahmebehandlung Middleware für unsere API einrichten . Was passiert, ist, dass wir benutzerdefinierte Ausnahmen hatten , die wir fast am Anfang des Projekts erstellt haben. Wir haben an bestimmten Punkten in unseren Handlern Ausnahmen ausgelöst. Wir haben jedoch nicht unbedingt dem API-Ganzen mitgeteilt , dass es antworten soll, wenn Ausnahmen ausgelöst werden. Sie möchten also natürlich immer fehl, wenn es eine Art von Ausnahme gibt. Wir möchten einen Code zurücksenden, der auf die Art der Ausnahme hinweist. Zum Beispiel habe ich alle meine Update-Handler aktualisiert, um auch eine nicht gefundene Ausnahme zu werfen. Also, um es zu wissen, lassen Sie mich einfach das hier korrigieren. So offen zu wissen. Ich hatte den Code nicht. Wenn du den Code bereits hattest, dann ist das gut. Das ist ein Lob an dich, oder? Aber wir haben Validierungsausnahmen ausgelöst, wenn die Validierung fehlschlägt. Aber was passiert dann, wenn der zu findende Datensatz nicht telefonisch war, dann wollen wir eine nicht gefundene Ausnahme. Also habe ich hinzugefügt, dass bei jeder Überprüfung zu sehen, ob Urlaub Zuteilung gefunden wird, wenn der Urlaub Anfragen, Das ist ein Boot, um sein Telefon aktualisiert werden und wenn der Urlaub sorry, die Blattart, ihr Ziel. Wenn der Blatttyp Telefon ist, werfen wir einfach eine nicht gefundene Ausnahme. Ordnung? Die Ausnahme zu werfen ist also einfach genug. Es zu handhaben ist eine andere Sache. Beachten Sie also, dass es keine Versuchsfänge gibt. Es wäre irgendwie überwältigend vorwärts zu versuchen, den Versuch fangen und jeden einzelnen zu setzen. Was wir also tun werden, ist Einrichtung und Ausnahmebehandlung von Middleware auf API-Ebene, weil der Controller Medien verwendet, um es als Handler zu bezeichnen, aber wir haben auch hier keine Track-Fänge, also kehren wir immer zurück, okay? Aber dann gibt es Zeiten, in denen die Ausnahme ausgelöst wird und es OK, kann geworfen werden. Und in der API wirft buchstäblich nur ein zufälliges Antwortgeld auf den Client. Wir wollen sicherstellen, dass wir wissen, was geworfen wird. Also gehen Sie weiter und erstellen Sie einen neuen Ordner im API-Projekt namens Middleware. Und in diesem Ordner erstellen Sie eine Datei namens Exception Middleware. Das ist also unsere Cross-Exception-Middleware. Und ich werde Sie einfach durch das führen, was das im Web oder im Detail tun wird. Also haben wir eine Klasse in dieser Datei, in dieser anderen Klasse, die Fehlerdetails genannt wird. Ich führe dich erst durch die einfacheren Teile. Und Fehlerdetails haben nur den Fehlertyp und eine Fehlermeldung. Zumindest können wir dem Klienten immer mitteilen, dass es das ist, was schief gelaufen basierend auf dem Umstand, mit dem wir konfrontiert sind, richtig? Jetzt. Alles, was es gesagt hat, dass wir innerhalb der Klasse für außergewöhnliche Middleware haben, haben wir ein privates schreibgeschütztes Feld namens nächste, und das ist vom Typ Request Delegate. Also instanziieren wir das im Konstruktor. Und dann haben wir eine Methode namens Aufruf einer Senke. So rufen öffentliche AsyncTask async auf und es nimmt einen Parameter namens HTTP-Kontexte. Wir haben uns also bereits angesehen, was die HTTP-Kontexte uns erlauben. Grundsätzlich ermöglicht es uns, die Anfrage zu sehen, die Antwort, alles mit einem ganzen Workflow zwischen Client und Server ist innerhalb dieser HTTP-Kontexte gespeichert. Das wird sich also wie ein Abfangjäger verhalten, wird versuchen, zu sehen. Es wird sagen, machen Sie die nächste Option, die über die HTTP-Kontexte abgeschlossen werden sollte. Das ist im Grunde das, was das tut. Sie. Http-Kontexte machen Ihre nächste Option. Wenn es eine Ausnahme gibt, fangen wir sie an und dann werden wir damit umgehen. Jetzt gehen wir weiter, wie wir damit umgehen. So private Aufgabe Handle Ausnahme ist Senke, wo Sie den HTTP-Kontext und die Ausnahme, die abgefangen wurde. Wissen wir, dass wir nur sagen, dass wir eine Antwort als Anwendungsschrägstrich JSON haben wollen , weil es die API ist. Wir wissen also, dass alles, was wir reagieren, in Form von JSON sein wird. Wir setzen auch einen internen Standardserverfehler, HTTP-Statuscode der Schule standardmäßig auf das, was 500 ist. Dann werden wir sagen, das Ergebnis ist gleich, ich möchte niemals Objekte in eine neue Instanz von Pfeil mit der Ausnahmemeldung serialisieren . In Ordnung, also serialisieren wir all das in die Ergebnisse null, wenn wir zum Schalter gehen. Wo im Grunde zu sehen, welche Art von Ausnahme dies ist, weil Ausnahme der Basisdatentyp ist. Aber dann, wie wir gesehen haben, haben wir unsere eigenen Ausnahmen. Wir haben die Validierungsausnahme, wir haben die lassen Sie mich gehen die Butter Anfragen Ausnahme. Wir haben die nicht gefundene Ausnahme. So können wir für alle diese Buchhaltung für schlechte Anfrage zu berücksichtigen. Ich bilanziere keine Validierung. Mich. Gehen Sie weiter und aktualisieren Sie das. Was wir jetzt hier tun, ist mir zu sagen, welche Art von Ausnahme es ist. Ich weiß, es ist eine Ausnahme, aber welcher Typ war es wirklich nicht so schlechte Anfrage. Eine Ausnahme der Validierung verdankt eher, dass ich nicht gefunden werde. Basierend auf dem einen Punkt, der zu tun ist, werden wir den Status quo ändern. Es ist also standardmäßig 50, 100. heißt, wenn es nur das Unaußergewöhnliche war, vielleicht war es auf Datenbankebene Fehler, vielleicht war es ein Netzwerkfehler, den wir nicht schließen können. Und vier, dann ist es definitiv eine 500. 500 bedeutet, dass es sich um ein System handelt, das System, das von der API verwendet wird, es ist der Fehler des Systems. Schlechte Anfragen würden jedoch darauf hindeuten, dass Sie als Client Schuld haben, aber Sie haben mir Mülldaten gesendet. Also werde ich Ihnen sagen, dass es eine schlechte Bitte ist, was vor 400 Jahren ist. Wenn es sich um eine Validierungsausnahme handelt, ist das auch eine Art schlechte Anfrage, weil Sie mir nur Daten gesendet haben, aber Sie können immer durchschauen und sehen, welchen anderen Code für die Art der Ausnahme oder besser könnte. Ordnung, aber dann willst du immer mit Fehlercodes im 400 Bereich bleiben, richtig? Das ist, wo wir sind. Also meine ich dir, das ist allein. Also dieser sagt Aber Anfrage und dann nicht gefunden Ausnahme ist eine 40 für das bedeutet, dass ich nicht finden konnte, wonach Sie suchen. Also 40 für so, wenn keiner von ihnen der Fall war, dann brechen wir einfach und das wäre als 500 bleiben. Dann sehen wir antworten mit dem Statuscode und kehren mit dem Ergebnis zurück. Ergebnis, was bedeutet, dass die ganze Nachricht, die Teil der Ausnahmemeldung war. Also denken Sie daran, dass, wenn wir unsere Ausnahmen einrichten oder unsere Ausnahmen von unseren Jägern werfen, immer die Nachricht saßen. Und diese Nachricht wird hier serialisiert. Ich werde geschickt, dass Bokeh diese Antwort ausgelöst hat. Null, wenn Sie möchten, dass es etwas expliziter ist. Da alles, was wir tun, ist, über Pfeil mit Ausnahmemeldung zu senden, könnten wir unsere Fehlerdetails verwenden. Ich hätte neue Fehlerdetails sagen können und dann eine Fehlermeldung wäre die Nachricht und der Fehlertyp könnte etwas anderes sein. Also würde ich sagen, Eric Type Tool und dann wahrscheinlich sagen nur Scheitern, unseren Fehler, was auch immer es ist, damit Sie kreativ werden können. Ich meine, es liegt an dir, was sie wieder in ihrer Antwort bekommen würden, was auch immer du dort hingelegt hast. Also ein Modus, in dem wir die Einrichtung dieser Middleware abgeschlossen haben, müssen wir zur Startdatei für API springen. Und Einsatz der Konfigurieren sexuellen. Wir werden ihm sagen, dass sie die Middleware benutzen soll. Also werde ich es einfach direkt über alles andere machen. Ich möchte nicht sagen, dass DOT Middleware verwendet, Ausnahme auf Middleware. Gehen Sie weiter und fügen Sie alle fehlenden Referenzen hinzu. Und da gehen wir. Also haben wir alle unsere Middleware versucht, global zu fangen und dann anmutig zu behandeln, wie sie auf jeden Kunden reagiert, der seine Berufung ist. Ich wollte nur noch einmal zur Implementierung zurückspringen und eine schnelle Anpassung vornehmen. Ich weiß nicht, warum ich hatte, wenn das anfangs aus. Mit den Ergebnissen für die Validierungsausnahme wollen wir definitiv, dass die Ausnahmefehler Buck in den Körper gehen, richtig? Also die Validierungsnachrichten, eine Sache, gut. Aber dann wollen wir, dass die Ergebnisse gleich der JSON-Serialisierung der Validierung der Pfeile sind, richtig? So haben Sie wieder viele Möglichkeiten, wie Sie mit der Situation umgehen können. Wir sitzen also standardmäßig die Ausnahmemeldung, aber wir überschreiben sie im Falle des Validierungsfehlers. Es wird also die Liste der Fehler sein. 37. Exception: Na gut, Leute, willkommen zurück. Diese Lektion basiert auf dem Fehlerpunkt, den wir gesehen haben, als wir den Genehmigungsstatus der Urlaubsanträge änderten. Wir sahen, dass ein Teil des Vorgangs abgeschlossen wurde und der andere Teil fehlgeschlagen ist. Aber dann brauchen wir beide Teile, um tatsächlich zu funktionieren, bevor wir die Datenbank aktualisieren können. Was wir jetzt tun, ist die Einrichtung einer Arbeitseinheit, die im Grunde besagt, dass ich all diese Arbeit zu erledigen habe. Ich habe all diese Berührungspunkte. Ich werde alle Operationen ausführen und dann einen letzten Commit in die Datenbank durchführen, wir werden entweder erfolgreich sein oder nicht. Also, was wir hatten, war jedes Repository, das Änderungen selbst speichert. Wenn dies also eine Operation gäbe, die zwei Repositories benötigt , um auf der einen Seite als die anderen Felder zu speichern, dann hätten wir konsistente Daten in der Datenbank und wir wollen das vermeiden. Also habe ich weitergemacht und diese Einheit des Arbeitsvertrags eingerichtet, damit wir wissen wo die Verträge in Ihrer Anwendung Persistenzordner I Arbeitseinheit leben. Es erbt von mir Einweg. Und es bezieht sich im Grunde nur auf die drei Repository-Schnittstellen, die wir kennen. Alles klar, also verlasse ich Zuweisung, lasse Anfragen und Blatttyp, und es hat eine Methode, die sagt, Knoten speichern Implementierung lebt in demselben Ordner wie die Implementierung für die anderen Repositories. Das ist also die Persistenzschicht Repositorys Ordnereinheit der Arbeit. In dieser Implementierung erben wir also von den Arbeitseinheiten. Wir haben unseren DB-Kontext injiziert. Alles klar, und wir haben auf das gesamte Repository verwiesen, also habe ich private Felder für jedes Repository. So falsch diese Datei verhält sich so, als würde ich mich für die Repositories registrieren, die wir haben, wollen die eindeutigen Repositories verwalten. Manchmal würde man tatsächlich eine Arbeitseinheit sehen, in der sie um die generischen Repositories aufgebaut ist. Also, und jede Implementierung wird nur generisch sein, weil es so viele einzigartige Methoden in unseren Repositories gibt , die das eindeutige Repository hier referenziert behalten möchten . Also später Kuppel, wir haben tatsächlich das öffentliche Eigentum, das viel ist jeder und lassen Sie mich einfach BreakLine, damit Sie es klarer sehen können. Also die Öffentlichkeit, ich verlasse Allokation Repository, es wird DV Anschuldigungen Repository genannt werden. Ich bin im Grunde, wir führen nur, ich bekomme, so dass wir sehen, Holen Sie mir das private Feld und wenn es null ist, eine neue Instanz derLeaf Allocation Repository-Implementierungzu initialisieren eine neue Instanz der Leaf Allocation Repository-Implementierung und in diesem Kontext zu übergeben, dass wir injizieren Sie es hinein. Denn denken Sie daran, dass jede Implementierung diesen Kontext in injiziert hat. Also, deshalb müssen wir sicherstellen, dass wir in den Kontext injizieren und dann an jeden weiterleiten. Diese drei Zeilen sehen also in den Namen und den Typen, auf die verwiesen wird, so ziemlich dieselbe Leiste aus. Dann haben wir eine Dispose-Methode, die im Hintergrund aufgerufen wird, wo wir nur den Kontext entsorgen und dann die endgültige Garbage Collection unterdrücken. Und dann wird unsere Aufgabe, zu speichern, unsere Änderungen zu speichern. Also mit anderen Worten, Sie werden alles tun würde setzen, würden wir hinzufügen, wird tun, was es ist. Diese Repositories müssen einzeln zu tun, aber dann machen wir eine letzte Save. In Ordnung, also nachdem Sie das implementiert haben oder all das repliziert haben. Werfen wir einen Blick auf einige der Änderungen, die in den anderen Repositories erforderlich sind. Beginnen wir also mit einem generischen Repository. Vor dem, was wir hatten, waren Einzelpersonen Speichern Änderungen in der Anzeige, die Lösch- und die Update-Methoden. Alles klar, jetzt bekomme ich Grönland, weil es keinen asynchronen Anruf mehr innerhalb dieser asynchronen Aufgaben gibt? Nun, wir können das später ansprechen, aber mein Punkt ist, dass ich alle Zeilen „Änderungen speichern“ von diesen speziellen Methoden entfernt habe , weil wir nicht wollen, dass sie sehen, ob wir mehrere Dinge tun müssen. Sie möchten etwas hinzufügen und etwas löschen und ein Update durchführen. Wir wollen ein letztes Commit in die Datenbank. Alle oder nichts pro Arbeitseinheit befinden sich in jedem Handler. Denn denken Sie daran, dass sich die Handler im Grunde mit Szenarien beschäftigen. Wir wollen also, dass das vollständige Szenario abgeschlossen ist, ganz oder gar nichts. Also haben wir alle Änderungen aus dem generischen Repository sowie aus jedem anderen einzelnen Repository entfernt , in dem möglicherweise ein Speichern von Änderungen verwendet wurde. So wie in Zuordnungen, bei denen der Durchschnitt Änderungen speichern musste, habe ich das entfernt. Und in den Urlaubsanfragen hatten wir die Änderungen speichern, die innerhalb dieser Methode durchgeführt wurden, um zu aktualisieren, richtig. Um den Genehmigungsstatus zu ändern, habe ich das alles entfernt. Jetzt mit diesen Remissionen müssen wir unsere Handler aktualisieren, um sich entsprechend anzupassen. Also werde ich zu den Erstellen-Urlaubsanfragen springen, und ich werde Ihnen genau zeigen, welche Art von Refactoring passieren würde. Erstens hätten wir mit zwei oder drei Repositories in diesem Handler interagiert. So hätte injiziert, ich verlasse Repository, Ich verlasse Allokation Repository, et cetera, et cetera. Ich weiß, dass wir nur injizieren oder eine Arbeitseinheit haben müssen. Und bevor ich weiter gehe, lassen Sie mich einfach darauf hinweisen, dass wir wissen, dass wir es anstelle der Persistenzdienste-Registrierung registrieren müssen . Dasselbe Ort, an dem du alle Repositories registriert hättest , wo wir gerade unsere Augeneinheit der Arbeit beginnen. Das macht es zu einem injizierbaren Komponenten. Also, jetzt können wir alle Einzelnen durch die I Einheit der Arbeit ersetzen. Nein, Sie sind mit einem Haufen FRD-Linien konfrontiert. Nun, wissen Sie, wo Sie den Unterstrich verlassen Typ Repository als privates Feld hatte. Sie können das jetzt durch Unit of Work Dot Leaf Type Repository ersetzen , da Sie ihm das gleiche Repository nur über die Arbeitseinheit geben. Das ist also wie unser Register für alle Repositories aus mir. Erwähnung davon vorhin. Also markiere ich nur alle Änderungen , die ich gemacht hätte, dass ich die Arbeitseinheit an der quadratischen Arbeitseinheit für das Urlaubs-Allokation-Repository verwende , Einheit von vier für das Urlaubsanforderungs-Repository. Und dann, wenn wir eine Operation haben, die Daten erweitert, machen wir ein Speichern. Siehst du das? Jetzt, während ich in diesem Create leave Request Handler bin, wollte ich nur auf einen anderen Fehlerpunkt hinweisen, den ich in meinen Tests gesehen habe und Sie wahrscheinlich begegnet sind und ich möchte nur, dass wir es hier ansprechen. Dann gibt es keine Zuteilung, weil ich versucht habe, einen Mutterschaftsurlaub bei einem Arbeitnehmer zu beantragen, der keinen Mutterschaftsurlaub hat. Sie haben also zwei Möglichkeiten, damit umzugehen. Erstens, Sie könnten nur filtern, dass Blatttypen Liste nur auf Urlaubstypen, die diesem Benutzer zugewiesen sind. So würde der Benutzer nie in der Lage sein, sich für etwas zu bewerben, für das er keine Zuteilung hat. Und ehrlich gesagt denke ich, dass das ein netter sauberer Weg ist, dies zu tun, schafft einen neuen Repository-Aufruf, bei dem Sie die spitzen Listen bekommen und Sie gesendet haben, aber nicht zuletzt denke ich, das ist einfach genug. Ich habe jedoch eine Anpassung in diesem Handler in der Zwischenzeit vorgenommen , um zu sagen, die Zuweisung zu bekommen. Also denken Sie daran, dass wir die Zuteilung haben und dann haben wir berechnet, dass die d angefordert wird. Und wenn das d angefordert, überschritten wird, dann haben wir einen Validierungsergebnisfehler hinzugefügt, richtig? Nun, was ich hier mache, ist, dass ich sehe, ob die Zuteilung nicht ist. Also mit der neuen Version von C Sharp, müssen Sie nicht sehen, ist äquivalent zu wissen, die Vakanz ist nein, oder? Wenn dies also als null zurückkommt, fügen wir einen Validierungsergebnisfehler für die Blatttyp-ID hinzu, der besagt, dass Sie keine Zuordnungen für diesen Blatttyp haben. Also, das ist eine einfache, wenn sonst Addition. Sie können fortfahren und das replizieren oder Sie können es selbst ausprobieren, um die gefilterte Liste für den bestimmten Benutzer zu erhalten , der kurz davor ist, den Urlaub anzufordern und nur die Blatttypen anzuzeigen, für die sie berechtigt sind, je nachdem, welches funktioniert. Nun springen wir zum Update-Leave Requests Command Handler, wo wir die echten Fehlerpunkte gesehen haben, die wir JETZT mit der Arbeitseinheit zu adressieren versuchen. Also noch einmal, injizieren Sie nur die Einheiten wurden in diesen Handler gezwungen. Und Sie werden sehen, dass es viel kompakter ist, oder? Und dann müssen Sie jede Zeile nur sagen, Einheiten sind vier Punkte das entsprechende Repository und Punkt Punkt die Methode. Wissen Sie, wann wir die Daten erweitern. Denken Sie daran, dass wir gesagt haben, wenn die Anfrage mit dem DTO kommt, dann gehen wir weiter und machen unsere Zuordnung namens Update. Und dann werde ich die Arbeitseinheiten anrufen, um zu retten. In Ordnung. Später, tun Sie nicht, wenn es die Genehmigung der Änderungsanforderung war, und hier haben wir den Fehler gesehen, wir werden fortfahren und ihre Genehmigung ändern. Und dann, wenn es genehmigt wurde, würde es die Zuteilung aktualisieren. Und dann arbeitete dieser, aber dann dieses eine Feld, so wurde es genehmigt und die Person diese nicht angenommen, das verursachte Inkonsistenz. Also nein, diese Person wäre für 10 Tage in Urlaub gegangen und kommen zurück und wir werden wieder kommen und sehen, dass es immer noch oft diese und zerbrochen plie und niemand würde bemerken. Wir wollen also sicherstellen, dass unser System nicht schuld ist. Richtig. So haben wir die Änderung des Genehmigungsstatus aktualisiert. Ordnung. Wenn es dann genehmigt ist, aktualisieren wir die Anzahl der Tage und speichern dann. Wenn dies fehlschlägt, geschieht dies in der Datenbank. Jetzt mit dieser Änderung und der Einheit, in der eingeführt wird, ist es tatsächlich ein größerer Faktor, weil Sie tatsächlich in jeden einzelnen Handler gehen müssen , der sich mit dem Augmentieren Daten und einer Injektoreinheit der Arbeit zu wahrscheinlich ältere Referenzen auf die Repositories ändern, alles über den Ort. Und dann drei, stellen Sie sicher, dass Sie die Speichermethode der Arbeitseinheit aufrufen. Jetzt, wo du diesen riesigen Risikofaktor gemacht hast, okay? Und vor allem, wenn Sie das mit dem Leaf Type Command Handler und anderen Konfliktpunkten getan haben , die kommen, sind unsere Unit-Tests. Denn denken Sie daran, dass wir zumindest die Unit-Tests für den Leaf Type Command Handler zusammen durchgeführt haben und wissen, dass Sie die Injektion ändern, Sie ändern etwas darüber. Wenn Sie also zu diesem Zeitpunkt kompilieren, würden Sie wahrscheinlich einige Fehler in den Testdateien bekommen weil bestimmte Dinge nicht mehr existieren. Das sind 12. Die Tatsache, dass sich die Operation im Allgemeinen geändert hat, müssen wir Künstler aktualisieren. Beginnen wir mit den Mocks , denn das ist wahrscheinlich, wo Sie den ersten Fehler bekommen, dass das Mach-Repo nicht mehr existiert oder die Spottjungen nicht mehr von dem Typ, den es braucht. Das ist in Ordnung. Also, was ich getan habe, ist eine neue Mock-Datei erstellt, die ich Mock-Einheiten der Arbeit nenne. Und es folgt dem gleichen Prinzip dem vorherigen Rauch, wo ich gerade einen Spott unserer Arbeitseinheit instanziiere. Es nennt sich Arbeitseinheiten. Das ist eine Methode. Und ich habe Spott, Sie werden w ist gleich einer neuen Instanz der Scheineinheit der Arbeit. Nein, ich habe den Typ „Mock Leaf“. Lassen Sie mich das Mock Leaf Typ Repo korrigieren. Damit hatten wir es zu tun, oder? Das ist also der Test, den wir geschrieben haben, um die Blatttypen zu testen. Wissen Sie, dass ich die Einheit verwende, in der ich das Repository innerhalb der Arbeitseinheit verspotten muss. Und ich habe bereits den Code, um die Einheiten des elif-Typ-Repositorys zu verspotten, sorry, richtig, also habe ich das schon. Diese Methode muss sich überhaupt nicht ändern. In Ordnung. Wir füllen es mit Testdaten und wir haben all das getan. Nein, ich muss diesen Mach in die Arbeitseinheit bringen. Also alles, was ich hier mache, ist Spott zu sehen. Der Typ Repo ist gleich dem Aufrufen dieser Mock-Klasse und dem Abrufen des Blatttyp-Repositorys. Und dann ist mein Setup-Hinweis, dass das Blatttyp-Repository dieses Mock-Objekt zurückgibt. Dann bringe ich diese Scheineinheiten der Arbeit zurück. Also jetzt im eigentlichen Test für den Blatttyp-Handler, und ich habe gerade einige der Zeilen kommentiert, nur um Ihnen zu zeigen, was genau ich geändert habe. Ich habe ein neues Feld vom Typ Mock I Arbeitseinheiten namens Mock eingeführt. Sie werden w, w Einheit der Arbeit. Und dann habe ich es innerhalb des Konstruktors instanziiert , indem ich meine Mock-Einheiten der Arbeit dot a2 Einheiten oder fork aufrufe. Danach bleibt alles andere gleich. Nicht ausrichten. Nun für mich, 42, 43, wo ich sehe, dass der Handler keine neue Instanz ist, die die Mock-Einheit der Arbeit nimmt , im Gegensatz zu der Mock-Welligkeit, die zuvor verwendet wurde und dieses Objekt, dann wird alles andere fließen. Also zumindest nicht in den Tests müssen wir sagen, Mock Unit des Work-Punkt-Objekts, dot leaf type repository bekommt alle. Ähnlich Mock Einheit der Arbeit Punktobjekt dot lifo Repository bekommt alle. Andernfalls werden die Tests bestehen und dann sind Sie gut zu gehen. einmal würden Unit-Tests zeigen, dass Sie Punkte oder potenzielle Fehlerpunkte in verschiedenen Teilen Ihrer Anwendung füllen , nur für den Fall, dass sie es sind, oder sie haben massive Refactor-Aktivitäten durchlaufen. Aber das ist es wirklich für diese Aktivität, wo wir die Einheiten der Arbeit hinzufügen. Ich hoffe, Sie sehen den Wert darin, und wir werden unsere Anwendung in den nachfolgenden Lektionen weiter verbessern. 38. Token Ablauf: In dieser Lektion werden wir eine globale Ausnahmebehandlung Middleware für unsere API einrichten . Was passiert, ist, dass wir benutzerdefinierte Ausnahmen hatten , die wir fast am Anfang des Projekts erstellt haben. Wir haben an bestimmten Punkten in unseren Handlern Ausnahmen ausgelöst. Wir haben jedoch nicht unbedingt dem API-Ganzen mitgeteilt , dass es antworten soll, wenn Ausnahmen ausgelöst werden. Sie möchten also natürlich immer fehl, wenn es eine Art von Ausnahme gibt. Wir möchten einen Code zurücksenden, der auf die Art der Ausnahme hinweist. Zum Beispiel habe ich alle meine Update-Handler aktualisiert, um auch eine nicht gefundene Ausnahme zu werfen. Also, um es zu wissen, lassen Sie mich einfach das hier korrigieren. So offen zu wissen. Ich hatte den Code nicht. Wenn du den Code bereits hattest, dann ist das gut. Das ist ein Lob an dich, oder? Aber wir haben Validierungsausnahmen ausgelöst, wenn die Validierung fehlschlägt. Aber was passiert dann, wenn der zu findende Datensatz nicht telefonisch war, dann wollen wir eine nicht gefundene Ausnahme. Also habe ich hinzugefügt, dass bei jeder Überprüfung zu sehen, ob Urlaub Zuteilung gefunden wird, wenn der Urlaub Anfragen, Das ist ein Boot, um sein Telefon aktualisiert werden und wenn der Urlaub sorry, die Blattart, ihr Ziel. Wenn der Blatttyp Telefon ist, werfen wir einfach eine nicht gefundene Ausnahme. Ordnung? Die Ausnahme zu werfen ist also einfach genug. Es zu handhaben ist eine andere Sache. Beachten Sie also, dass es keine Versuchsfänge gibt. Es wäre irgendwie überwältigend vorwärts zu versuchen, den Versuch fangen und jeden einzelnen zu setzen. Was wir also tun werden, ist Einrichtung und Ausnahmebehandlung von Middleware auf API-Ebene, weil der Controller Medien verwendet, um es als Handler zu bezeichnen, aber wir haben auch hier keine Track-Fänge, also kehren wir immer zurück, okay? Aber dann gibt es Zeiten, in denen die Ausnahme ausgelöst wird und es OK, kann geworfen werden. Und in der API wirft buchstäblich nur ein zufälliges Antwortgeld auf den Client. Wir wollen sicherstellen, dass wir wissen, was geworfen wird. Also gehen Sie weiter und erstellen Sie einen neuen Ordner im API-Projekt namens Middleware. Und in diesem Ordner erstellen Sie eine Datei namens Exception Middleware. Das ist also unsere Cross-Exception-Middleware. Und ich werde Sie einfach durch das führen, was das im Web oder im Detail tun wird. Also haben wir eine Klasse in dieser Datei, in dieser anderen Klasse, die Fehlerdetails genannt wird. Ich führe dich erst durch die einfacheren Teile. Und Fehlerdetails haben nur den Fehlertyp und eine Fehlermeldung. Zumindest können wir dem Klienten immer mitteilen, dass es das ist, was schief gelaufen basierend auf dem Umstand, mit dem wir konfrontiert sind, richtig? Jetzt. Alles, was es gesagt hat, dass wir innerhalb der Klasse für außergewöhnliche Middleware haben, haben wir ein privates schreibgeschütztes Feld namens nächste, und das ist vom Typ Request Delegate. Also instanziieren wir das im Konstruktor. Und dann haben wir eine Methode namens Aufruf einer Senke. So rufen öffentliche AsyncTask async auf und es nimmt einen Parameter namens HTTP-Kontexte. Wir haben uns also bereits angesehen, was die HTTP-Kontexte uns erlauben. Grundsätzlich ermöglicht es uns, die Anfrage zu sehen, die Antwort, alles mit einem ganzen Workflow zwischen Client und Server ist innerhalb dieser HTTP-Kontexte gespeichert. Das wird sich also wie ein Abfangjäger verhalten, wird versuchen, zu sehen. Es wird sagen, machen Sie die nächste Option, die über die HTTP-Kontexte abgeschlossen werden sollte. Das ist im Grunde das, was das tut. Sie. Http-Kontexte machen Ihre nächste Option. Wenn es eine Ausnahme gibt, fangen wir sie an und dann werden wir damit umgehen. Jetzt gehen wir weiter, wie wir damit umgehen. So private Aufgabe Handle Ausnahme ist Senke, wo Sie den HTTP-Kontext und die Ausnahme, die abgefangen wurde. Wissen wir, dass wir nur sagen, dass wir eine Antwort als Anwendungsschrägstrich JSON haben wollen , weil es die API ist. Wir wissen also, dass alles, was wir reagieren, in Form von JSON sein wird. Wir setzen auch einen internen Standardserverfehler, HTTP-Statuscode der Schule standardmäßig auf das, was 500 ist. Dann werden wir sagen, das Ergebnis ist gleich, ich möchte niemals Objekte in eine neue Instanz von Pfeil mit der Ausnahmemeldung serialisieren . In Ordnung, also serialisieren wir all das in die Ergebnisse null, wenn wir zum Schalter gehen. Wo im Grunde zu sehen, welche Art von Ausnahme dies ist, weil Ausnahme der Basisdatentyp ist. Aber dann, wie wir gesehen haben, haben wir unsere eigenen Ausnahmen. Wir haben die Validierungsausnahme, wir haben die lassen Sie mich gehen die Butter Anfragen Ausnahme. Wir haben die nicht gefundene Ausnahme. So können wir für alle diese Buchhaltung für schlechte Anfrage zu berücksichtigen. Ich bilanziere keine Validierung. Mich. Gehen Sie weiter und aktualisieren Sie das. Was wir jetzt hier tun, ist mir zu sagen, welche Art von Ausnahme es ist. Ich weiß, es ist eine Ausnahme, aber welcher Typ war es wirklich nicht so schlechte Anfrage. Eine Ausnahme der Validierung verdankt eher, dass ich nicht gefunden werde. Basierend auf dem einen Punkt, der zu tun ist, werden wir den Status quo ändern. Es ist also standardmäßig 50, 100. heißt, wenn es nur das Unaußergewöhnliche war, vielleicht war es auf Datenbankebene Fehler, vielleicht war es ein Netzwerkfehler, den wir nicht schließen können. Und vier, dann ist es definitiv eine 500. 500 bedeutet, dass es sich um ein System handelt, das System, das von der API verwendet wird, es ist der Fehler des Systems. Schlechte Anfragen würden jedoch darauf hindeuten, dass Sie als Client Schuld haben, aber Sie haben mir Mülldaten gesendet. Also werde ich Ihnen sagen, dass es eine schlechte Bitte ist, was vor 400 Jahren ist. Wenn es sich um eine Validierungsausnahme handelt, ist das auch eine Art schlechte Anfrage, weil Sie mir nur Daten gesendet haben, aber Sie können immer durchschauen und sehen, welchen anderen Code für die Art der Ausnahme oder besser könnte. Ordnung, aber dann willst du immer mit Fehlercodes im 400 Bereich bleiben, richtig? Da sind wir also. Also meine ich dir, das ist allein. Also dieser sagt Aber Anfrage und dann nicht gefunden Ausnahme ist eine 40 für das bedeutet, dass ich nicht finden konnte, wonach Sie suchen. Also 40 für so, wenn keiner von ihnen der Fall war, dann brechen wir einfach und das wäre als 500 bleiben. Dann sehen wir antworten mit dem Statuscode und kehren mit dem Ergebnis zurück. Ergebnis, was bedeutet, dass die ganze Nachricht, die Teil der Ausnahmemeldung war. Also denken Sie daran, dass, wenn wir unsere Ausnahmen einrichten oder unsere Ausnahmen von unseren Jägern werfen, immer die Nachricht saßen. Und diese Nachricht wird hier serialisiert. Ich werde geschickt, dass Bokeh diese Antwort ausgelöst hat. Null, wenn Sie möchten, dass es etwas expliziter ist. Da alles, was wir tun, ist, über Pfeil mit Ausnahmemeldung zu senden, könnten wir unsere Fehlerdetails verwenden. Ich hätte neue Fehlerdetails sagen können und dann eine Fehlermeldung wäre die Nachricht und der Fehlertyp könnte etwas anderes sein. Also würde ich sagen, Eric Type Tool und dann wahrscheinlich sagen nur Scheitern, unseren Fehler, was auch immer es ist, damit Sie kreativ werden können. Ich meine, es liegt an dir, was sie wieder in ihrer Antwort bekommen würden, was auch immer du dort hingelegt hast. Also ein Modus, in dem wir die Einrichtung dieser Middleware abgeschlossen haben, müssen wir zur Startdatei für API springen. Und Einsatz der Konfigurieren sexuellen. Wir werden ihm sagen, dass sie die Middleware benutzen soll. Also werde ich es einfach direkt über alles andere machen. Ich möchte nicht sagen, dass DOT Middleware verwendet, Ausnahme auf Middleware. Gehen Sie weiter und fügen Sie alle fehlenden Referenzen hinzu. Und da gehen wir. Also haben wir alle unsere Middleware versucht, global zu fangen und dann anmutig zu behandeln, wie sie auf jeden Kunden reagiert, der seine Berufung ist. Ich wollte nur noch einmal zur Implementierung zurückspringen und eine schnelle Anpassung vornehmen. Ich weiß nicht, warum ich hatte, wenn das anfangs aus. Mit den Ergebnissen für die Validierungsausnahme wollen wir definitiv, dass die Ausnahmefehler Buck in den Körper gehen, richtig? Also die Validierungsnachrichten, eine Sache, gut. Aber dann wollen wir, dass die Ergebnisse gleich der JSON-Serialisierung der Validierung der Pfeile sind, richtig? So haben Sie wieder viele Möglichkeiten, wie Sie mit der Situation umgehen können. Wir sitzen also standardmäßig die Ausnahmemeldung, aber wir überschreiben sie im Falle des Validierungsfehlers. Es wird also die Liste der Fehler sein. 39. Token Ablauf: In Ordnung, also verbessern wir unsere Anwendung weiter, und dieses Mal verlagern wir unseren Fokus auf unsere Kundenanwendung. Also ein paar Szenarien hier, die wir nicht berücksichtigt haben, oder zumindest haben wir ihnen wahrscheinlich begegnet, aber wir haben sie nicht vollständig angesprochen. Nummer 1, wenn Sie wahrscheinlich mittlerweile feststellen, dass, wenn Sie sich vor etwa einer Stunde angemeldet haben und die nahe Buffon Sie an der Reihe sind, ein System zu verwenden. Sie erhalten Ausnahmen von der API für 100, da das Token, das vorhanden ist, obwohl Sie in der Anwendung zugewiesen sind, tolkien abgelaufen ist. Also der Klient Dinge, es ist in Ordnung. Wenn Sie jedoch versuchen, auf die API zuzugreifen und über ein Stand-Token zu senden, lehnt die AICPA es ab und die Anwendung weiß nicht, was zu tun ist. Also erhalten Sie wahrscheinlich diese Ausnahmeseiten. Und andere Sache ist, dass wir Ihre eigene benutzerdefinierte Seite einrichten möchten , wenn eine nicht autorisierte Browseranfrage gesendet wird. Das bedeutet, dass Sie ein Benutzer sind, aber Sie versuchen, zu einer Admin-Seite zu gelangen. Sie hätten MIGA den Fehler gesehen und Sie haben wahrscheinlich zu einem Pfeil gekommen, wo es versucht, zu einer Seite namens Access verweigert zu gehen, die eine der Standardseiten ist, die wir in dieser Client-Anwendung nicht durchbrochen haben. Also werde ich Ihnen zeigen, wie wir den gesamten HTTP-Kontext, die Anforderungspipeline, noch mehr nutzen können . Wir haben es gerade mit der Ausnahmebehandlung für die API gemacht und alles, was wir auf der Client-Anwendung betrachten werden und wie wir diese verschiedenen Szenarien global behandeln können . Beginnen wir also mit der Costal-Middleware, die ich eingerichtet habe. Und ich rufe seine Anfrage Middleware an. Einige, die es aufrufen, fordern die Middleware an, weil ich zwischen jeder einzelnen Browseranfrage sitzen wollte , die jemals in unserer Anwendung passiert. Und dann, wie wir mit der API gesehen haben, können wir immer abgefangen, abgefragt und dann eine Entscheidung treffen, wie das Wort gehen sollte, wenn es ein bestimmtes Kriterien erfüllt auf. Aber beginnen wir mit einem Ordner namens Middleware in der MVC up und die Datei heißt Anfragen, die Middleware. Dies wird also eine öffentliche Klasse sein, die den Anforderungsdelegaten als nächstes annimmt. Und ich injiziere auch meinen lokalen Speicherdienst geht, denken Sie daran, dass wir jederzeit auf die Tolkien zugreifen. Also gehen wir voran und initialisieren sie im Konstruktor, und dann haben wir unsere Methodenaufgabe, rufen Sie eine Senke auf. Also hat diese Methode einen großen Try-Catch, richtig? Er hat großen Try-Fang gewonnen. Also werden wir es versuchen. Und die einfachste Zeile wäre genau wie wir in der API gesehen haben, wäre so einfach. Versuchen Sie, auf die nächste Auktion zu warten und dann alle Ausnahmen zu fangen und zu behandeln. In Ordnung. Bevor wir jedoch voran gehen und es erlauben, die nächste Aktion auszuprobieren, wollen wir ein paar Kontrollen vornehmen. Also die Überprüfung, die wir tun, ist, naja eins, wir bekommen die Endpunkte. Diese Linie EP stellt also den Endpunkt dar. So HTTP-Kontexte Punkt-Features, erhalten Sie die AI-Endpunkt-Funktion und erhalten Sie die Endpunkte, was bedeutet, wohin Sie gehen, wo Sie Rosing-Tool. Dann werde ich sehen, haben diese Endpunkte ein Metadatenattribut? Denken Sie daran, wenn unsere Controller im Grunde Metadaten-Attribute sind, oder? Hat es also ein Metadatenattribut, Typ authorize attribute? Nun, autorisiert ist vom Typ autorisieren Attribut. Also sehe ich, wo immer Sie Browser-Tool sind, gibt es autorisierte Attribute, die nicht jemals kontrollieren oder sind Endpunkt hat einen Autor, da Attribut nach Hause geht keine Benutzer hat, hat keine. Wenn es also so ist, bedeutet, dass wir etwas haben, es ist nicht null, dann wollen wir sagen, okay, da dieser Endpunkt autorisiert ist, um sicherzustellen , dass es ein Tolkien gibt und noch mehr, dass dieses Token gültig ist. Also werde ich sagen, Autorenattribut ist nicht gleich null. Oder sorry, wenn es nicht gleich null ist, dann besorgen Sie mir den lokalen Speicher. Tolkien, richtig, also geh und überprüfe, ob es existiert. Und dann sehe ich auch, dass es gültig ist, weil ich davon ausgehe, dass es jederzeit gültig ist. Aber wenn es existiert, müssen wir es noch mehr Seele validieren, oder? Also sehe ich, ob die Tolkien existieren, dann hol dir das Tolkien, dann benutze ich den Sicherheitsgriff, den Tolkien-Handler. Wir wissen, was wir brauchen, um eine using-Anweisung dafür zu injizieren. Und dann sehe ich mir die Tolkien-Inhalte, dann das Ablaufdatum, und dann überprüfen, ob das Ablaufdatum abgeschlossen ist. In Ordnung. Also, wenn das Ablaufdatum kleiner als der Datetime Punkt 10 ist, was bedeutet, dass wir weit vorbei sind oder wo keine Vergangenheit, egal welche Zeit als Exploration sitzen wird, dann ist das Token nicht gültig. Dann werde ich sagen, ob das Token nicht gültig ist oder die Tolkien nicht existieren und die Ausrufezeichen bemerken. Das könnte also leicht gewesen sein, ist äquivalent zu false, was ich tun werde, um die Lesbarkeit zu erhöhen. Also, wenn einer von ihnen falsch ist, dann wollen wir eine Methode aufrufen, die ich unten erstellt habe, genannt Sinusoide und Weiterleitung im HTTP-Kontext. So lebt die HTTP-Kontexte. Von dieser Middleware, kein Problem, wir geben es einfach weiter und dann kehren wir zurück. Also dann bedeutet das, dass die Option, die hier gesagt wird, die nächste Option punktet. Wir werden nie zu diesem hier kommen, wenn wir an diesem Punkt abgefangen haben. Keine andere, die ich mache, ist, wenn das Authentifizierungsattribut die Regeln hat. So können wir tatsächlich in mehrere Zeilen setzen, können Sie Administrator-Komma sehen, dieses Komma, das, so viele Regeln, wie Sie suchen müssen. Aber in diesem Fall möchte ich nur sicherstellen, dass wenn die Autorenattribute, wie wir hier sehen, Administratoren beschränkt sind und der Benutzer nicht in der Administratorrolle ist. Dann möchte ich zu Hause Schrägstrich nicht autorisiert umleiten. Dies ist, wenn er bereit war, den Zugriff standardmäßig verweigert. Also überschreiben wir es nur und sehen, gehen Sie zu unserer benutzerdefinierten Seite. Bitte umleiten und zurückgeben. Also, wenn das Token gültig ist, aber Sie kein Administrator sind, der versucht, zu einem Administratorpfad zu gelangen , zu dem wir umleiten werden, und das ist das Ende davon. Jetzt gibt es Situationen, in denen wir eine Ausnahme beim Versuch abfangen könnten , diese Operation zu durchlaufen. Eine dieser Situationen wäre mit der API. Manchmal könnte es ein Synchronisationsproblem mit der Zeit geben, was bedeutet, dass wir die Tolkien als nicht abgelaufen und gültig betrachten können. Aber dann, wenn er geht über die WPA, die EPA wirft immer noch eine Ausnahme sehen 40 ein Jahr nicht autorisiert. Okay, in dieser Situation werden wir uns abmelden und umleiten, haben auch eine ähnliche Situation wie die API-Ausnahme-Middleware, wo wir die Ausnahme sehen. Wenn es sich um eine Art von API-Ausnahme handelt, dann führen Sie diese Aktion aus. Ansonsten einfach auf die allgemeine Startseite Schrägstrich Fehlerseite umleiten, umleiten und brechen. Also schauen wir uns an, was in diesem Seinfeld passiert und umleiten. Alles, was wir tun, wir schicken euch alle aus dem HTTP-Kontext, genau wie das, was wir Milliarde haben, ich benutze einen Service, die Zeit der Logos. Und dann werden wir Sie auf den Pfad für Benutzer Schrägstrich Login umleiten. Also Schrauben der Login-Seite und dann gehen Sie voran und umleiten, dann kehren wir zurück. Das ist also alles, was in diesen Bereichen passiert. In Ordnung? Und dann im Grunde macht das diese immer dort. Wenn also all das übersprungen wird, wird das alles übersprungen. Es gibt kein Attribut, dann gehen Sie weiter und kreisen Sie die nächste Anfrage. Wenn wir eine Ausnahme fangen, gehen wir entweder auf die Fehlerseite oder wir gehen davon aus, ob es eine API-Ausnahme ist, Senat und Umleitung, Natürlich kann es verschiedene Arten von EPA-Ausnahmen geben, sind unterschiedliche Szenarien mit ihnen. Sie könnten also leicht eine andere Costalmethode haben, um zu sehen, ob die API-Ausnahme vom Typ ist. Dieser Antworttyp wechselt dann zu dieser Art von Sprache , da dieses EPA-Ausnahmeobjekt tatsächlich Antwortcode enthält. So können wir den Statuscode eher erhalten. Dort gehen wir, können wir den Statuscode bekommen, der zurückgeschickt wird. Also, wenn es 40, 1 ist, dann Sinus Alton umleiten. Wenn es vielleicht 500 ist, dann tun Sie das. Denken Sie also daran, dass wir unsere verschiedenen Arten von Antwortcodes in der API eingerichtet hatten. Also wissen wir, dass wir Butteranfragen bekommen können, wir können Validierung bekommen, wir können nicht telefonieren, oder? Basierend auf dem Typ des Statuscodes, den wir von der API erwarten, wird es in der Ausnahme zurückkommen und dann können wir damit umgehen. Das ist also eine schnelle und schmutzige Art zu behandeln, was passiert, wenn die Tolkien's abgelaufen sind oder wenn wir verschiedene Ausnahmen haben, die wir nicht in der Lage sind zu behandeln. Und wenn Sie mehr Ausnahmen sehen, können Sie natürlich mehr Handlingfunktionen in der Middleware einsetzen. Nein. Einfach schnell zu Hause. Einige Umleitung zu oder ist es, die ich zu einer verweigerten oder nicht autorisierten Sprache umleiten. Es ist nichts Mittel, die es im Home-Controller erstellt wird und neue Aktion nicht autorisiert ist. Und ich habe nur eine Seite, die buchstäblich nur sagt, dass Text nicht autorisiert. Das ist alles, was passiert. Es gibt Jumbotron nicht autorisieren, so können Sie verrückt mit Ihrer Kreativität. Finden Sie eine schöne benutzerdefinierte PCC. Sie dürfen die Nettoleistung nicht weitergeben. Das ist alles, was wirklich passiert. Also lasst uns das testen. Ich werde nur versuchen, zu einer Seite zu navigieren , von der ich weiß, dass ich nicht auch bekommen kann, während ich nicht eingeloggt bin. Und dann sehen Sie nicht autorisiert. In Ordnung. An diesem Punkt könnten wir wahrscheinlich sehen, ob es einen Ambrose-Versuch zu einer Seite gibt, auf der es nicht autorisierte Tag gibt und der Benutzer nicht böse ist, authentifiziert und dann auf die Anmeldeseite umgeleitet wird, richtig? Das wäre sinnvoller, wenn ich als Benutzer eingeloggt bin. Und sobald ich bekomme, gebe ich nur Ideen zu halten, um Ihre Anwendung zu kontrollieren wächst, wenn ich versuche, mich als normaler Benutzer anzumelden. Und dann versuche ich noch einmal, auf die Admin-Seite zu gelangen, ich bin nicht autorisiert. Ich kann jedoch zu einer Seite navigieren, auf der ich das Bowl Tool autorisiert bin , und ich erhalte einen Fehler. Also habe ich das nicht mal richtig getestet und es ist ziemlich vor dir und das ist gut. Es ist gut zu sehen, dass diese Fehler dazu führen würden, dass dies eine weitere Ausnahme ist. Und es ist mehr als wahrscheinlich, weil ich die Authentifizierungsregel ohne Das Autoren-Attribut mit mehr Regeln habe, richtig? Also versuche ich, an einen Ort zu gelangen, der keine Zeilen in den Authentifizierungsattributen hat. Und dann wegen dieses Fehlers fängt die Ausnahme ab. Also, jetzt geht es auf die Startseite Schrägstrich Fehlerseite, die nur sagen wird, dass es einen Fehler gab, der versucht, Ihren Befehl abzuschließen. Das ist natürlich ein roter Hering, denn das ist nicht wirklich das Problem. Ich versuche, auf diese Seite zu kommen. Ok. Ich bin nicht autorisiert. Das sieht ein bisschen besser aus, wenn ich versucht habe, zu einer zu gelangen, die die Anfragen erstellen. In Ordnung, so ist es da. Wenn also ein Autorisierungsflag mit mehr Zeilen vorhanden ist, wird dies einen Fehler auslösen. Und das ist, was passiert, weil Urlaubsanträge autorisiert sind, aber es hat keine Bestimmung Regel. Also lassen Sie uns einfach schnell darauf zurückfließen. Und das war ein guter Bereich, weil es in diesem Refactor viel bessere und viel funktionalere Code-Bits inspiriert hat. Also habe ich einige der magischen Strings loswerden und ich denke, dass man viel mehr globale Situation berücksichtigt, wie es sich auf die Regeln bezieht, Bestimmungen, richtig? Anfangs war es nur, wenn Sie kein Administrator sind, dann können Sie nicht in. Wenn Sie jedoch mehrere Rollen und sogar Benutzer mit mehreren Rollen haben, möchten Sie sicherstellen, dass Sie alle Situationen berücksichtigen, richtig? Also in dieser Situation sagte ich, wenn Auth Dot Rollen oder die Autorattribute-Rollen nicht gleich null sind, gibt es Rollen in der Liste. Dann gehen Sie weiter und holen Sie sich die Rolle des Benutzers. In Ordnung, also bekommen wir die Rolle des Anspruchstyps. Natürlich müssen Sie dafür keine using-Anweisung einfügen. Und dann bekommen wir diesen Wert. Dann sehe ich, ob die Liste der Regeln diese Regel nicht enthält. In Ordnung, so dass mehrere Rollen verwendet werden könnten, um Endpunkte zu sichern. Ein Benutzer kann mehrere Rollen haben. Wenn dieser Benutzer keine Rolle hat und dies ist nur die Abrechnung für unseren Benutzer mit einer Regel. Also lassen Sie mich, lassen Sie mich zurückverfolgen. Dies ist, wenn einem Benutzer nur eine Rolle zugewiesen wird. Möglicherweise müssen Sie ein bisschen mehr fertig machen, vielleicht eine für jede Schleife oder eine andere Methode verwenden , um herauszufinden, ob eine der Regeln der Benutzer, in einer der Regeln und stattdessen in den Attributen, aber richtig, und alles, was wir die eine Regel für den Benutzer und überprüfen Sie, ob die Liste der Regeln für Jugendliche, die Rolle des Benutzers. Und wenn nicht, dann sind sie für diese spezielle Anfrage nicht autorisiert. Und das ist es im Grunde. So können Sie damit spielen und Sie können sehen, dass diese Variable voll ist, aber wenn Sie das Zitat nicht sorgfältig genug schreiben, könnte es die Anwendung abwerfen und einen kleinen Bildschirm eines Fehlers aufgeben , wenn es wirklich nichts falsch ist oder wenn es deine eigene Schuld ist. Also möchten Sie sehr vorsichtig sein, wenn Sie 18 Zitat für die Middleware sind. Aber es ist wirklich sehr mächtig. 40. Data: In dieser Lektion werden wir uns mit der Verbesserung der Auditing beschäftigen. Also, bisher haben wir einige Menge an Auditing in unseren Speicheränderungen implementiert , wo wir jede Entität nehmen, sobald sie aus der Basisdomänenentität ist, wir erhalten, um die Last-Modified Daten und die große automatisch erstellt. Wir müssen das nicht jedes Mal tun, wenn wir diese Objekte erstellen, die gespeichert werden sollen, oder? Was wir also tun werden, ist einen zweiten DB-Kontext zu erstellen , der dieses Auditing tatsächlich übernimmt, denn was wir jetzt nicht tun, ist das Hinzufügen der Namen des Benutzers oder des Namens des Benutzers für die durch die zuletzt modifizierte durch erstellt. Daher brauchen wir eine Möglichkeit, den Benutzer die Aktion automatisch in die Datenbank abschließen zu lassen. Also begannen wir diese Aktivität mit einer brandneuen Datei , die ich überwachbaren DB-Kontext nenne. Jetzt ist es eine abstrakte Klasse und erbt vom DB-Kontext. Es hat einen Konstruktor, der der vorherigen Szene im Leave Management DB-Kontext sehr ähnlich ist , außer es braucht nur DB-Kontext, Optionen, also wird es nicht eingegeben oder es ist in der anderen, Sie hätten es gesehen -Typen, wie es tatsächlich für den DB-Kontext eingegeben hat. Nun, das machen wir dieses Mal nicht, wir nehmen nur Optionen. Alles klar, dann haben wir unsere eigene Implementierung eines Speichern Änderungen. Dies ist also keine öffentliche virtuelle asynchrone Aufgabe außer Kraft setzen. Zurückgeben int speichern Änderungen. Es dauert einen Parameter namens string username, den ich standardmäßig System bin, was bedeutet, wenn kein Benutzername angegeben wird, dann ist System das, was in diese Benutzernamenspalte geht. So können Sie das tun, wenn Sie es wünschen. Wenn Sie einen Standardwert haben, können Sie andernfalls einfach diese Null erfüllen. Also noch einmal, das ist keine Überschreibung. Also haben wir tatsächlich das gleiche für jede Schleife, die durch den Eintrag in und die sensing basierten Change Trucker Verletzungen für Baseline-Entitäten geht durch den Eintrag in und die sensing basierten Change . In Ordnung. Und dann sagen wir, gehen Sie voran und setzen Sie das letzte Änderungsdatum und das hinzugefügte Datum oder das erstellte Datum jedes Mal ein, wenn man hinzugefügt wird. Nun, ich, bevor ich fortfahre, würde ich das weiter filtern wollen, weil der CI-Instruktor alles transportiert, wenn es unverändert ist, wenn es alles gelöst ist, brauchen wir diese Änderungen nicht an Sachen, die nicht geändert oder hinzugefügt. Also werde ich einen zusätzlichen Filter hinzufügen, wo ich sehe, dass ich diese Einträge besorge, sie in Basisdomänenentität analysieren kann. Aber wo ihre Zustände, so q-dot Zustand hinzugefügt oder geändert wird. Wir sind also nur daran interessiert, diese Auditfelder auf irgendetwas zu setzen , das aktualisiert oder erstellt wird. Also, dann kann ich wissen, sagen, Eintrag Punkt Entity Punkt zuletzt geändert von ist gleich dem Benutzernamen, der übergeben wird. Alles klar, und dann Ähnlichkeit, ich kann sehen, dass CreatedBy der Benutzername ist, der übergeben wird. Alles klar, also all das, nur um sicherzustellen, dass wir den Benutzernamen vorhanden haben. Aber danach werden wir sehen, var Ergebnis ist gleich 08 Basis. Also ist BS wieder einmal DB-Kontext. So basierter Punkt speichern Änderungen asynchron, und dann geben wir dieses Ergebnis zurück. Schauen wir uns nun die Änderungen an, die für die ursprünglichen Urlaub Management-DVI-Kontexte erforderlich sind . Erstens, ich muss nicht überschreiben, sehen, ob sich hier wieder ändert, also kann ich das vollständig entfernen. Das ist ein Tool, das ich weiß, dass ich von den überwachbaren DB-Kontexten erben muss. Also ist es dieser DVI-Kontexte erbt von dem überwachbaren, der dann von DVI-Kontexten erbt für den überwachbaren gibt eine eigene Version. Ich werde sehen, ob Änderungen, bevor es die Basis Save Changes aufrufen wird, was ohnehin mit freundlicher Genehmigung von DVI-Kontexten ist. Mit all dem erledigt, können wir jetzt unsere Arbeitseinheiten ändern. Denn denken Sie daran, wissen Sie, dass wir implementiert haben , dass unser C von Änderungen genau hier passiert. Und das wird im Kontext genannt. Mit dem injiziert, kann ich zu meiner Speicherfunktion gehen und ich kann sehen, dass der Benutzername den HTTP-Kontexten entspricht, Accessor HTTP-Kontexten, der Benutzer den Vornamen für die Benutzer-ID findet , weil denken Sie daran, dass wir Speichern der Benutzer-ID. So gut, ja, also verwende ich nur die benutzerdefinierten Anspruchstypen dot UID. Ein weiterer Grund, warum wir viel extremes ZNS und bequem und sauber vermeiden wollen, und wir bekommen diesen Wert, so dass wir diesen Benutzernamen in diese Methode übergeben können, die dann hier rüber springen würde, bootet Auditing Sachen, und speichern Sie dann die tatsächliche Änderungen im DB-Kontext und geben die Ergebnisse zurück, wenn wir es brauchen. So können Sie das Auditing verbessern. Mit diesem überprüfbaren DB-Kontext sitzt also zwischen der Arbeitseinheit und den tatsächlichen DVI-Kontexten. Es gibt nur wenige Dinge, die Sie hier tun können. Einige Leute hätten tatsächlich gerne eine eigentliche Überwachungsdatenbank oder eine Auditing-Tabelle oder eine Reihe von Tabellen. Sie wollen jedes einzelne Axon, das gegen diese Entitäten ausgeführt wird, protokollieren, nicht nur auf diesen Feldern sitzen, sondern sie vielleicht an woanders replizieren. All das könnte hier möglicherweise passieren. Ich werde nicht sagen, dass alles dazu führen könnte, dass es einige Einschränkungen geben wird. Aber ich habe gesehen, wo Leute tatsächlich vollwertige Auditing zwischen diesem, diesem bisschen Code und diesem bisschen Code durchführen, oder? So Einheit, so für erstreckt sich über alles. Und dann manipulieren wir sie für jede Entität, die darauf wartet, gespeichert zu werden. Und dann retten wir sie. 41. Schlussbemerkung: Ich möchte mich bei den Jungs dafür bedanken, dass sie es bis zum Ende dieses Kurses mit mir gemacht haben, wo wir am Ende nicht unbedingt ein voll funktionsfähiges EHR Leave Management-System hatten. Aber wir haben uns einige fortgeschrittene Techniken angeschaut. Ich weiß, du kannst es wegnehmen und auf deine täglichen Routinen anwenden. Für die Dauer dieses Kurses haben wir Code geschrieben, der modulo testbar, wartbar und wiederverwendbar war, und wir waren empfindlich auf die soliden architektonischen Prinzipien. Wir implementierten das Meer QRS und Medien, um Muster. Wir haben uns die bewährten Praktiken für die Trennung von Bedenken angesehen. Wir haben eine API implementiert. Wir haben uns angesehen, wie wir es mit JWT-Authentifizierung sichern und halten, um das zu konsumieren und das zu unserem Vorteil in einer Client-Anwendung nutzen können, wir haben so viel zusammen getan und ich bin nochmals sehr dankbar für Ihr Engagement und Ihre Unterstützung und Sie haben irgendwelche Vorschläge. Fühlen Sie sich frei, sie in der Vorschlagsbox zu lassen. Und ich bin immer offen für Feedback. Nochmals vielen Dank und haben Sie einen tollen.