t22 the asp.net mvc framework - …download.microsoft.com/documents/uk/remix08/day2/01_… · ppt...
TRANSCRIPT
ASP.NET MVCA new option for ASP.NETEasily testable and TDD friendly“Closer to the Metal” option
HTTP programming model surfacedMore control over <html/> and URLs
Not for everyone (car vs. motorcycle)
Lots of WebForms improvements coming
GoalsMaintain Clean Separation of Concerns
Enable highly maintainable applications
Enable Easy Unit TestingSupport Red/Green TDD
Extensible and PluggableSupport replacing any component of system
GoalsEnable clean URLs and HTML
SEO and REST friendly URL structures
Great integration within ASP.NETAll the same providers still workMembership, Session, Caching, etc.
Current StatusASP.NET MVC Preview 5 Currently Out
Beta release in a few weeks
Final V1 by end of the year
Production Deployment Supported Now
MVCModel
ControllerView
How ASP.NET MVC WorksBrowser Web
Serverhttp://myserver.com/Products/
ProductsController(Controller)
Product(Model) SQL
Edit.aspx
(View)
http://myserver.com/Products/Edit/5
List.aspx
(View)ViewData
DemoBuilding a Product Catalog
Understanding Form Interactions
ProductsController
(Controller)
GET: /Products/Edit/5
Product(Model) SQL
POST: /Products/Edit/5
URL:
DemoHandling Updates
Filter AttributesEnable custom behavior to be added to Controllers and Controller actionsExamples:
[OutputCache][Authorize][HandleError]
DemoAttributes
Custom URL RoutingCan setup custom URL routing rules within the RegisterRoutes() method in Global.asaxEnables very flexible mapping and route rules:
Default parametersConstraintsNamed routesWildcard “catch-all” routes
DemoCustom Routing
AJAX HelpersBuilt-in AJAX helper object within views
Ajax.Form()Ajax.ActionLink()Ajax.RouteLink()
Automatically emit client-side JavaScript
Use ASP.NET AJAX library by defaultPluggable to use jQuery, Prototype, or other AJAX libraries as well
More Extensibility GoodnessCustom Route RulesController FactoriesCustom IController implementationsCustom View Engines
SummaryA new option for ASP.NET.More control over your <html/> and URLsMore easily testable approachNot for everyone – only use it if you want toShipping later this year
© 2008 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries.
The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after
the date of this presentation. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
Interfaces and TestingMockable Intrinsics
HttpContextBase, HttpResponseBase, HttpRequestBase
Extensibility IControllerIControllerFactoryIRouteHandlerViewEngineBase
Testing Controller ActionsNo requirement to test within ASP.NET runtime.
Can mock parts of runtime you want to fake[TestMethod]public void ShowPostsDisplayPostView() { BlogController controller = new BlogController(…); var result = controller.ShowPost(2) as ViewResult;
Assert.IsNotNull(result); Assert.AreEqual(result.ViewData[“Message”], “Hello”);}
Common QuestionsShould I use WebForms or MVC?Difference between MVC and MVP?Do I have to write <%= %> code in my view?What about AJAX?How fast/scalable is it?When will it ship?
Even More Detail – Request Flow• You can futz at each step
in the processRequest
ExtensibilityViewsControllersModelsRoutes
…are all Pluggable
ViewEngineBaseView Engines render outputYou get WebForms by defaultCan implement your own
MVCContrib has ones for Brail, NvelocityNHaml is an interesting one to watch
View Engines can be used toOffer new DSLs to make HTML easierGenerate totally different mime/types
Images, RSS, JSON, XML, OFX, VCards, whatever.
View Engine Base ClassViewEngineBase
public abstract class ViewEngineBase { public abstract void RenderView(ViewContext
viewContext); }
NHaml – Extreme Custom Views<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
AutoEventWireup="true" CodeBehind="List.aspx"
Inherits="MvcApplication5.Views.Products.List" Title="Products" %><asp:Content ContentPlaceHolderID="MainContentPlaceHolder"
runat="server"> <h2><%= ViewData.CategoryName %></h2> <ul> <% foreach (var product in ViewData.Products) { %> <li> <%= product.ProductName %> <div class="editlink"> (<%= Html.ActionLink("Edit", new { Action="Edit",
ID=product.ProductID })%>) </div> </li> <% } %> </ul> <%= Html.ActionLink("Add New Product", new { Action="New" }) %></asp:Content>
NHaml – Extreme Custom Views%h2= ViewData.CategoryName
%ul - foreach (var product in ViewData.Products)
%li = product.ProductName .editlink = Html.ActionLink("Edit", new { Action="Edit", ID=product.ProductID }) = Html.ActionLink("Add New Product", new { Action="New" })
APPENDIXMVC
ControllerBase Controller Class
Basic Functionality most folks will useIController Interface
Ultimate Control for the Control FreakIControllerFactory
For plugging in your own stuff (IOC, etc)
Basic Controller HandlingScenarios, Goals and Design
URLs route to controller “actions”, not pages – mark actions in Controller.Controller executes logic, chooses view.All public methods are accessible
public void ShowPost(int id) { Post p = PostRepository.GetPostById(id); if (p != null) { RenderView("showpost", p); } else { RenderView("nosuchpost", id); }}
Controller Base Classpublic class Controller : IController { … protected virtual void Execute(ControllerContext
controllerContext); protected virtual void HandleUnknownAction(string
actionName); protected virtual bool InvokeAction(string actionName); protected virtual void InvokeActionMethod(MethodInfo
methodInfo); protected virtual bool OnError(string actionName, MethodInfo methodInfo, Exception exception); protected virtual void
OnActionExecuted(FilterExecutedContext filterContext);
protected virtual bool OnActionExecuting(FilterExecutedContext filterContext);
protected virtual void RedirectToAction(object values); protected virtual void RenderView(string viewName, string masterName, object viewData);}
Controller – Regular APIspublic class Controller : IController { … protected virtual void Execute(ControllerContext
controllerContext); protected virtual void HandleUnknownAction(string
actionName); protected virtual bool InvokeAction(string actionName); protected virtual void InvokeActionMethod(MethodInfo
methodInfo); protected virtual bool OnError(string actionName, MethodInfo methodInfo, Exception exception); protected virtual void
OnActionExecuted(FilterExecutedContext filterContext);
protected virtual bool OnActionExecuting(FilterExecutedContext filterContext); protected virtual void RedirectToAction(object values);
protected virtual void RenderView(string viewName, string masterName, object viewData);}
Controller – Customization APIspublic class Controller : IController { … protected virtual void Execute(ControllerContext
controllerContext); protected virtual void HandleUnknownAction(string
actionName); protected virtual bool InvokeAction(string actionName); protected virtual void InvokeActionMethod(MethodInfo
methodInfo); protected virtual bool OnError(string actionName, MethodInfo methodInfo, Exception exception); protected virtual void
OnActionExecuted(FilterExecutedContext filterContext);
protected virtual bool OnActionExecuting(FilterExecutedContext filterContext);
protected virtual void RedirectToAction(object values); protected virtual void RenderView(string viewName, string masterName, object viewData);}
Controller – Test Hooks public class Controller : IController { … protected virtual void Execute(ControllerContext
controllerContext); protected virtual void HandleUnknownAction(string
actionName); protected virtual bool InvokeAction(string actionName); protected virtual void InvokeActionMethod(MethodInfo
methodInfo); protected virtual bool OnError(string actionName, MethodInfo methodInfo, Exception exception); protected virtual void
OnActionExecuted(FilterExecutedContext filterContext);
protected virtual bool OnActionExecuting(FilterExecutedContext filterContext);
protected virtual void RedirectToAction(object values); protected virtual void RenderView(string viewName, string masterName, object viewData);}
Basic ViewsScenarios, Goals and Design:
Are for rendering/output. Pre-defined and extensible rendering helpers
Can use .ASPX, .ASCX, .MASTER, etc.Can replace with other view technologies:
Template engines (NVelocity, Brail, …).Output formats (images, RSS, JSON, …).Mock out for testing.
Controller sets data on the ViewLoosely typed or strongly typed data
ViewEngineBaseView Engines render outputYou get WebForms by defaultCan implement your own
MVCContrib has ones for Brail, NvelocityNHaml is an interesting one to watch
View Engines can be used toOffer new DSLs to make HTML easier to writeGenerate totally different mime/types
ImagesRSS, JSON, XML, OFX, etc.VCards, whatever.
View Engine Base ClassViewEngineBase
public abstract class ViewEngineBase { public abstract void RenderView(ViewContext
viewContext); }
NHaml – Extreme Custom Views<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
AutoEventWireup="true" CodeBehind="List.aspx"
Inherits="MvcApplication5.Views.Products.List" Title="Products" %><asp:Content ContentPlaceHolderID="MainContentPlaceHolder"
runat="server"> <h2><%= ViewData.CategoryName %></h2> <ul> <% foreach (var product in ViewData.Products) { %> <li> <%= product.ProductName %> <div class="editlink"> (<%= Html.ActionLink("Edit", new { Action="Edit",
ID=product.ProductID })%>) </div> </li> <% } %> </ul> <%= Html.ActionLink("Add New Product", new { Action="New" }) %></asp:Content>
NHaml – Extreme Custom Views%h2= ViewData.CategoryName
%ul - foreach (var product in ViewData.Products)
%li = product.ProductName .editlink = Html.ActionLink("Edit", new { Action="Edit", ID=product.ProductID }) = Html.ActionLink("Add New Product", new { Action="New" })
Controller FactoryScenarios, Goals and Design:
Hook creation of controller instanceDependency Injection.Object Interception.
public interface IControllerFactory { IController CreateController(RequestContext context, string controllerName);}
protected void Application_Start(object s, EventArgs e) { ControllerBuilder.Current.SetControllerFactory( typeof(MyControllerFactory));}
View EngineScenarios, Goals and Design:
Mock out views for testingReplace ASPX with other technologies
public interface IViewEngine { void RenderView(ViewContext context); }
Inside controller class: this.ViewEngine = new XmlViewEngine(...);
RenderView("foo", myData);