MVC BASICS Kevin Picalausa 1
ASP.NET MVC 2
Geschiedenis ASP.NET MVC Aangekondigd in 2007 Het MVC patroon 1979: Thing-Model-View-Editor Nu: Model-View-Controller Terug te vinden in verschillende frameworks, o.a. : Java, C++, Hoe wordt dit patroon omschreven? Model: een set van klassen dat de data omschrijft waarmee gewerkt wordt, maar ook een deel van de business laag met daarin hoe de data kan gewijzigd en manipuleert worden. View: beslist hoe de UI er zal uitzien Controller: een set van klassen dat de gebruikers- en applicatie specifieke- logica afhandelt. 3
ASP.NET MVC MVC = Framework om web-applicaties te bouwen Helpt mee aan het DRY principe = Don t repeat yourself Features: View engine (Razor) HTML helpers Model validatie Bundling en Minification NuGet packet manager Web API Open source 4
ASP.NET MVC 1 Scott Guthrie (2007) Core MVC Open source license.net Community werd gevraag om te helpen (inspraak) De weg naar MVC 5.0 ASP.NET MVC 2 (2010) Strongly typed HTML helpers Model validation (client & server) API verbeteringen ASP.NET MVC 3 (2010) Razor view engine NuGet package manager ASP.NET MVC 4 (2012) Mobile project template (jquery Mobile based) Bundling en minification 5
MVC 5.0 One ASP.NET New Web Project ASP.NET identity Bootstrap templates Attribute routing ASP.NET Scaffolding 6
Model Definieert de representatie van de data (gegevens) waarmee de applicatie zal werken. [Data access layer] Deze eenheid wordt ook omschreven als het datamodel. Hierbinnen maak je best de LINQ-to-SQL klassen aan. De model objecten zullen de gegevens van logica voorzien. Bv. validatie of een leeftijdsberekening 7
View Template om dynamisch HTML van te genereren Een model-object zal kunnen weergegeven worden door middel van een view. De view doet geen verwerkingen (controle, berekening, ) van gegevens die getoond worden. 8
Controller De coördinator die de link voorziet tussen de view en het model. De controller is verantwoordelijk voor de verwerking van input, handelend op het model, en beslissend over welke actie hoort uitgevoerd te worden (renderen van een view, doorzenden naar een andere pagina, ). Een controller reageert dus op events die meestal het gevolg zijn van een handeling van een gebruiker. 9
View engine 10
Web Forms view engine Is gebaseerd op.aspx en.aspx.cs (C#) of.aspx.vb (VB.NET) bestanden. <%@ Page Title= separate entry" Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <asp:content ID="Content1" ContentPlaceHolderID= TitleContent" runat="server"> Guestbook message </asp:content> <asp:content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <div class="row"> <div class="col-md-5"> <asp:gridview runat="server" ID="addressGrid" AutoGenerateColumns="false"> <Columns> <asp:boundfield DataField="name" HeaderText="Naam" /> </Columns> </asp:gridview> </div> </div> </asp:content> 11
Is gebaseerd op.cshtml (C#) en.vbhtml (VB.NET) bestanden. Razor view engine @model GuestbookTutorial.Models.GuestbookEntry @{ ViewBag.Title = Guestbook message"; <section id="styles" class="clearfix"> <h1>guestbook Entry:</h1> <div class="primary"> <h2>@model.name</h2> <blockquote> <p>@model.message</p> </blockquote> <p>posted on @Model.DateAdded.ToLongDateString()</p> @Html.ActionLink("Back to entries", "Index") </div> </section> 12
Getting started 13
Nieuw project aanmaken: type 14
Nieuw project aanmaken: template 15
Basis project structuur App_Data: data files App_Start: configuratie klassen met code voor features zoals: Routing Bundling Web API Content: hier plaats je CSS, afbeeldingen en andere site inhoud 16
Basis project structuur Controller: hierin plaats je controller klassen die zullen instaan voor het afhandelen van URL requests Fonts: bootstrap template voorziet enkele basis web fonts die hierin geplaatst zijn Models: hierin plaats je klassen die data manipuleren en voorstellen. 17
Basis project structuur Scripts: hierin plaats je uw javascript library files Views: hierin maak je UI templates aan die output renderen zoals HTML Shared: hierin plaatsen we views die op meerdere pagina s terug keert _ViewStart: wordt iedere keer bij het renderen van een pagina uitgevoerd. Het vervangt de Masterpage. Meestal vind je hier een link terug naar je _layout pagina. Global.asax: bevat initialisatiecode dat uitgevoerd wordt als de app. de eerste keer opstart. Web.config: configuratiebestand van de web-app Vb. dataconnectie string 18
Convention over configuration We know by now how to build a web application. Let s roll that experience into the framework so we don t have to configure absolutely everything again Deze 3 mappen zijn er standaard (convention): Controllers Models Views Convention-based-directory-naming ASP.NET MVC zoekt standaard volgende de controller klasse naam, de view map en gebruikt het aangegeven model in uitvoering. Vb. HomeController -> Views/Home/Index 19
Controllers 20
Controller systeem 1. URL vertelt het routing mechanisme: Van welke Controller klasse een instantie aan te maken Welke Action methode op te roepen + levert de nodige argumenten aan 2. De Controller kiest welke View er weergegeven zal worden 3. De View rendert de HTML 21
Controller: aanmaken 22
public class HomeController : Controller { public ActionResult Index() { ViewBag.SomethingElse = "Tekst ingevoerd via de MVC viewbag"; return View(); public ActionResult About() { ViewBag.Message = "Your application description page."; return View(); public ActionResult Contact() { ViewBag.Message = "Your contact page."; Controller: navigatie /Home/Index /Home/About /Home/Contact return View(); 23
Controller klasse public class HomeController : Controller { public ActionResult Index() { //Response.Write("test"); //return Content("<h1>welkom op deze testwebsite</h1>"); ViewBag.Something = DateTime.Now; ViewBag.SomethingElse = "Tekst ingevoerd via de MVC viewbag"; return View(); De navigatie URL is in dit geval: localhost/home/index Een actie binnen de MVC wereld 24
Controller: parameters // // GET: /Home/Contact?person=Kevin public ActionResult Contact(string person) { ViewBag.Message = HttpUtility.HtmlEncode("Contacteer nu :" + person); return View(); HTML encoding: gebruikt om JavaScript injectie of invoer van HTML markup tegen te gaan. Bv. /Home/Contact?person=<script>window.location= http://malafidewebsite.be </script> 25
[HttpPost] public ActionResult Create(GuestbookEntry entry) { if (ModelState.IsValid) { try { entry.dateadded = DateTime.Now; GuestbookEntry.Insert(entry); return RedirectToAction("Index"); catch(exception ex) { Response.Write(ex.Message); return View(entry); Controller: postback 26
Views 27
View: aanmaken 28
View: aanmaken MVC 5 View Page: met of zonder layout (masterpage) is dit een lege (.cshtml) pagina waarin je HTML code kan schrijven. Mèt layout zorgt voor een referentie naar de _Layout view. MVC 5 Layout Page: Kan aanzien worden als een masterpage waarin je head, scripts en style definieert. Een @RenderBody() blok zorgt voor het aanduiden waar de aparte views zullen inladen. MVC 5 Partial Page: Kan bijvoorbeeld gebruikt worden om de login HTML en keuze logica af te zonderen. Door @HTML.Partial( naam ) makkelijk in te voegen in elke view. 29
View: aanmaken (scaffolding types) Create: view met een form en daarin labels en velden, gebaseerd op een geselecteerd databank model. Delete: view met een form, gebaseerd op het databank model om een instantie te verwijderen uit de DB. Details: view met HTML elementen volgens het opgegeven datamodel. Edit: (zie Create en Delete) Empty: zonder of met model List: tabel weergave van een model 30
<!DOCTYPE html> <html> <head> <meta http-equiv="x-ua-compatible" content="ie=edge,chrome=1"/> <meta charset="utf-8"/> <title>@viewbag.title</title> @Styles.Render("~/Content/themes/base/css", "~/Content/css") </head> <body> View: layout CSS import <!-- header-wrap --> <div id="header-wrap"> @Html.Partial("_LoginPartial") </div> Partial view import voor de login <!-- content-wrap --> <div class="content-wrap"> </div> @RenderBody() Link naar al de andere views die hierin geladen zullen worden <!-- footer --> 31
Viewbag principe Controller: public ActionResult Index() { ViewBag.Something = DateTime.Now; ViewBag.SomethingElse = "Tekst ingevoerd via de MVC viewbag"; return View(); View: @{ ViewBag.Title = "Index - Guestbook"; <p> @ViewBag.Something.ToLongDateString() <br /> @ViewBag.SomethingElse </p> 32
View: model (1) Controller Model public ActionResult Index() { var entries = GuestbookEntry.GetGuestbookEntries(); return View(entries); public static IQueryable GetGuestbookEntries() { db = new GuestbookDataClassesDataContext(); var mostrecententries = (from entry in db.guestbookentries orderby entry.dateadded descending select entry).take(20); return mostrecententries; 33
@using GuestbookTutorialv3.Models @model IEnumerable<GuestbookEntry> View: model (2) <section id="styles" class="clearfix"> <h1>guestbook Entries: Overview </h1> <div class="primary"> @foreach (GuestbookEntry entry in Model) { <h2>@html.actionlink((string)@entry.guestbookuser.username, "Show", "Guestbook", new { @entry.id, null) </h2> <blockquote> <p>@entry.message</p> </blockquote> <p>posted on @entry.dateadded.tolongdatestring()</p> </div> </section> 34
View: viewbag Controller public ActionResult Index() { ViewBag.Entries = GuestbookEntry.GetGuestbookEntries(); return View(); View @foreach (var entry in ViewBag.Entries) { <h2>@html.actionlink((string)@entry.name, "Show","Guestbook",new { @entry.id,null) </h2> <blockquote> <p>@entry.message</p> </blockquote> <p>posted on @entry.dateadded.tolongdatestring()</p> 35
Razor View Engine 36
Razor view engine Wat? Een syntax taal waarmee je op een makkelijke manier binnen een view acties kan gaan uitvoeren. Razor minimaliseert de hoeveelheid syntax en extra karakters. Hoe? Om de switch te maken tussen opmaak en code gebruik je het @ teken. <h1>deze blogpost is geschreven door @gebruikers.naam </h1> + Razor expressies zijn automatisch HTML encoded -> tegen gevaar van cross-site-script injections 37
Razor Syntax voorbeelden Implicit code expression <span>@model.message</span> Explicit code expression <span>1 + 2 = @{1 + 2</span> Unencoded code expression <span>@html.raw(model.message)</span> 38
Code block @{ int x = 123; string y = "Opleiding ICT"; Tekst en opmaak combineren Code en tekst combineren Razor Syntax voorbeelden @foreach (var item in items) { <span>dit is tekst @item.eigenschap. En de tekst loopt verder</span> @if (ShowMessage) { <text>dit is puur tekst zonder html</text> 39
Razor Syntax voorbeelden Escaping the code Delimiter <p>de Twitter handle van onze opleiding is @@ikdoeict</p> Commentaar @* *@ Alles wat hiertussen staat is uit gecommentarieerd 40
Razor syntax: sectioning <div class="content-wrap"> @RenderBody() </div> <footer>@rendersection("footer")</footer> _layout.cshtml <h1>guestbook application </h1> <p>this is the main content</p> @section Footer{ This is the <strong>footer</strong> index.cshtml 41
HTML helpers 42
ASP.NET HTML controls <%@ Page Language="C#" %> <!DOCTYPE html> <html> <body> <form runat="server"> <p> <label for= Name">Please enter your name:</label><br /> <input id= Name" name= Name type="text" size="30" runat="server" /> </p> <p> <label for= Message">Please enter your message:</label><br /> <textarea cols= 40 id= Message name= Message rows="10" runat="server"> </textarea> </p> <p> <input type="submit" value= Submit entry" runat="server" /> </p> </form> </body> </html> 43
MVC HTML helpers Form ex. Non-model based: @using (Html.BeginForm(null, null, FormMethod.Post, new { id = "contactform" )) { @Html.Label("Please enter your name:") @Html.TextBox("Name") @Html.Label("Please enter your message:") @Html.TextArea("Message", new {rows=10, cols=40) <input type="submit" value="submit entry" class="button" /> 44
MVC HTML helpers Form ex. Model based: @model GuestbookTutorial.Models.LoginModel @{ ViewBag.Title = "Login"; @using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl )) { @Html.LabelFor(m => m.username) @Html.TextBoxFor(m => m.username) @Html.LabelFor(m => m.password) @Html.PasswordFor(m => m.password) <input type="submit" value="login" class="button" /> 45
Html.TextBox & Html.TextArea Vb. @Html.TextBox( Title, Model.Title) Resulteert in: <input id= Title name= Title type= tekst value= voorbeeld titel /> Html.Label Html.DropDownList Html.ListBox Html.ValidationMessage Html.Hidden Html.Password Html.RadioButton Html.CheckBox HTML helpers 46
HTML Helpers Html.ActionLink De ActionLink methode maakt een hyperlink aan naar een andere pagina (controller actie). Hiervoor maakt de HTML helper gebruik van de routing API die standaard in MVC zit. @Html.ActionLink( Link tekst", "Index", "Home") Actienaam Controller naam Doorverwijzing maken naar een bepaalde detail view met gebruik van input (bv. id) @Html.ActionLink("Edit Link tekst", "Edit", "Home", new object { id = 12, null) Route attribuut HTML attribuut 47
HTML Helpers Html.ActionLink Tip: Hoe zet je uw CSS class snel en handig op active @Html.ActionLink("Guestbook", "Index", "Guestbook", null, htmlattributes: new { @class = ViewContext.RouteData.Values["controller"].ToString() == "Guestbook"? "active" : "" ) 48
URL Helper Url.Action Zorgt ervoor dat de gevormde link niet standaard in een <a href= > </a> weergegeven wordt. <span> @Url.Action("Browse", "Store", new { genre = "Books", null) </span> <span> /store/browse?genre=jazz </span> 49
Html Action HTML.Action Laat je toe om acties binnen de view zelf uit te voeren (on render) @model Menu <ul> @foreach (var item in Model.MenuItem) { <li>@item.text</li> </ul> <body> @Html.Action("Menu") <h1>welcome to the Index View</h1> </body> 50
Validatie 51
Validatie - Model namespace GuestbookTutorial.Models { [MetadataType(typeof(GuestbookEntryMD))] public partial class GuestbookEntry { public class GuestbookEntryMD { [Required(ErrorMessage = "please enter your name")] [StringLength(150,ErrorMessage="The name you entered is too long")] public object Name { get; set; [Required(ErrorMessage = "please enter a message")] public object Message { get; set; 52
Validatie - Controller [HttpPost] public ActionResult Create(GuestbookEntry entry) { db = new DataClassesGuestbookDataContext(); if (ModelState.IsValid) {... return RedirectToAction("Index"); return View(entry); 53
Validatie - View @model GuestbookTutorial.Models.GuestbookEntry // op de plaats waar je de summary wil @Html.ValidationSummary() 54