Blazor CRUD
Inleiding
De meeste web applicaties volgen meestal een REST architectuurstijl waarbij vanuit een client een web API server controller wordt aangeroepen. De Web API server controller voert dan op verzoek van de client diverse CRUD (Create/Read/Update/Delete)-acties uit op een gegevensbron.
In deze post zullen we ingaan op deze CRUD action methods waarbij we het één en ander niet alleen vanuit een Blazor Web Assembly client bekijken, maar ook vanuit de browser en een tool als Postman want die kunnen ook clients zijn.
De voorbeeldcode kun je in de GitHub repository vinden.
Terminologie
De termen Web API, REST, StateLess, Endpoint en CRUD duiken regelmatig op als we het hebben over Web API. We gaan dan ook kort in op deze termen alvorens we in detail een web applicatie gaan bekijken.
Web API
Bij een client / server web applicatie staat op een web server een web API server controller. De server controllers kunnen via een web API (Application Programming Interface) door verschillende clients benaderd worden en voor de communicatie wordt gebruik gemaakt van HTTP (Hypertext Transfer Protocol).
REST
De term REST komt ook om de hoek kijken als we het gaan hebben over web API server controllers. REST staat voor Representational State Transfer en is een architectuurstijl voor het doen communiceren van software met andere software. REST gebruikt HTTP-methoden voor het versturen en ontvangen van data. Verder worden voor de interactie tussen de client en de server universele berichtformaten gebruikt zoals JSON en XML.
Stateless
De relatie tussen de client en server bij REST is stateless. Dit houdt in dat niks over de client wordt bijgehouden op de server. Als informatie over de client een rol speelt dan dient de client dit zelf bij te houden in bijvoorbeeld de cache van de clientmachine. De gegevens van de client moeten dan ook elke keer naar de server gestuurd worden indien de server zulke gegevens nodig heeft.
Endpoint
Elke web API server controller heeft een endpoint en een endpoint kan beschouwd kan worden als een loket tot welke we ons moeten wenden indien we gebruik willen maken van een bepaalde dienst van een server controller.
In de vorige post hadden we deze url http://localhost:62167/api/Berekening/DoeBerekening als voorbeeld waarbij DoeBerekening een endpoint is en achter de endpoint een dienst schuilt. De dienst betrof het doen van een deling.
CRUD
Aan een endpoint kan ook een resource hangen en dat kan bijvoorbeeld een gegevensbak zijn met de gegevens van eigenaren van auto’s. De resource ga je via een endpoint benaderen en dan is het van belang wat je met de gegevensbron wilt doen.
Met een verb (GET, PUT, POST en DELETE) geef je aan wat de aard van het verzoek is naar de web API server controller.
Wat voor CRUD (Create Read Update Delete) – action method moet de server controller uitvoeren op de gegevensbron? Gaat het alleen maar om het opvragen van gegevens (GET) ? Of gaat het ook om het wijzigen van gegevens (PUT) en het toevoegen van gegevens (POST)? Of wil je gegevens juist verwijderen uit de gegevensbron (DELETE).
Web Applicatie
In deze post zullen we het één en ander toelichten aan de hand van een Blazor Web Assembly hosted solution. In Visual Studio 2019 gebruiken we wederom de Blazor Web Assembly Hosted template.
De web applicatie gaat CRUD bewerkingen uitvoeren op een datasource waarbij de datasource een tabel in een SQL server database is of een List<T> in het intern geheugen.
In de web applicatie is Razor-component Eigenaren.razor het startpunt van de applicatie. Eigenaren.razor toont alle eigenaren uit de datasource (tabel EIGENAAR of de List<T> in het intern geheugen):
Vanuit Eigenaren.razor springen we naar EigenaarVoegToe.razor indien we een nieuwe eigenaar willen toevoegen. We maken voor het muteren van de gegevens van een eigenaar een uitstapje naar EigenaarMuteer.razor en voor het verwijderen van een eigenaar gebruiken we EigenaarVerwijder.razor. De desbetreffende Razor-componenten hebben een @page-directive zodat de Razor-componenten als web pagina’s opgestart kunnen worden.
De Razor-componenten zijn Blazor Web Assembly clients met een bijbehorende uitgebreide UI (User Interface) en de clients benaderen via een web Api een web API server controller. De web API server controller geeft data terug aan de client waarbij voor de uitwisseling van data JSON als bestandsformaat wordt gebruikt.
Een client kan van alles roepen en willen, maar een client is niks zonder een Web API server controller. De Web API server controllers doen het uiteindelijke werk en op verzoek van de client gaan ze aan de gang met de gegevens in de datasource. De Razor-client-componenten komen in deze post nog ter sprake, maar we gaan eerst in op de web API server controllers.
Server / Host
Blazor Web Assembly clients roepen Web API server controllers aan op de server. Het verschil met het voorbeeld in deze post is dat we de dependency injection op de server doen en niet bij de client.
De server controllers gebruiken een IModel-interface en de IModel-interface kent een MemoryModel-implementatie waarbij een List<T> in het intern geheugen de datasource is. Daarnaast is er een DBModel-implementatie waarbij een tabel in een SQL Server database de datasource is.
Bij de host op de server geven we in bestand Startup.cs aan welke IModel-implementatie van toepassing is. De clients roepen de server controller aan via de Web API, maar welke implementatie de server controller gebruikt? Dat is iets voor de server en geen aandachtspunt voor de client.
IModel
De IModel-interface kent de volgende action methods:
In de voorbeeld in deze post zijn twee implementaties aanwezig voor de interface. De implementaties en hun interface maken deel uit van de server project en je kunt ze terugvinden in de Model-folder (IModel.cs, MemoryModel.cs en DBModel.cs).
DBModel
De DBModel is een implementatie van de IModel-interface waarbij een tabel in een SQL Server database de datasource is. We gebruiken in het geval van een database de tabel in deze post waarbij we nog wat extra velden hebben toegevoegd aan tabel EIGENAAR. De tabel bestaat nu uit de volgende velden: ID, omschrijving, regio, achternaam en voornaam:
Een dbContext-klasse is nodig voor het ophalen van de gegevens uit de database en voor het bijwerken van de gegevens in de database. De klasse is een intermediair naar de onderliggende database en klasse DbContextClass is een klasse dat erft van klasse DbContext.
Meer over de DbContextClass en connectiestrings in deze post. We zien dat we voor deze implementatie in de constructor een DbContextClass injecteren en toekennen aan backing variable _dbContextClass. Backing variable _dbContextClass wordt daarmee een geïnstantieerd object waarmee we de database benaderen.
Zie verder de broncode op GitHub als je wilt zien wat de methoden precies doen en hoe ze per implementatie van elkaar verschillen.
MemoryModel
MemoryModel is een implementatie van de IModel-interface waarbij een List<T> in het intern geheugen de datasource is. De CRUD action methods voeren bewerkingen uit op de gegevens in de List<T>. Toegevoegde en gewijzigde gegevens in de List<T> gaan verloren zodra de applicatie wordt afgesloten. De applicatie komt bij het opstarten elke keer weer met eenzelfde initiële vulling.
MemoryModel heeft dezelfde action methods als DBModel maar de methods doen per implementatie verschillende dingen. Zo gaat de MemoryModel iets doen met een List<T> terwijl de dbModel aan de gang gaat met een tabel in een database.
Zie verder de broncode op GitHub als je wilt zien wat de methoden precies doen en hoe ze per implementatie van elkaar verschillen
Controller
In een Blazor Web Assembly hosted solution zullen Razor-componenten in een client project de belangrijkste clients zijn van de Web API server controllers in de server project. We zullen het één en ander demonstreren met web API server controller CRUDController.
Let op de constructor van CRUDController. Via de constructor komt interface IModel binnen en de interface wordt aan backing variable _model toegekend. We geven nergens op welke implementatie van toepassing is (MemoryModel of DBModel). Maar is dat van belang voor de web API server controller?
Het antwoord is “nee“. Een web API server controller is, net als de client, niet geïnteresseerd in de implementatie. De interface komt binnen en het is aan de Host op de server om in bestand Startup.cs op te geven welke implementatie van toepassing is. Clients en web API server controllers ga je daar niet mee lastig vallen.
Controller / Client
Het achterliggende idee van een web API server controller is dat zij benaderd kan worden door verschillende clients. Daarbij hoeft de client hoeft niet per se een Blazor Web Assembly client te zijn. Het kan ook de browser zijn of een tool als Postman.
De controller action methods van web API server controller CRUDController gaan we verder bekijken en we gebruiken daarvoor de browser of Postman.
De Blazor Web Assembly clients bewaren we voor het laatst en die behandelen we dan ook als laatste onderwerp in deze post.
HaalOpEigenaren
De web applicatie start met het tonen van de eigenaren uit de gegevensbron. Afhankelijk van de implementatie kan dat of de inhoud zijn van tabel EIGENAAR of de inhoud van een List<T> in het intern geheugen.
De client roept voor dit alles controller action method HaalOpEigenaren aan en de controller action method gebruikt de Ok–helper method indien alles naar behoren verloopt. De Problem-helper method wordt gebruikt indien dingen niet gaan zoals voorzien en in dat geval wordt ook een fout-object naar de aanroepende client gestuurd.
Controller action method HaalOpEigenaren haalt alleen maar gegevens op uit een gegevensbron en de gegevensbron wordt verder met rust gelaten. Het één en ander komt tot uiting in attribuut [HttpGet] waarmee je aangeeft dat bij de aanroep een GET-verb gebruikt moet worden.
Een client doet een verzoek naar een web API server controller en we zagen in deze post dat het verzoek uit een header en een body bestaat. Voor controller action method HaalOpEigenaren hoeven we niks mee te geven in de body en het betreft een GET-request waardoor we de browser ook als client kunnen gebruiken.
We plakken deze url in de adresbalk van de browser: http://localhost:56199/api/CRUD/HaalOpEigenaren en we zien dat we een array met JSON-objecten terugkrijgen. HaalopEigenaren is één van de endpoints van CRUDController en de output van die endpoint is inderdaad een collectie met objecten.
De browser is in dit geval de client en “what you see is what you get”. De browser gaat verder geen fancy dingen doen m.b.t. de opmaak en presentatie van de output.
HaalOpEigenaar
Het is handig dat we eerst zien wat we gaan wijzigen alvorens we enthousiast over gaan tot het muteren van van alles en nog wat. De bestaande gegevens moeten we dan ook ophalen zodat de gebruiker ziet hoe alles er nu voor staat waarna de gebruiker kan overgaan tot het muteren van het één en ander.
Voor het verwijderen hoeft het niet per se, maar we kiezen er in deze applicatie ook voor om eerst de gegevens op te halen en te tonen. We verplichten de gebruiker tot het bekijken van de te verwijderen gegevens en daarna mag de gebruiker overgaan tot de daadwerkelijke verwijdering.
We hebben voor het ophalen van de gegevens van een eigenaar controller action method HaalOpEigenaar die aan de hand van een ID de gegevens ophaalt van de eigenaar in kwestie.
We geven voor controller action method HaalOpEigenaar een ID mee, maar dat geven we mee in de Header en niet in de body. het betreft verder een GET-request waardoor we de browser ook als client kunnen gebruiken.
We plakken deze url in de adresbalk van de browser: http://localhost:56199/api/CRUD/HaalOpEigenaar/1 waarbij de waarde 1 voor de ID staat onder welke de eigenaar geregistreerd staat in de datasource.
HaalopEigenaar is één van de endpoints van CRUDController en de output van die endpoint is een EIGENAAR-object in JSON-formaat die met de OK-helper method naar de aanroepende client is verstuurd. We krijgen onderstaand te zien in de browser.
De Problem-helper method wordt ook gebruikt indien de ID niet klopt en voor de ID niks gevonden kan worden in de datasource. Een fout-object wordt dan naar de aanroepende client gestuurd met HTTP Status Not Found (=HTTP Status Code 404). We krijgen voor bijvoorbeeld ID 666 onderstaand te zien omdat in de datasource voor ID 666 niks geregistreerd is:
Muteer
We hebben voor het muteren van de gegevens van een EIGENAAR controller action method Muteer waarbij een EIGENAAR-object wordt meegegeven en het object wordt gebruikt voor het bijwerken van de gegevens in de datasource.
Het object wordt met de OK-helper method weer terug gegeven aan de aanroepende client indien het bijwerken goed is gegaan.
De Problem-helper method wordt gebruikt als het muteren niet gaat zoals voorzien of als het een eigenaar betreft die op één of andere manier niet meer aanwezig is in de datasource. Een fout-object wordt dan naar de aanroepende client gestuurd.
We kunnen de browser niet gebruiken als client voor controller action method Muteer. Het verzoek naar de web API server controller moet een EIGENAAR-object in de body bevatten en de browser kent geen mogelijkheden om bij de body-gedeelte te komen.
Verder moet voor controller action method Muteer een PUT-request gedaan worden (geen GET-request) wat ook weer een reden is dat de browser niet als client gebruikt kan worden. Een tool als Postman leent zich beter voor gevallen zoals deze en we gaan die tool dan ook gebruiken.
In de header van het verzoek naar de web API server controller geven we aan dat we JSON gebruiken:
In de body van het verzoek naar de web API server controller nemen we het object op dat gebruikt moet worden voor het doen muteren van de gegevens in de datasource.
In dit geval is eigenaresse Sandra met ID 1 in het huwelijk getreden met een meneer Veerman waarbij ze bij hem intrekt en daardoor niet meer woonachtig is in regio Noord, maar in regio Midden.
Url http://localhost:56199/api/CRUD/Muteer zijnde een PUT-request is door de web API server controller naar behoren uitgevoerd. We kunnen dat zien aan die HTTP Status Ok (HTTP Status Code 200) en de server controller heeft ook het object teruggestuurd dat we hadden meegegeven in het verzoek naar de web API server controller.
Verwijder
We hebben voor het verwijderen van de gegevens van een EIGENAAR controller action method Verwijder en het verwijderen gaat wat simpeler. We geven een ID mee en die ID wordt gebruikt voor het verwijderen van de gegevens in de datasource.
Een waarde true wordt met de OK-helper method weer terug gegeven aan de aanroepende client indien het verwijderen goed is gegaan (zie de signature van controller action method Verwijder in IModel).
De Problem-helper method wordt gebruikt als het verwijderen niet gaat zoals voorzien of als het een eigenaar betreft die op één of andere manier niet meer in de datasource aanwezig is. Een fout-object wordt dan naar de aanroepende client gestuurd.
We gebruiken wederom Postman als client. De ID van de te verwijderen eigenaar wordt weliswaar meegegeven in de header, maar voor controller action method Verwijder moet een DELETE-request gedaan worden (geen GET-request) waardoor de browser als client weer afvalt.
In dit geval kunnen we eigenaresse Sandra met ID 1 uit de datasource verwijderen omdat kersverse echtgenoot meneer Veerman al een GHB GuanggongHunnenburgBetrieb auto heeft die veel beter is dan die krakkemikkige XPAZ automobiel waardoor de XPAZ van de hand gedaan kan worden.
Url http://localhost:56199/api/CRUD/Verwijder/1 zijnde een DELETE-request is door de web API server controller naar behoren uitgevoerd. We kunnen dat zien aan die HTTP Status Ok (HTTP Status Code 200) en de door de server controller geretourneerde waarde true.
We hebben afscheid genomen van Sandra, maar we hopen dat ze snel terugkomt en weer een auto bij ons koopt (en deze keer eens niet omdat haar zoveelste huwelijk op de klippen is gelopen en ze weer ergens anders woont en weer een auto nodig heeft).
VoegToe
We hebben voor het toevoegen van een EIGENAAR controller action method VoegToe waarbij een EIGENAAR-object met ID 0 wordt meegegeven en het object wordt gebruikt voor het toevoegen van de gegevens aan de datasource.
Het object wordt met de OK-helper method weer terug gegeven aan de aanroepende client indien het bijwerken goed is gegaan. De server controller kent daarbij een waarde toe aan de ID onder welke de nieuwe eigenaar is geregistreerd in de datasource.
De Problem-helper method wordt gebruikt als het toevoegen niet gaat zoals voorzien. Een fout-object wordt dan naar de aanroepende client gestuurd.
We gebruiken wederom Postman als client. Het verzoek naar de web API server controller moet een EIGENAAR-object in de body bevatten en de browser kent geen mogelijkheden om bij de body-gedeelte te komen.
Verder moet voor controller action method VoegToe een POST-request gedaan worden (geen GET-request) wat ook weer een reden is dat de browser niet als client gebruikt kan worden.
Helaas voor Sandra, het huwelijk met meneer Veerman is op de klippen gelopen, maar gelukkig voor ons, ze is weer bij ons teruggekeerd voor de aanschaf van een nieuwe auto omdat ze weer is verhuisd en weer een auto nodig heeft om mobiel te blijven. We voegen Sandra als volgt opnieuw toe aan onze datasource:
Url http://localhost:56199/api/CRUD/VoegToe/ zijnde een POST-request is door de web API server controller naar behoren uitgevoerd. We kunnen dat zien aan die HTTP Status Ok (HTTP Status Code 200) en de aan de ID van het object dat door de server controller is geretourneerd. Sandra is weer teruggekeerd in onze datasource en haar ID is 24.
Blazor WebAssembly
We hebben tot dusver de browser en Postman gebruikt voor het doen aanroepen van de controller action methods van server controller CRUDController. Leuk voor ons, maar niet leuk genoeg voor de gebruiker. We gaan de CRUDController vanuit een “echte” client aanroepen waarbij de client een UI (UserInterface) heeft en de gebruiker niet wordt lastiggevallen met urls en JSON-object notaties.
In de client project creëren we dan ook een aantal Razor-componenten en in die Razor-componenten gebruiken we de @page-directive zodat de Razor-component als een pagina is op te starten.
De Razor-componenten maken weliswaar gebruik van de browser, maar het is niet de browser die de client is. De Razor-componenten (met uitgebreide UI) zijn nu de clients.
In het voorbeeld in deze post wordt veel door de “code behind” van de Razor-componenten gedaan. Weliswaar niet “best practice”, maar we doen het voor nu even wel omdat het voorbeeld anders te complex wordt. Zie deze post waarin wordt getoond hoe je de componenten van je applicatie via een MVVM design pattern kunt ordenen en wat de voordelen daarvan zijn.
Eigenaren
Eigenaren.razor is het startpunt van de applicatie. Eigenaren.razor toont alle eigenaren uit de datasource en dat kan, afhankelijk van de implementatie, tabel EIGENAAR of een List<T> in het intern geheugen zijn:
Eigenaren.razor heeft een @page-directive waardoor Eigenaren.razor als een web pagina opgestart kan worden. De waarde voor de @page-directive zien we ook terug in de adresbalk van de browser: http://localhost:56199/eigenaren.
In Eigenaren.razor injecteren we een HttpClient zodat we web APIs op de server kunnen aanroepen en een NavigationManager zodat we naar andere pagina’s kunnen navigeren.
Alle eigenaren uit de datasource worden in een <table> in de pagina getoond.
We hebben ten slotte in de Razor-component nog wat code die “getriggerd” moet worden bij het laden van de pagina en als op bepaalde buttons wordt geklikt.
In OnInitializedAsync wordt de code getriggered die moet gaan draaien zodra de pagina wordt geladen. We zien dat controller action method HaalOpEigenaren wordt aangeroepen.
De controller action method hadden we eerder besproken en we zagen dat HaalOpEigenaren direct opgestart kan worden vanuit de browser. We gebruikten daarvoor deze url http://localhost:56199/api/CRUD/HaalOpEigenaren en we zagen dat het resultaat een array met JSON-objecten is. De array met JSON-objecten zetten we in private variabele eigenaren.
We willen ook het fout-object uitlezen indien de controller action method niet draait zoals voorzien. We gebruiken daarom voor het uitlezen methode .GetAsync en niet methode .GetFromJsonAsync.
Private variabele eigenaren zou gevuld moeten zijn indien controller action method HaalOpEigenaren naar behoren heeft gedraaid en we kunnen door de array “itereren” en de <table> vullen:
Ten slotte de code die getriggerd wordt als op bepaalde buttons wordt geklikt. We zien dat we doorgestuurd worden naar respectievelijk EigenaarVoegToe.razor, EigenaarMuteer.razor en EigenaarVerwijder.razor. Voor de laatste twee Razor-componenten wordt een ID meegegeven zodat de eigenaar in kwestie door de component opgehaald kan worden uit de datasource.
EigenaarMuteer
We klikken op de Wijzig-button in Eigenaren.razor en we komen voor een bepaalde eigenaar uit bij EigenaarMuteer.razor.
EigenaarMuteer.razor heeft een @page-directive waardoor EigenaarMuteer.razor als een web pagina opgestart kan worden. De ID van de eigenaar in kwestie maakt deel uit van de @page-directive en dat zien we ook terug in de adresbalk van de browser: http://localhost:56199/eigenaarmuteer/1 waarbij 1 voor de ID van een eigenaar staat. De ID moet ook als parameter en property opgenomen worden in de Razor-component: [Parameter] public intID { get; set; }.
In Eigenaren.razor injecteren we een HttpClient zodat we web APIs op de server kunnen aanroepen en een NavigationManager zodat we naar andere pagina’s kunnen navigeren.
We gebruiken in de Razor-component een <EditForm> waarin de gegevens van de eigenaar worden gezet.
We hebben ten slotte in de Razor-component nog wat code die “getriggerd” moet worden bij het laden van de pagina en als op bepaalde buttons wordt geklikt.
In OnInitializedAsync wordt de code getriggered die moet gaan draaien zodra de pagina wordt geladen. We zien dat controller action method HaalOpEigenaar wordt aangeroepen.
De controller action method hadden we eerder besproken en we zagen dat HaalOpEigenaar direct opgestart kan worden vanuit de browser. We gebruikten daarvoor deze url http://localhost:56199/api/CRUD/HaalOpEigenaar/1 (waarbij 1 voor de ID van een eigenaar staat) en we zagen dat het resultaat een EIGENAAR JSON-object is. De JSON-object zetten we in private variabele eigenaar.
We willen ook het fout-object uitlezen indien de controller action method niet draait zoals voorzien. We gebruiken daarom voor het uitlezen methode .GetAsync en niet methode .GetFromJsonAsync.
We gebruiken in de Razor-component een <EditForm> waarin de gegevens van de eigenaar worden gezet. Het formulier is “gebind” aan private object eigenaar (die weer gevuld is door controller action method HaalOpEigenaar). Meer over de <EditForm> in deze post.
Ten slotte de code die getriggerd wordt als op bepaalde buttons wordt geklikt. We zien dat we teruggestuurd worden naar Eigenaren.razor als we klikken op de Terug-button.
We maken voor het opslaan van de gewijzigde gegevens gebruik van controller action method Muteer. De controller action method hadden we eerder besproken en we hadden Postman gebruikt voor het doen opstarten van controller action method Muteer. We gebruikten in Postman deze url http://localhost:56199/api/CRUD/Muteer.
Controller action method Muteer vereist een EIGENAAR object in de body van de request en we maken voor deze Blazor Web Assembly client gebruik van methode .PutAsJsonAsync(). De methode zorgt ervoor dat het object in de body van de request wordt gezet en object eigenaar wordt daarvoor meegegeven aan de input parameters van methode .PutAsJsonAsync().
EigenaarVerwijder
We klikken op de Verwijder-button in Eigenaren.razor en we komen voor een bepaalde eigenaar uit bij EigenaarVerwijder.razor.
EigenaarVerwijder.razor heeft een @page-directive waardoor EigenaarVerwijder.razor als een web pagina opgestart kan worden. De ID van de eigenaar in kwestie maakt deel uit van de @page-directive en dat zien we ook terug in de adresbalk van de browser: http: //localhost:56199/eigenaarverwijder/1 waarbij 1 voor de ID van een eigenaar staat. De ID moet ook als parameter en property opgenomen worden in de Razor-component: [Parameter] public intID { get; set; }.
In EigenaarVerwijder.razor injecteren we een HttpClient zodat we web APIs op de server kunnen aanroepen en een NavigationManager zodat we naar andere pagina’s kunnen navigeren.
We gebruiken geen <EditForm>. We verplichten de gebruiker tot het bekijken van de te verwijderen gegevens en daarna mag de gebruiker overgaan tot de daadwerkelijke verwijdering en het is verder niet de bedoeling dat in dit scherm gegevens gewijzigd worden.
We hebben ten slotte in de Razor-component nog wat code die “getriggerd” moet worden bij het laden van de pagina en als op bepaalde buttons wordt geklikt.
In OnInitializedAsync wordt de code getriggered die moet gaan draaien zodra de pagina wordt geladen. We zien dat controller action method HaalOpEigenaar wordt aangeroepen.
De controller action method hadden we eerder besproken en we zagen dat HaalOpEigenaar direct opgestart kan worden vanuit de browser. We gebruikten daarvoor deze url http://localhost:56199/api/CRUD/HaalOpEigenaar/1 (waarbij 1 staat voor de ID van een eigenaar) en we zagen dat het resultaat een EIGENAAR JSON-object is. De JSON-object zetten we in private variabele eigenaar.
We willen ook het fout-object uitlezen indien de controller action method niet draait zoals voorzien. We gebruiken daarom voor het uitlezen methode .GetAsync en niet methode .GetFromJsonAsync.
En slotte de code die getriggerd wordt als op bepaalde buttons wordt geklikt. We zien dat we teruggestuurd worden naar Eigenaren.razor als we klikken op de Terug-button.
We maken voor het verwijderen van de eigenaar gebruik van controller action method Verwijder. De controller action method hadden we eerder besproken en we hadden Postman gebruikt voor het doen opstarten van controller action method Verwijder.
We gebruikten in Postman deze url http://localhost:56199/api/CRUD/Verwijder/1 waarbij de waarde 1 voor de ID staat onder welke de eigenaar geregistreerd staat in de datasource. De ID van de te verwijderen eigenaar maakt deel uit van de url en wordt meegegeven in de header.
EigenaarVoegToe
We klikken op de Voeg Toe-button in Eigenaren.razor en we komen bij EigenaarVoegToe.razor.
EigenaarVoegToe.razor heeft een @page-directive waardoor EigenaarVoegToe.razor als een web pagina opgestart kan worden. De waarde voor de @page-directive zien we ook terug in de adresbalk van de browser: http://localhost:56199/eigenaarvoegtoe.
In EigenaarVoegToe.razor injecteren we een HttpClient zodat we web APIs op de server kunnen aanroepen en een NavigationManager zodat we naar andere pagina’s kunnen navigeren.
We gebruiken in de Razor-component een <EditForm> waarin de gegevens van de toe te voegen eigenaar worden gezet.
We hebben ten slotte in de Razor-component nog wat code die “getriggerd” moet worden als op bepaalde buttons wordt geklikt.
We gebruiken in de Razor-component een <EditForm> waarin de gegevens van toe te voegen de eigenaar worden gezet. Het formulier is “gebind” aan private object eigenaar. Meer over de <EditForm> in deze post.
En slotte de code die getriggerd wordt als op bepaalde buttons wordt geklikt. We zien dat we teruggestuurd worden naar Eigenaren.razor als we klikken op de Terug-button.
We maken voor het toevoegen van de gewijzigde gegevens gebruik van controller action method VoegToe. De controller action method hadden we eerder besproken en we hadden Postman gebruikt voor het doen opstarten van controller action method VoegToe. We gebruikten in Postman deze url http://localhost:56199/api/CRUD/VoegToe.
Controller action method VoegToe vereist een EIGENAAR object in de body van de request en we maken voor deze Blazor Web Assembly client gebruik van methode .PostAsJsonAsync(). De methode zorgt ervoor dat het object in de body van de request wordt gezet en object eigenaar (die “gebind” is aan de <EditForm>) wordt daarvoor meegegeven aan de input parameters van methode .PostAsJsonAsync().
Terugkerend naar het voorbeeld van autobezitster Sandra. Helaas voor Sandra, het huwelijk met meneer Veerman is op de klippen gelopen, maar gelukkig voor ons, ze is weer bij ons teruggekeerd voor de aanschaf van een nieuwe auto omdat ze weer is verhuisd en weer een auto nodig heeft om mobiel te blijven. We voegen Sandra als volgt opnieuw toe aan onze datasource:
Url http://localhost:56199/api/CRUD/VoegToe/ zijnde een POST-request is door de web API server controller naar behoren uitgevoerd. We kunnen dat zien aan die HTTP Status Ok (HTTP Status Code 200) en aan de ID van het object dat door de server controller is geretourneerd. Sandra is weer teruggekeerd in onze datasource en haar ID is 24.
Het scherm is uitsluitend bedoeld voor het toevoegen van gegevens en in de code is geprogrammeerd dat toevoegen niet meer mogelijk is zodra de controller action method het toe te voegen object heeft geretourneerd en heeft voorzien van een waarde voor de ID. De geretourneerde waarde is in dit geval 24 zijnde de ID onder welke de gegevens zijn opgeslagen in de datasource.
Slot
In deze post hebben we het gehad over de CRUD-acties die door een web API server controller op verzoek van de client uitgevoerd kunnen worden op een datasource. We hebben het één en ander toegelicht aan de hand van een Blazor Web Assembly hosted solution waarvoor we in Visual Studio 2019 de Blazor Web Assembly Hosted template hebben gebruikt.
Een client hoeft niet per se een Blazor Web Assembly client te zijn. Het kan ook de browser zijn of een tool als Postman. We zijn niet meteen begonnen met een Blazor Web Assembly client, maar met de browser en een tool als Postman. De tools hebben geen of een technisch georiënteerde (gebruikersonvriendeljke) user interface, maar ze laten vaak beter zien wat een web API server controller precies nodig heeft en wat na het gedane werk geretourneerd wordt door de server controller.
Uiteindelijk willen we een server controller vanuit een “echte” client aanroepen. Een client met een gelikte UI (UserInterface) waarbij de gebruiker niet lastig wordt gevallen met urls, JSON-object notaties en allerlei andere technische details. En dat is dan ook het laatste onderwerp van deze post geworden. Hoe roept een Blazor Web Assembly client een web API server controller aan vanuit haar Razor-componenten waarbij de server controller allerlei CRUD-handelingen moet uitvoeren op een datasource.
Hopelijk ben je met deze posting weer wat wijzer geworden en ik hoop je weer terug te zien in één van mijn volgende blog posts. Wil je weten wat ik nog meer over Blazor heb geschreven? Hit the Blazor button…