Asp.net mvc intro PER KVARNBRINK, 2015-01-27
Byggstenarna i ett mvc-projekt 1. Databasen 2. Datamodellen (M:et) 3. Entity framwork 4. Routing 5. Kontroller (C:et) 6. Vy (V:et) 7. Vymodeller 8. Troligen en radda språk/verktyg: sql, linq, C#, Razor, Jquery, html, css, json, xml
Datamodellen 1. Skrivs i ett programmeringsspråk, t.ex. C# 2. Beskriver data som en klass, egenskaper 3. Har nästan alltid en motsvarighet i databasen, tabeller, fält, relationer 4. Följer med som en röd tråd genom hela strukturen, i vyn (view), i kontrollern, i kontrollens action och i databasen. 5. Kan innehålla randvillkor, t.ex. om det är obligatoriskt, begränsat, antal tecken etc. Detta gör att valideringen styrs från Modellen. 6. Man bör se till att alla randvillkor finns i modellen. Det är en dålig lösning att lägga till det när alla views är klara. Valideringen blir enkel då.
Här har jag skrivit en egen modell! public class UserDetail public int id get; set; public string namn get; set; public DateTime datum_created get; set; public class UserMethod public int CreateUser (UserDetail) //lägg till kod här //komplettera så att det blir CRUD, ReadUser, UpdateUser, DeleteUser
namespace NewOmtenta.Models using System; using System.Collections.Generic; Här har Entity Framework skrivit en egen modell! public partial class Amne public Amne() this.kursers = new HashSet<Kurser>(); [DisplayName("Kurs-Id")] public int Id get; set; [DisplayName("Ämne")] public string ANamn get; set; public virtual ICollection<Kurser> Kursers get; set;
Man kan lägga till attribut till fälten i datamodellen using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations; [DisplayName("Efternamn")] [Required(ErrorMessage = "Ange efternamn")] [StringLength(30, ErrorMessage = "Det är max 30 tecken för detta fält.")] public string Efternamn get; set;
Databasen och Entity Framework (EF) 1. En databas är en databas! 2. Databasen har tabeller, fält och relationer inga konstigheter alls! 3. All data brukar sparas i databasen. Controller, datalagret och views skyfflar och moddar data 4. EF kopplar ihop datamodell med databas och man väljer mellan två metoder: - Database first EF bygger då upp datamodellen med CRUD, dvs det kommer att finnas ett detaljobjekt och ett metodobjekt med metoder för CRUD - Code first EF bygger då upp databas och utgår från hur modellen ser ut 5. Om man har bråttom så kan man använda Scaffolding New Scaffolded Item - då får man en controller och ett antal views automatiskt!
Controllern 1. Tar emot en förfrågan, request, från Internet och levererar en passande view med eller utan data 2. Den förstår skillnaden mellan, och hanterar get och post 3. Kan hämta data (ofta vid get) eller skicka data (ofta vid post) till databasen 4. Hanterar databasfrågorna. 5. Man kan välja teknik för databasfrågorna, frågespråket LINQ är vanligt men SQL går också bra. 6. Den hanterar också inloggning, t.ex. kan den kontrollera att en viss användare kan göra vissa saker 7. Den kan också lägga till extra säkerhet för att säkerställa att inmatad data kommer från ett pålitligt formulär (formulär är en webbsida med inmatningsfält och en submit-knapp) 8. Den anpassar sig till de regler för routing som gäller för sajten 9. En kontroller är en kontroller!
Routing Routing sker enligt vissa mönster: http://localhost:63421/tentamenslista/index Action i controllern (och det finns ett defaultvärde) Namn på controllern (och det finns ett defaultvärde) Adressen till webbservern http://localhost:63421/amne/edit/1 Extra parameter t.ex. ett id för ett ämne
Routing exempel: public static void RegisterRoutes(RouteCollection routes) routes.ignoreroute("resource.axd/*pathinfo"); routes.maproute( name: "Default", url: "controller/action/id", defaults: new controller = "Home", action = "Index", id = UrlParameter.Optional ); I routingen ser jag defaultadressen http://localhost/home/index/ ( = http://localhost/)
Controllen ett exempel public class AmneController : Controller Controllern heter Amne och svarar mot http://domännamn/amne private NewOmtentaEntities1 db = new NewOmtentaEntities1(); // GET: /Amne/ [Authorize(Users = "MonaLisa,Valentina,Catharina")] public ActionResult Index() Action Index, svarar mot http://domännamn/amne/index/ return View(db.Amnes.ToList()); Här passar controllern data till vyn
Controllen ett exempel till: Edit - get // GET: /Amne/Edit/5 [Authorize(Users = "MonaLisa,Valentina,Catharina")] public ActionResult Edit(int? id) Action Edit, svarar mot http://domännamn/amne/edit/5, get if (id == null) return new HttpStatusCodeResult(HttpStatusCode.BadRequest); Amne amne = db.amnes.find(id); if (amne == null) return HttpNotFound(); return View(amne); Här passar controllern data till vyn
Controllen ett exempel till: Edit - post // POST: /Amne/Edit/5 // To protect from overposting attacks, please enable the specific properties you want to bind to, for // more details see http://go.microsoft.com/fwlink/?linkid=317598. [HttpPost] [ValidateAntiForgeryToken] [Authorize(Users = "MonaLisa,Valentina,Catharina")] public ActionResult Edit([Bind(Include = "Id,ANamn")] Amne amne) if (ModelState.IsValid) db.entry(amne).state = EntityState.Modified; db.savechanges(); Action Edit, svarar mot http://domännamn/amne/edit/5, post och den binder data från formuläret return RedirectToAction("Index"); Om allt går bra så skickas användaren till Index return View(amne); Om inte sidan valideras som korrekt så skickas användaren tillbaka till vyn
Sista handen på konstverket The View! 1. Vyn sätter ihop data med html-kod 2. Vyn exekverar på servern och skickar html-kod till klienten 3. I vyn kan man skriva C#-kod 4. I vyn kan man också använda Razor ett språk som hjälper till att baka ihop allt eller som är smidigt på att göra bra html-taggar (html-helper) 5. Vyn kan med fördel ta emot data i välförpackad form t.ex. IEnumerable (enumererbar data) 6. Här löser man problem (programmeringsuppgifter) och jämför gärna med övriga delar i MVC som i huvudsak förpackar om och skickar data. (Det betyder inte att det är dåligt)
Underskatta inte vyn 1. Det är nästan som gamla tekniken MS ASP active server pages 2. Det är nästan som vanlig php, pretty home page 3. Det är nästan som asp.net webforms om man skippar code behind och lägger allt i.asp-sidan 4. Man kan göra en hel del i vyn
Delar i en Vy @model IEnumerable<NewOmtenta.Models.Amne> @ ViewBag.Title = "Ämnen"; Sätter sidans titel Beskriver inkommande data <h2>ämnen</h2> <p> </p> Blanda med html @Html.ActionLink("Skapa ett nytt ämne", "Create") Blir en länk till Amne/Create/ där Create är Action i controllern Amne
Delar i en Vy <table class="table"> <tr> <th> Ämnen </th> <th></th> </tr> En vy kan innehålla en hel del html Och man kan loopa igenom data @foreach (var item in Model) //rendera ut koden för ämnen här, se nästa slide </table>
Delar i en Vy @foreach (var item in Model) <tr> <td> @Html.DisplayFor(modelItem => item.anamn) </td> <td> Skriver ut data @Html.ActionLink("Ändra", "Edit", new id=item.id ) @Html.ActionLink("Detaljerad vy", "Details", new id=item.id ) @Html.ActionLink("Ta bort", "Delete", new id=item.id ) </td> </tr>
I en vy kan man rendera olika kod om en användare är inloggad @if (@User.Identity.IsAuthenticated) else <div class="bigtext"> </div> <ol> </ol> <ol> </ol> @foreach (var item in Model)rendera ut data och html här Blanda in html @foreach (var item in Model)eller rendera ut data och html här
I en vy kan man också fixa datum @ string s = item.datum.tostring(); s = s.replace("00:00:00", ""); s = s.replace(" ", ""); <td> @s, @Html.DisplayFor(modelItem => item.dag), </td>
Det finns också något som heter vymodeller view models 1. En vymodell är en datamodell som görs för att kopplas till en vy 2. Modellen beskriver data 3. Rätt utfört så får man hjälp att passa data till vyn och hantera data i vyn
Exempel vymodell, cat.cs namespace ViewModelWithCats.ViewModel public class Cat // Auto-implemented properties. public int Age get; set; public string Name get; set;
Exempel vymodell, controllern using ViewModelWithCats.ViewModel; namespace ViewModelWithCats.Controllers public class CatController : Controller // // GET: /Cat/ // Här ska action för index komma public ActionResult Index() List<Cat> cats = new List<Cat> new Cat() Name = "Sylvester", Age=8, new Cat() Name = "Whiskers", Age=2, new Cat() Name = "Sasha", Age=14 ; Cat cat = new Cat Age = 10, Name = "Fluffy" ; cats.add(cat); return View(cats);
Exempel i controllern - linq List<Cat> ordered_cats = new List<Cat> ; ordered_cats = cats.orderby(x => x.age).tolist(); ordered_cats = cats.orderby(x => x.age).thenby(x => x.name).tolist(); ordered_cats = cats.orderby(x => x.age).where(x => x.name == "Sylvester").ToList();
Exempel vymodell, cat/index.cshtml @model IEnumerable<ViewModelWithCats.ViewModel.Cat> @ ViewBag.Title = "Index"; <h2>mina katter</h2> <ul> @foreach (var item in Model) <li>@html.displayfor(modelitem => item.name), @Html.DisplayFor(modelItem => item.age) år</li> </ul>
Och så här blir html-koden (förstås ) <h2>mina katter</h2> <ul> <li>sylvester, 8 år</li> <li>whiskers, 2 år</li> <li>sasha, 14 år</li> <li>fluffy, 10 år</li> </ul>
Något mer om Linq IEnumerable<Cat> ordered_cats = from katt in cats orderby katt.name ascending select katt; (Ordering data) IEnumerable<Cat> ordered_cats = from m in cats where m.name == Sylvester select m; (Filtering data) Mer: Joinig data Grouping data Plus mycket mer, tex. samla data från två tabeller eller två listor
M C 10. Lägg ihop allt till en helhet V 1. Request 2. Vilken controller? Webbläsare till routern Routern Controllern 9. Html V Vyn 1. 2. 3. Vilken action? 8. Data! C 3. Action M 4. Data? Entity Framework 5. Data? 7. Data! DataModel 6. Data! Datamodellen håller koll! Databasen Html Css Javascript Bilder
M V Ett vanligt sätt att hantera formulär C Gör en controller med tre action samt två vyer: 1. Action Index() returnerar en vy som innehåller formuläret 2. I webbläsaren fyller man i kontrollerna och submittar. Det är formtaggen som avgör var data ska skickas. 3. Formuläret returnerar till en action: GetData(). Den är av typen HttpPost. Här kan inparametern vara av typen FormCollection men det finns andra sätt att ta in data i metoden. 4. GetData tar emot data och skickar över jobbet till action ShowData(). Den returnerar inte en vy, utan en RedirectToAction() 5. ShowData avslutar med att skicka över informationen till vyn med samma namn. Det går att se att data levereras antingen ett verktyg i en webbläsare eller i en breakpoint i VisualStudio. Felsökningen kan gå lättare om man delar upp jobbet på tre actions.