Artiklar » .NET 4.0 » Introduktion till ASP.NET MVC 3

 
 

Introduktion till ASP.NET MVC 3

Författare: vimpyboy
Datum: den 3 augusti 2010
Antal lästa: 5295
Ej stjärnmärkt

Vad är ASP.NET MVC 3?
I mars släpptes ASP.NET MVC 2, vilket innehöll nyheter som data annotations, areor, validering och mycket annat. De här funktionerna gjorde det enklare att skapa större projekt där vi enkelt kan märka upp vad olika fält får innehålla, och sedan dela upp olika delar av sidan för att få en bättre struktur.

Det finns dock vissa saker som vi fortfarande behöver byta ut, och det finns delar som vi alltid kommer att vilja ha möjligheten att anpassa. Vi behöver även ofta upprepa kod över olika delar för till exempel ActionFilter. Vi har kunnat lösa det här tidigare, men det har krävt mycket extra kod då det inte finns något inbyggt stöd för detta i ASP.NET MVC 2.

Lösningen på många av dessa problem kommer att lösas i och med ASP.NET MVC 3 som nu finns ute som Preview.

Så, vilka är de största nyheterna och förändringarna i denna första preview av ASP.NET MVC 3?

•    Razor, ny ViewEngine för ASP.NET MVC. Razor fungerar även för ASP.NET Web Pages.
•    ASP.NET MVC 3 kräver .NET 4.0 och fungerar inte längre med .NET 3.5 SP 1.
•    Globala ActionFilter, vilket gör att vi kan registrera ActionFilters för alla Action-metoder direkt.
•    Dynamiska View- och ViewModel-properties. Tidigare använde vi ViewData, vilket är en dictionary med strängar och objekt, nu har vi istället dynamiska egenskaper för detta.
•    Möjlighet att välja ViewEngine när vi skapar en vy.
•    Stöd för att injicera egen kod tack vare utökat stöd för IoC.
•    JsonValueProviderFactory vilket gör att vi kan posta Json direkt till en sida och ta emot det som ett objekt.
•    Stöd för nya valideringsattribut i .NET 4.0.
•    Möjlighet att använda IValidateObject för modellerna, så vi kan validera modellens värden direkt från modellen i sig.
•    Nya typer av ActionResult.

Jag kommer att ta upp de flesta nyheterna i artikeln, och det andra kommer att publiceras i separata artiklar.

Skapa ett första ASP.NET MVC-projekt
När ASP.NET MVC 3 är installerat så kan vi se att vi får nya projekttyper i Visual Studio 2010. När vi väljer att skapa ett nytt projekt så kan vi se det här:

Klicka för att se bilden i full skala...


Det vi kan se här är att vi har tre nya projekttyper, ”ASP.NET MVC 3 Web Application (ASPX)”, ”ASP.NET MVC 3 Web Application (Razor)” och ”ASP.NET MVC 3 Empty Web Application”. Skapar vi ett projekt med ASPX så får vi ett vanligt standardprojekt där WebFormViewEngine används, precis som i tidigare versioner av ASP.NET MVC 3, men om vi skapar ett med Razor så används istället den nya Razor-motorn för våra vyer. I det här fallet väljer jag att skapa ett Razor-projekt.

Det vi får upp nu är ett vanligt ASP.NET MVC-projekt med mappar för Models, Views och Controllers. Det är dock några skillnader mot hur projekten såg ut i ASP.NET MVC 2. Först och främst så har vi .cshtml-filer i Views-mapparna:

Klicka för att se bilden i full skala...

Cshtml är filändelsen för Razor-vyer. Vi kan fortfarande ha aspx-filer, men då används samma ViewEngine som i ASP.NET MVC 2.

Öppnar vi upp Views\Home\Index.cshtml så får vi det här:

Kod:
@inherits System.Web.Mvc.WebViewPage

@{
  View.Title = "Home Page";
  LayoutPage = "~/Views/Shared/_Layout.cshtml";
}

<h2>@View.Message</h2>
<p>
  To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc&quot; title="ASP.NET MVC Website">http://asp.net/mvc&lt;/a&gt;.
</p>



Det finns ingen intellisense och syntax-highlighting för Razor i Preview 1, så vill ni ha det så kan ni använda aspx-filer tills det finns tillgängligt.

Kikar vi på koden så kan vi se några intressanta saker. Först och främst så har vi @inherits på översta raden. Där anger vi vilken typ av sida det är. I ASP.NET MVC 2 använde vi ViewPage eller ViewPage<T>, och i ASP.NET MVC 3 med Razor använder vi alltså WebViewPage eller WebViewPage<T>. Använder vi aspx-filer med ASP.NET MVC 3 så är det fortfarande ViewPage.

När vi sedan kommer till kodblocket nedan så ser vi två rader kod. Den första sätter View.Title, och den andra sätter LayoutPage. View är den dynamiska motsvarigheten till ViewData, och LayoutPage sätter vilken MasterPage vi vill använda.

Efter kodblocket så skriver vi ut View.Message, vilket även det är ett ViewData-objekt.
Hur kommer det sig att vi först sätter ett värde till View, och sedan läser av ett annat?
Om vi börjar med att kika i HomeController.cs så kan vi se att den ser ut så här:

Kod:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcRazor.Controllers
{
  public class HomeController : Controller
  {
  public ActionResult Index()
  {
  ViewModel.Message = "Welcome to ASP.NET MVC!";

  return View();
  }

  public ActionResult About()
  {
  return View();
  }
  }
}



Här sätter vi ViewModel.Message. ViewModel är précis som View den dynamiska motsvarigheten till ViewData. Det här värdet läser vi sedan av i vår vy.

Men vi sätter även ett värde till View.Title, utan att läsa av det i vyn. Det som händer är att det värdet istället skickas vidare till vår LayoutPage som ser ut så här:

Kod:
@inherits System.Web.Mvc.WebViewPage

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;
<html xmlns="http://www.w3.org/1999/xhtml&quot;&gt;
<head>
  <title>@View.Title</title>
  <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
</head>

<body>
  <div class="page">

  <div id="header">
  <div id="title">
  <h1>My MVC Application</h1>
  </div>

  <div id="logindisplay">
  @Html.Partial("_LogOnPartial")
  </div>

  <div id="menucontainer">

  <ul id="menu">
  <li>@Html.ActionLink("Home", "Index", "Home")</li>
  <li>@Html.ActionLink("About", "About", "Home")</li>
  </ul>

  </div>
  </div>

  <div id="main">
  @RenderBody()
  <div id="footer">
  </div>
  </div>
  </div>
</body>
</html>



Här kan vi se att vi läser av View.Title i rubriken. Värdet har alltså skickats från vår vy till vår LayoutPage, precis som vi tidigare har gjort med en separat ContentPlaceholder.

I vår LayoutPage använder vi sedan standard-helpers för ASP.NET MVC, precis som vi har gjort tidigare. Det finns dock en del här som är ny, och det är RenderBody() som vi använder i slutet av filen. Det är där vår vy kommer att renderas.

Startar vi nu projektet genom att klicka på F5 så får vi det här:

Klicka för att se bilden i full skala...


Sidan ser ut precis som de har gjort i tidigare versioner av ASP.NET MVC, och vi kan nu sätta igång och bygga ut sidan.

Skapa en gästbok
För att få veta vad besökarna tycker om sidan så kan det vara kul att ha en gästbok. Jag kommer att skapa upp en från grunden där jag använder de nya funktionerna i ASP.NET MVC 3 samt lagrar sedan alla inlägg i en SQL Server Compact 4-databas som är baserad på modellen.

Först och främst så behöver vi skapa en modell. Vi kallar modellen för GuestbookEntry och ger den det här utseendet:

Kod:
using System;
using System.ComponentModel.DataAnnotations;

namespace MvcRazor.Models
{
  public class GuestbookEntry
  {
  public int Id { get; set; }

  [StringLength(25)]
  [Required]
  public string Name { get; set; }

  [DataType(DataType.EmailAddress)]
  [Required]
  public string Email { get; set; }

  [Required]
  public string Message { get; set; }

  public DateTime Posted { get; set; }
  }
}



För att skapa upp en databas så skapar jag en ny mapp vid namn Code, där jag skapar en ny klass vid namn DataContext. Där lägger jag till det här:

Kod:
using System.Data.Entity;
using MvcRazor.Models;

namespace MvcRazor.Code
{
  internal class DataContext : DbContext
  {
  public DbSet<GuestbookEntry> Guestbook { get; set; }
  }
}



För att komma åt nya funktionerna i Entity Framework 4 så måste en referens till EF 4 CTP 4 läggas till. Det som sker här är att vi säger att vi i databasen vill ha åtkomst till vår modell. Vi kommer därmed att kunna lagra den direkt i databasen utan att behöva skriva SQL för att jobba med datan.

För att databasen ska skapas upp automatiskt om den inte finns så behöver vi lägga till det här i Application_Start i global.asax:

Kod:
Database.SetInitializer<DataContext>(new RecreateDatabaseIfModelChanges<DataContext>());



Det gör så att databasen uppdateras varje gång modellen ändras.
Det sista som behövs innan vi kan använda modellen är en nyckel i web.config som säger vilken databas som skall användas:

Kod:
<add name="DataContext" connectionString="Data Source=|DataDirectory|DataContext.sdf" providerName="System.Data.SqlServerCe.4.0" />



Eftersom inte databasen finns så kommer den att skapas upp när vi kör applikationen första gången.

Hur man kan använda DataContext för att jobba med databasen
För att jobba mot databasen så behöver vi skapa upp en controller som skickar data mellan databasen och våra vyer. Jag kommer nu att skapa upp en controller vid namn GuestbookController där jag bockar i rutan för extra metoder:

Klicka för att se bilden i full skala...


Då vi inte behöver all funktionalitet i vår gästbok så tar jag bort några irrelevanta action-metoder och har nu det här:

Kod:
using System.Web.Mvc;
using MvcRazor.Code;
using MvcRazor.Models;

namespace MvcRazor.Controllers
{
  public class GuestbookController : Controller
  {
  DataContext _ctx = new DataContext();

  // GET: /Guestbook/
  public ActionResult Index()
  {
  return View();
  }

  // GET: /Guestbook/Create
  public ActionResult Create()
  {
  return View();
  }

  // POST: /Guestbook/Create
  [HttpPost]
  public ActionResult Create(GuestbookEntry entry)
  {
  try
  {
  return RedirectToAction("Index");
  }
  catch
  {
  return View();
  }
  }
  }
}



Utanför metoderna så skapar jag en ny instans av DataContext, vilken kommer att användas i de olika metoderna för att jobba med datan.

I index-metoden så vil vi lista alla inlägg i gästboken. Då vi har en ObjectContext (i det här fallet DataContext), blir det väldigt enkelt att göra. Index-metoden får det här utseendet:

Kod:
public ActionResult Index()
{
  return View(_ctx.Guestbook.ToList());
}



Vi uppdaterar även Create-metoden så att våra inlägg ska kunna sparas:

Kod:
// POST: /Guestbook/Create
[HttpPost]
public ActionResult Create(GuestbookEntry entry)
{
  try
  {
  entry.Posted = DateTime.Now;

  _ctx.Guestbook.Add(entry);
  _ctx.SaveChanges();

  return RedirectToAction("Index");
  }
  catch
  {
  return View();
  }
}



Det är väldigt enkelt att arbeta med datan genom DataContext, och nu har vi allt som krävs för att vi ska kunna lista och spara inlägg I vår controller.

Nästa steg blir att skapa vyerna, så vi börjar med att skapa Index-vyn. Det ska vara en hårt typad vy (GuestbookEntry), det ska vara en listning, och vi vill använda Razor som ViewEngine. Högerklicka därför i Index-metoden och välj Add View. Har du suttit med ASP.NET MVC 2 eller tidigare så ser du nog att rutan har fått en del förändringar:

Klicka för att se bilden i full skala...


Nyheten mot tidigare är att vi nu kan välja vilken view engine som skall användas, och automatiskt använda rätt T4-template för att generera en vy. Klickar vi nu på Add så genereras vyn åt oss. Den har dock vissa fält som vi inte vill ha med i listningen, som länkar för att ändra, visa detaljer och ta bort, samt att den har ett fält för Id:t. Dessa tar vi bort. Resultatet efter ändringarna blir följande:

Kod:
@inherits System.Web.Mvc.WebViewPage<IEnumerable<MvcRazor.Models.GuestbookEntry>>

@{
    View.Title = "Guestbook";
    LayoutPage = "~/Views/Shared/_Layout.cshtml";
}

    <h2>Index</h2>

    <table>
        <tr>
            <th>
                Name
            </th>
            <th>
                Email
            </th>
            <th>
                Message
            </th>
            <th>
                Posted
            </th>
        </tr>

    @foreach (var item in Model) {
    
        <tr>
            <td>
                @item.Name
            </td>
            <td>
                @item.Email
            </td>
            <td>
                @item.Message
            </td>
            <td>
                @String.Format("{0:g}", item.Posted)
            </td>
        </tr>
    
    }

    </table>

  <p>
  @Html.ActionLink("Create New", "Create")
  </p>



Vyn påminner mycket om den vyn som finns på startsidan, med skillnaden att vi nu har en modell specificerad, vilket vi kan se på första raden. Sen används Razor istället för vanliga kodblock som tidigare (<%%>).

Sen skapar vi även en Create-vy på samma sätt som vi skapade index-vyn. Skillnaden är att vi väljer Create istället för List.

När vi skapar vyn så har vi fått fält för Id och datum, vilket vi inte vill att användaren skall ange, så vi plockar bort det. Vyn ser då ut så här:

Kod:
@inherits System.Web.Mvc.WebViewPage<MvcRazor.Models.GuestbookEntry>

@{
  View.Title = "Create";
  LayoutPage = "~/Views/Shared/_Layout.cshtml";
}

<h2>Create</h2>

  @using (Html.BeginForm()) {
  @Html.ValidationSummary(true)

  <fieldset>
  <legend>Fields</legend>
  
  <div class="editor-label">
  @Html.LabelFor(model => model.Name)
  </div>
  <div class="editor-field">
  @Html.TextBoxFor(model => model.Name)
  @Html.ValidationMessageFor(model => model.Name)
  </div>
  
  <div class="editor-label">
  @Html.LabelFor(model => model.Email)
  </div>
  <div class="editor-field">
  @Html.TextBoxFor(model => model.Email)
  @Html.ValidationMessageFor(model => model.Email)
  </div>
  
  <div class="editor-label">
  @Html.LabelFor(model => model.Message)
  </div>
  <div class="editor-field">
  @Html.TextBoxFor(model => model.Message)
  @Html.ValidationMessageFor(model => model.Message)
  </div>
  
  <p>
  <input type="submit" value="Create" />
  </p>
  </fieldset>

  }




Om vi trycker på F5 för att starta sidan så får vi upp det här:

Klicka för att se bilden i full skala...


Vi har nu skapa en enkel gästbok där vi kan lägga till nya inlägg. Databasen skapas upp automatiskt baserat på DataContext-klassen vi skapade, så den behöver vi inte bry oss om.
Om vi öppnar Create-vyn och försöker posta utan att ange värden i fälten så ser vi även att vi automatiskt fick med validering baserat på de attribut vi satte i modellen.
 
     

  » Logga in  
 
Användarnamn

Lösenord

 
     

  » Bli medlem  
  Bli medlem på ASPsidan!  
     

     
  Microsoft  
     

  » Partners  
  Comsolvia  
     
  » ANNONS  
  ingen annons än  
     

  » Senast online  
  Endast för inloggade  
  Antal inloggade: 1  
     

Copyright © 2007 www.ASPsidan.se
ingen sponsrar längre ASPsidan med Dedikerad Server
ASPsidan RSS
   
 XHTML / CSS
Det tog 0,0781 sekunder att ladda sidan