Create

Natuurlijk willen we niet steeds in onze broncode hoeven te kruipen als we een film willen toevoegen, het zou handig zijn als we dat vanuit onze web applicatie zelf zouden kunnen doen.

We starten opnieuw met een model, en we noemen die MovieCreateViewModel. Hierin zetten we alle properties die we in onze klasse Movie ook hebben, behalve het Id, want deze gaat automatisch omhoog.

We zijn nog niet klaar! Dit is een mooi moment om eens Data Annotations te gebruiken. Boven de properties kunnen we een attribute zetten. Bijvoorbeeld het Required attribuut, dat gaat zeggen dat deze property een value nodig heeft.

Nu is elke property verplicht in te vullen, behalve de Description. Daarnaast kunnen we ook limitaties invullen.

Nu kan de titel maximum 50 characters bevatten, en de beschrijving 250. We kunnen meerdere attributen toevoegen aan de hand van een komma.

Uiteindelijk kunnen we ook nog een DisplayName toevoegen.

Dat gaat er voor zorgen dat we automatisch een label aan het veld kunnen toevoegen bij het aanmaken van een film. Bijvoorbeeld “Beschrijving: [______]”. Zoals je kan zien, kan je een attribuut ook in een aparte blok zetten in plaats van een komma. Dit is puur persoonlijke smaak. Ik zet graag limitaties apart. Bijvoorbeeld Required en MaxLength gaan beide over het invullen, langs de gebruiker zijn kant, DisplayName gaat over hoe het formulier er uit gaat zien.

In MovieController maken we een nieuwe methode aan, Create.

Net zoals de Index methode van onze HomeController, hoeven we hier geen model mee te sturen in de View methode. Er is immers geen data dat ingevuld moet worden als we op Create klikken.

In het mapje Movie maken we Create.cshtml aan. Ookal hebben we geen model meegestuurd naar onze view, we gaan hem nog steeds gebruiken als model.

We willen hier invulveldjes maken, zodat we deze later als een Movie object in de database kunnen steken, dus we hebben MovieCreateViewModel nog steeds nodig. We maken een basic HTML form, met een beetje Bootstrap classes voor de opmaak.

In het label element willen we dat de DisplayName geschreven staat. Herinner je dat nog als attribuut in MovieCreateViewModel? Daarvoor dient dat dus.

Zo een donkergroen attribuut heb je al gezien als je een verwijzing wou maken naar een nieuwe pagina in _Layout.cshtml, maar misschien stond je er niet meteen bij stil wat dat exact deed. Dit is een attribuut dat niet standaard bij HTML hoort, maar bij Razor. Door asp-for te gebruiken, gaat hij de DisplayName van Title nemen en die in dit label zetten. Zoals je kan zien is de Razor-syntax slim genoeg om te weten dat dit over het model zijn Title gaat, dus je moet er niet expliciet Modle.Title van maken.

Ook bij de input gaan we asp-for gebruiken.

Hier zeggen we dat de input dient voor de Title property in te vullen als we onze form versturen. Uiteindelijk hebben we ook nog een span, met een class text-danger. Deze dient voor onze limitaties. Herinner je nog dat we Required en MaxLength hadden toegevoegd? Als we onze form zouden versturen, maar we hebben een veld niet ingevuld, dan kan de applicatie bijvoorbeeld zeggen “Genre is required”.

Hier gaan we dus valideren of Title juist is ingevuld. We copy/pasten deze div een paar keer voor elke property.

Helemaal onderaan de form zetten we nog een knopje van het type submit, om deze form door te sturen.

Wat we nu nog moeten doen is het form element de nodige attributen geven.

De asp-attributen wijzen naar de action methode dat we gaan willen uitvoeren eenmaal we op de knop drukken, en dat is een post method.

Wat we nu nog kunnen doen is een knopje maken om naar het create formulier te gaan. Dat kunnen we doen in de Index view. Ook hier gaan we asp-attributen gebruiken om te verwijzen naar een action.

Als we nu op de nieuwe knop drukken, gaan we naar de create view.

Zoals je ziet staat alles heel erg netjes door gebruik te maken van Bootstrap. We zien dat de labels de DisplayName overnemen dat we vooraf hebben gebruikt.

Als je iets verder kijkt zie je dat het veld Score ook niet zomaar een textbox is, maar een vorm van NumericUpDown. Dit is automatisch omdat we voor de Rating een integer hebben gebruikt.

Natuurlijk, als je op Create drukt gaat er nog niet veel gebeuren, daar moeten we namelijk nog code voor schrijven. We gaan terug naar de MovieController.

Hier gaan we een paar nieuwe attributen zien.

  • FromForm: We willen de data dat we verzonden hebben in een object steken, dat gaan we hiermee aanduiden in onze methode parameter.
  • HttpPost: Hiermee gaan we aanduiden dat dit de methode is dat uitgevoerd gaat worden als we onze form doorsturen.
  • HttpGet: Deze hebben we al een paar keer gebruikt, omdat deze impliciet is hoeven we die er niet steeds bij te zetten, maar het kan wel.

We gebruiken de methode TryValidateModel om te testen of we voldoen aan de limitaties zoals Required en MaxLength. Als dat niet het geval is, keren we terug naar de Create view.

Aangezien we willen testen of dit werkt gaan we even een NotImplementedException throwen, anders zou de applicatie nog steeds return View(); uitvoeren ookal is de form juist ingevuld.

Als we nu een Required veld vergeten in te vullen, krijgen we een deftige foutmelding voor de eindgebruiker.

Als we alles goed invullen, krijgen we een exception.

In plaats van een exception willen we natuurlijk dat deze in onze database geplaatst wordt. We maken een movie object en zetten de properties gelijk aan wat we meegenomen hebben in het MovieCreateViewModel. Daarna gebruiken we de Insert methode dat we voordien gemaakt hebben in MovieDatabase.

Natuurlijk willen we niet terug naar de Create view keren als het gelukt is om een film toe te voegen, maar naar de Index view. Hiervoor kunnen we RedirectToAction gebruiken.

We zouden ook RedirectToAction(“Index”) kunnen gebruiken, maar als we nu de Index methode van naam zouden veranderen, kunnen we hem hier ook automatisch laten aanpassen omdat we nameof gebruiken.

Ziezo! Als we nu een film toevoegen komt die uiteindelijk op de lijst te staan.

Zolang onze applicatie draait, zal deze blijven bestaan in de mock database. Vanaf dat we de applicatie sluiten, zal deze verdwijnen. Later zullen we er voor zorgen dat de film voor eeuwig blijft bestaan.