Michal Augustýn www.augi.cz ALWIL Software Microsoft Most Valuable Professional
ASP.NET/IIS MVC v ASP.NET MVC Routing Controllery Views master pages kompozice
framework pro tvorbu webového rozhraní na platformě ASP.NET používá návrhový vzor MVC podobně jako Nette, Django, SpringMVC, RoR, ZendFW, nyní ve verzi 2, pracuje se na verzi 3 rozšiřitelný/upravitelný v mnoha směrech open-source (licence Ms-PL) zdrojáky dostupné na Codeplex.com
.NET Framework ~ Java C#, VB.NET, F#, IronPython, Internet Information Services ~ Apache web.config ~.htaccess module ~ module handler ~ handler ASP.NET je handler
IIS ASP.NET WebForms MVC
Požadavek GET http://domena.cz/produkt/zobraz/10 IIS moduly ASP.NET [ISAPI filter] handler moduly Výsledek <html> </html>
request response 1 routing Controller 5 2-3 4 Model View
public class HomeController : Controller public ActionResult Index() ViewData["Message"] = "Welcome to ASP.NET MVC!"; return View(); public ActionResult About() return View();
defaultně se používá WebForms view-engine view == aspx stránka public ViewResult Show(int id) Product p = BusinessLayer.Load(id); return View("Show", p); <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Product>" %> <asp:content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server >Home Page</asp:Content> <asp:content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server"> <h2><%= Html.Encode(ViewData["Message"]) %></h2> <p><%= Html.Encode(ViewData.Model.Name) %></p> </asp:content>
určuje tvar url konfigurace v souboru Global.asax.cs pravidla se vyhodnocují v pořadí vložení mapuje zpracování url na kontroler a akční metodu umožňuje generování url výchozí nastavení: /Home/Product/20 routes.maproute( "Default", // Route name "controller/action/id", // URL with parameters new controller = "Home", action = "Index", id = "" // Parameter defaults );
třída odvozená od třídy Controller obsahuje akční metody (vrací ActionResult) 1. čte data z requestu 2. komunikuje s modelem 3. vybírá view a předává mu data k prezentaci Controller Model View
parametry requestu mapovány na vstupní parametry akční metody ( deserializace ) public ActionResult Show(int id) Routovací parametry: controller, action, id POST parametry: product.id, product.name, product.price public ActionResult Create(Product product) manuálně: [Try]UpdateModel vlastní konverze - IModelBinder
slouží k zápisu výsledku do HttpResponse public abstract class ActionResult public abstract void ExecuteResult(ControllerContext context); return View("Index"); // ViewResult return PartialView("Product"); // PartialViewResult return Json(myObject); // JsonResult return Redirect("http://www.bing.com/"); // RedirectResult return RedirectToAction("Index"); // RedirectToRouteResult return File("soubor.txt", "txt/plain"); // FilePathResult return new MyRssResult(myCollection); // Rss(myCollection)
vlastní action-result na přesměrování public class MyRedirectResult : ActionResult public string Url get; set; public override void ExecuteResult(ControllerContext context) context.httpcontext.response.redirect(this.url); return new MyRedirectResult Url = "http://www.bing.com" ;
1. hash-table ViewData ViewData[ message ] = Hello world! ; 2. Model libovolná třída ViewData.Model = new MyViewModel(); typově bezpečné Controller Model View
všechny produkty public ViewResult Index() IEnumerable<Product> products = BusinessLayer.LoadAll(); return View(products); // ViewData.Model = products; jeden produkt public ViewResult Show(int id) Product p = BusinessLayer.Load(id); return View("Show", p);
editace produktu public ViewResult Update(int id) Product p = BusinessLayer.Load(id); return View("Update", p); [AcceptVerbs(HttpVerbs.Post)] public RedirectToRouteResult Update(int id, FormCollection formdata) Product p = BusinessLayer.Load(id); if (TryUpdateModel<IProduct>(p, formdata.tovalueprovider())) BusinessLayer.Update(p); return RedirectToAction("Update", new id = p.id );
master page určuje layout stránky definuje díry k vyplnění (ContentPlaceHolder) content page plní ContentPlaceHoldery při zobrazení stránky řekneme jakou master page použít jak vyplnit jednotlivé díry
<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title><asp:contentplaceholder ID="TitleContent" runat="server" /></title> <link href="../../content/site.css" rel="stylesheet" type="text/css" /> </head> <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Product>" %> <asp:content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> Home Page - <%= Html.Encode(Model.Name) %> </asp:content>
<% using (Html.BeginForm()) %> <fieldset> <legend>fields</legend> <p> <%= Html.LabelFor(model => model.name) %> <%= Html.TextBoxFor(model => model.name) %> <%= Html.ValidationMessageFor(model => model.name) %> </p> <p> <%= Html.LabelFor(model => model.price) %> <%= Html.TextBoxFor(model => model.price) %> <%= Html.ValidationMessageFor(model => model.price) %> </p> <p> <input type="submit" value="save" /> </p> </fieldset> <% %>
<% using (Html.BeginForm()) %> <fieldset> <legend>fields</legend> <%= Html.EditorFor(model => model.name) %> <%= Html.EditorFor(model => model.price) %> <p> <input type="submit" value="save" /> </p> </fieldset> <% %> <% using (Html.BeginForm()) %> <fieldset> <legend>fields</legend> <%= Html.EditorForModel() %> <p> <input type="submit" value="save" /> </p> </fieldset> <% %>
<% Html.EnableClientValidation(); %> <%= Ajax.ActionLink("Odkaz", "IndexAjax", "Home", new AjaxOptions InsertionMode = InsertionMode.Replace, LoadingElementId = "loading-image", UpdateTargetId = "dynamic-content", ) %>
standardní umístění ~/Views/controller/view.[aspx,ascx] ~/Views/Shared/view.[aspx,ascx] lze změnit (stejně jako vše) partial views: UserControls (ascx) dědí z ViewUserControl<TModel> Html.RenderPartial( MyPView, model)
vyšší úroveň kompozice proběhne celý round-trip jde proti filozofii MVC, ale je užitečný Kdy použít RenderAction a kdy RenderPartial? Action pro rendering nutná komunikace s modelem Partial všechna data dostupná
přijde request: routing: controller = Product action = Show id = 21 model-binding: id = 21 public ViewResult Show(int id) Product p = BusinessLayer.Load(id); return View("Show", p); /Product/Show/21
public ViewResult Show(int id) Product p = BusinessLayer.Load(id); return View("Show", p); <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Product>" %> <asp:content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> Product details </asp:content> <asp:content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <h2><%= Html.Encode(Model.Name) %></h2> <p><%= Html.Encode(Model.Description) %></p> <p>price: <%= Html.Encode(Model.Price) %></p> </asp:content>
aspektové rozšíření akčních metod lze aplikovat i na celé controllery [Authorize(Roles = "Admin")] [OutputCache(CacheProfile="TestProfile")] [HandleError(View="Error")] public ActionResult Test() return new EmptyResult();
public interface IAuthorizationFilter void OnAuthorization(AuthorizationContext filtercontext); public interface IActionFilter void OnActionExecuting(ActionExecutingContext filtercontext); void OnActionExecuted(ActionExecutedContext filtercontext); public interface IResultFilter void OnResultExecuting(ResultExecutingContext filtercontext); void OnResultExecuted(ResultExecutedContext filtercontext); public interface IExceptionFilter void OnException(ExceptionContext filtercontext);
1.0 2.0 silně typovější Html.RenderAction display & edit templates 3.0 komponenty (grid, captcha, ) multiple partial updates, client templates, scaffolding, DI, MEF,
MVC jednoduché čistý kód nutí správně strukturovat plná kontrola nad html zezačátku vyžaduje více znalostí WebForms složitější model RAD, komponentový vývoj odstínění od stavovosti http ViewState, PostBack
http://asp.net/mvc http://haacked.com Phil Haack http://weblogs.asp.net/scottgu - ScottGu http://forum.builder.cz české fórum i o.net http://www.aspnetmvc.cz snad už brzy
a odpovědi