devcoach.com ASP.NET MVC & HTML 5 Daniel Fisher | devcoach
devcoach.com HTML 5 – A new Era? • … or back to the 90's
devcoach.com What is new? • HTML 5 – A few tags – … Less Markup • CSS 3 – Rounded corners – Drop shadow? – Media Queries – … Less Definition • EcmaScript 5 – Web Sockets – Server Sent Events – … Less Code
devcoach.com A new ASP.NET Style • It's not Web Forms!
devcoach.com What is there • Maintain Clean Separation of Concerns • Extensible and Pluggable • Enable clean URLs and HTML • Build on to of a mature platform
devcoach.com Whats the difference to Web Forms • File System Based • Event based Server Forms – Makes adoption easy for e.g. VB forms devs. – Process logic is coupled with page life-cycle. • Difficult to test using automated tests. • Server Controls – Easy because they render the HTML for you. – Often not so nice because they render it the way they want.
devcoach.com
devcoach.com What Do They Have In Common? • Visual Studio web designer • Master pages • Membership/Roles/Profile providers • Globalization • Caching
devcoach.com The MVC Pattern • The request hits the controller • Loads the model • Returns the view to return to the client Controller Model View
devcoach.com IIS sends Response ViewResult.Render ViewResult locates corresponding View ActionResult. ExecuteResult ActionResult builds ViewData / Model Controller.{Action}Controller.ExecuteIControllerFactory IHttpHandler. ProcessRequest MvcRouteHandler (IHttpHandler) IRouteHandler. GetHttpHandler URLRoutingModule IIS takes Request
devcoach.com First of all think of the URLs • It's in the nature of the pattern that it makes you think before you code!
devcoach.com Nice URLs • REST-like • Fits with the nature of the web – MVC exposes the stateless nature of HTTP • Friendlier to humans • Friendlier to web crawlers – Search engine optimization (SEO)
devcoach.com Defining Routes routes.Ignore("*.svc"); routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters new { controller = "Home", action = "Index", id = "" });
devcoach.com Default Parameters routes.Ignore("*.svc"); routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters new { controller = "Home", action = "Index", id = UrlParameter.Optional });
devcoach.com Controllers • Base Controller Class – Basic Functionality most folks will use • IController Interface – Ultimate Control for the Control Freak • IControllerFactory – For plugging in your own stuff (IOC, etc)
devcoach.com Controller – Regular APIs 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); }
devcoach.com Controllers & Actions public ActionResult Index() { return View(); }
devcoach.com Action Default Values public ActionResult View( [DefaultValue(1)] int page) { return View(); }
devcoach.com Results • ActionResult • JsonResult • ...
devcoach.com Action Attributes • HttpPost, HttpGet, HttpDelete, RequiresHttps • Authorize • ...
devcoach.com Action Filters • Allow code to be wrapped around controller actions and view results • Similar to HttpModules • Provide a mechanism for removing cross cutting code (logging, authorization, etc.) from controller classes
devcoach.com Action Filters public class MyFilter : ActionFilterAttribute { public override void OnActionExecuting( ActionExecutingContext filterContext) { // Your code here… } }
devcoach.com Passing Data public ActionResult Index() { ViewData["Message"] = "Welcome to ASP.NET MVC!"; return View(); }
devcoach.com Passing Dynamic Data public ActionResult Index() { ViewModel.Message = "Welcome to ASP.NET MVC!"; return View(); }
devcoach.com Passing Typed Data public ActionResult Index() { var p = new Person(); return View(p); }
devcoach.com Model Binder public ActionResult Save(Person p) { // No need to cope with Form/QueryString return View(p); }
devcoach.com Asyncronous Actions public class PortalController : AsyncController { public void NewsAsync(string city) { AsyncManager.OutstandingOperations.Increment(); NewsService newsService = new NewsService(); newsService.GetHeadlinesCompleted += (sender, e) => { AsyncManager.Parameters["headlines"] = e.Value; AsyncManager.OutstandingOperations.Decrement(); }; newsService.GetHeadlinesAsync(city); } public ActionResult NewsCompleted(string[] headlines) { return View( "News", new ViewStringModel { NewsHeadlines = headlines }); }
devcoach.com Value Provider namespace System.Web.Mvc { public interface IValueProvider { bool ContainsPrefix(string prefix); ValueProviderResult GetValue(string key); } }
devcoach.com Views • 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 View • Loosely typed or strongly typed data
devcoach.com ASPX Views Untyped <%@ Page Inherits="ViewPage<dynamic>" %> Typed <%@ Page Inherits="ViewPage<Product>" %>
devcoach.com Razor Views Untyped Typed @model Product
devcoach.com View Engine public abstract class ViewEngineBase { public abstract void RenderView( ViewContext viewContext); }
devcoach.com View Engine • View Engines render output • You get WebForms by default • Can implement your own – MVCContrib has ones for Brail, Nvelocity – NHaml is an interesting one to watch • View Engines can be used to – Offer new DSLs to make HTML easier to write – Generate totally different mime/types • Images • RSS, JSON, XML, OFX, etc. • VCards, whatever.
devcoach.com ASPX Output • Response Write – <%= "<b>Text with markup</b>" %> • Html Encoding – <%: "<b>Text with encoded markup</b>"%>
devcoach.com Razor Output • Response Write – @(new HtmlString("<b>Text with markup</b>")) • Html Encoding – @"<b>Text with encoded markup</b>"
devcoach.com Html Helper • Html.Form() • Html.ActionLink() • Url.Content()
devcoach.com Strongly Typed Helpers • Html.TextBoxFor(m=>m.Name) • Html.TextAreaFor() • Html.ValidationMessageFor()
devcoach.com Templated Helpers • Display Helper Methods – Html.Display() – Html.DisplayFor() – Html.DisplayForModel() • Edit Helper Methods – Html.Editor() – Html.EditorFor() – Html.EditorForModel()
devcoach.com Assign Template • By Type: DateTime.ascx • By Name: Html.DisplayForModel(“MyTemplate.ascx”); • By UIHint [UIHint("MyPropertyTemplate")] public string Title { get; set; } [HiddenInput]
devcoach.com Partial Views Html.RenderPartial() • Renders UI
devcoach.com Rendered Actions Html.RenderAction() • Invokes action that renders UI – Menus – Banner Ads – Shopping Carts Any UI that appears in multiple pages and requires business logic
devcoach.com Areas AreaRegistration.RegisterAllAreas(); • Enables you to maintain a clear separation of functionality in a single project
devcoach.com Area Registration public class BlogAreaRegistration : AreaRegistration { public override string AreaName { get { return "blog"; } } public override void RegisterArea( AreaRegistrationContext context) { //Register Routes } }
devcoach.com Validation • Define rules in Model • Server Side Validation • Client Side Validation
devcoach.com Validation Providers • Data Annotation (Default) • Enterprise Library • XML • Anything you want…
devcoach.com Data Annotations • [Required] • [Range] • [RegularExpression] • [StringLength] • [CustomValidator]
devcoach.com Client Side Validation jQuery <script src="@Url.Content("~/Scripts/jquery-1.4.1.min.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> <% Html.EnableClientValidation(); %>
devcoach.com everything is extensible • Custom routing handlers (IRouteHandler) • Custom handlers (IHttpHandler) • Custom controllers (IController, IControllerFactory) • Custom views (IViewEngine ) • Custom view locator (IViewLocator) • Custom views (IViewDataContainer)

2011 NetUG HH: ASP.NET MVC & HTML 5