200 likes | 382 Views
Samuli Haverinen, 29.9.2010. Developing ASP.NET MVC2. Agenda. Introduction to Web development The MVC pattern Comparison to Web Forms ASP.NET MVC2 basic principles Important rules Controllers Views AJAX Input validation URL Routing Localization Additional reading.
E N D
Samuli Haverinen, 29.9.2010 Developing ASP.NET MVC2
Agenda • Introduction to Web development • The MVC pattern • Comparison to Web Forms • ASP.NET MVC2 basic principles • Important rules • Controllers • Views • AJAX • Input validation • URL Routing • Localization • Additional reading
Introduction to Web development • User Request HTTP server Server application HTTP server Browser • By definition web is stateless • States can be implemented in client side as cookies or in the server side
The MVC pattern 1/2 • Model-View-Controller • Separates application logic from presentation logic and user interface • Permits independent development, testing and maintenance of each ”component” • MVC Model2 improves traditional MVC • Works better with stateless nature of the web • Is the model used by ASP.NET MVC • From here on MVC refers to the Model2
The MVC pattern 2/2 • Model contains the data you want to present • Views present the data of the model • Controller controls the application flow
Comparison to Web Forms • ASP.NET MVC2 does differ from Web Forms • Doesn’t use event-driven design • No code-behind classes, postbacks or viewstates • Do not try to use Web Forms controls in MVC! • Provides clear separation of concerns • You specify every bit of HTML rendered • Designed to follow the stateless nature of web • Makes TDD and unit testing of presentation logic easier
Important rules • There are a few things to keep in mind... • Never ever put business logic into views or controllers! • Aim for slim controllers and fat models • Max. 10 lines of code in controller methods • Include only presentation and application flow logic in controller, e.g. what page to display next. • Aim for loose coupling and high cohesion for easy maintenance and improved testability
Models • Models contain the data that we have in our domain and that we want to present to the users publicclassCar { publicstringRegNum { get; set; } publicstring Make { get; set; } publicintMaxNumberOfPassengers { get; set; } publicList<Passenger> Passengers { get; set; } } publicclassPassenger { publicstring Name { get; set; } publicint Age { get; set; } }
Controllers 1/2 • Controllers contain methods called ”Actions” that respond to the actions from user and handle web server requests. • Resposibilities of a controller • Receive and validate user input • Decide which actions to take • Call relevant service layer methods • Decide which view to show next • Return the model to the view
Controllers 2/2 • Controllers contain one or two actions for each view or page • Separate methods for GET and POST • Methods can take and return strongly-typed models! [HttpGet] publicActionResult AddCar() { return View(); } [HttpPost] publicActionResult AddCar(Car car) { this._carService.Add(car); return RedirectToAction("Cars"); }
Views 1/3 • View renders the model and forwards data from user to the controller <%@PageTitle=""Language="C#"MasterPageFile="~/Views/Shared/Site.Master"Inherits="System.Web.Mvc.ViewPage<MvcDemo.Core.Models.Car>"%> <asp:ContentID="Content1"ContentPlaceHolderID="TitleContent"runat="server"> Add a Car </asp:Content> <asp:ContentID="Content2"ContentPlaceHolderID="MainContent"runat="server"> <h2>Add a car</h2> <p>Please fill in the form data to add a car.</p> <%using (Html.BeginForm()) { %> <%=Html.LabelFor(e => e.RegNum) %>: <%= Html.TextBoxFor(e => e.RegNum) %><br/> <%=Html.LabelFor(e => e.Make) %>: <%= Html.TextBoxFor(e => e.Make) %><br/> <%=Html.LabelFor(e => e.MaxNumberOfPassengers) %>: <%= Html.TextBoxFor(e => e.MaxNumberOfPassengers, new {style="width: 30px;"}) %><br/> <inputtype="submit"name="submit"id="submit"value="Add"/> <% } %> </asp:Content>
Views 2/3 • Most of the functionality can be accessed through the static HTML helper class. <%=Html.LabelFor(e => e.RegNum) %> • The helper class can be easily extended by using .NET extension methods • If you find yourself putting if-then-else clauses in the view, please extend the HTML helper class! Really! • If you find your self copy-pasting code from a view to another, extend the HTML helper class!
Views 3/3 • Otherwise you’ll end up with something like this...
AJAX • MVC2 has good support for AJAX and JQuery • JSON is usually used for exchanging data • PartialViews can be used to only refresh a specific part of a page $(function () { $('#btnAddRandomCar').click(function () { $.getJSON("/Home/AddRandomCar", null, function (data) { if(!data) alert("Error while adding random car!"); else refreshCarsTable(); }); }); }); function refreshCarsTable() { $.ajax({ url: "/Home/GetCarTable", success: function (result) { $('#cartable').html(result); } }); }
Input Validation 1/2 • ASP.NET MVC2 has built-in support for user input validation using Data Annotations • Supports both client- and server-side validation • Validation rules need to be written only once • Rules are expressed as attributes for properties [DisplayName("Register Number")] [Required] [StringLength(7)] publicstringRegNum { get; set; } [DisplayName("Make")] publicstring Make { get; set; }
Input Validation 2/2 • Server-side validation is done by checking ModelState.IsValid property [HttpPost] publicActionResult AddCar(Car car) { if(!ModelState.IsValid) returnView(); // else add the car... } • Client-side validation is done by adding some references in Site.Master... <scriptsrc="../../Scripts/jquery.validate.js" type="text/javascript"></script> <scriptsrc="../../Scripts/MicrosoftAjax.js"type="text/javascript"></script> <scriptsrc="../../Scripts/MicrosoftMvcAjax.js"type="text/javascript"></script> <scriptsrc="../../Scripts/MicrosoftMvcValidation.js"type="text/javascript"></script> • ...and then... <% Html.EnableClientValidation(); %> <%=Html.ValidationMessageFor(e => e.TheFieldIWantToValidate) %>
URL Routing • ASP.NET MVC doesn’t follow the traditional method to map an URL directly to a view • Instead, an URL is mapped to an action in a controller that decides which view to show • E.g. www.myhost.com/Products/List is mapped to List-action in Products-controller • It is possible to define custom routing rules, e.g. Route www.myhost.com/Products/512 to an action that takes product id as a parameter
Localization • .NET Framework provides an easy way to make localizations for multiple languages • All the localizations are stored in resource files • E.g. we can have Localizations.resx, Localizations.fi-FI.resx files etc. • The default localization is stored in the file without language specific suffix <divid="title"> <h1><%=Localizations.Localization.AppName%></h1> </div> • Choosing the language that is used can be done e.g. in global.asax publicoverridevoid Init() { base.Init(); System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("fi-FI"); System.Threading.Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fi-FI"); }
Additional reading • Remember, Google is your friend • Official site:http://www.asp.net/mvc • MSDN:http://msdn.microsoft.com/en-us/library/dd394709.aspx • Scott Gu’s blog:http://weblogs.asp.net/scottgu/ • JQuery:http://jquery.com/