Indy Tech Fest 2008 - ASP.NET MVC

4,335 views

Published on

The slides from my Indy Tech Fest presentation on ASP.NET MVC.

Published in: Technology, Business
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
4,335
On SlideShare
0
From Embeds
0
Number of Embeds
292
Actions
Shares
0
Downloads
0
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

Indy Tech Fest 2008 - ASP.NET MVC

  1. 1. Web Development with ASP.NET MVC Aaron Lerch Development Team Lead Interactive Intelligence
  2. 2. • The MVC Pattern • MVC in ASP.NET • Testability • AJAX
  3. 3. The MVC Pattern VIEW CONTROLLER MODEL
  4. 4. The MVC Pattern VIEW CONTROLLER MODEL
  5. 5. What is the Model? • Domain Objects • Data Transfer Objects • “Business Logic”
  6. 6. What is the Model? • Domain Objects • Data Transfer Objects • “Business Logic” public class Person { } public class PersonDTO { } Repository<Person>.Load(personId) MessageService.Send(message)
  7. 7. What is the View? • Format the Model • Render a display • Enable selecting of Actions
  8. 8. What is the Controller? • Expose and Respond to Actions • Manipulate Model • Choose a View
  9. 9. MVC in ASP.NET
  10. 10. Acts like a 12 year old Is a 12 year old 20-something
  11. 11. Acts like a 12 year old Is a 12 year old 20-something
  12. 12. HTTP Client Server
  13. 13. HTTP Client Server GET /foo.html HTTP 1.1
  14. 14. HTTP Client Server GET /foo.html HTTP 1.1 200 OK Content-Type: application/xhtml+xml <html> <body>Foo</body> </html>
  15. 15. HTTP Client Server
  16. 16. HTTP Client Server GET /foo.html HTTP 1.1
  17. 17. HTTP Client Server GET /foo.html HTTP 1.1 302 Found Location: http://www.foobar.com/bar.html
  18. 18. HTTP Client Server GET /foo.html HTTP 1.1 302 Found Location: http://www.foobar.com/bar.html
  19. 19. HTTP Client Server GET /foo.html HTTP 1.1 302 Found Location: http://www.foobar.com/bar.html GET /bar.html HTTP 1.1
  20. 20. HTTP Client Server GET /foo.html HTTP 1.1 302 Found Location: http://www.foobar.com/bar.html GET /bar.html HTTP 1.1 200 OK <html> <body>Bar</body> </html>
  21. 21. ASP.NET Client Server
  22. 22. ASP.NET Client Server GET /foo.aspx HTTP 1.1
  23. 23. ASP.NET Client Server GET /foo.aspx HTTP 1.1 Init Load Render
  24. 24. ASP.NET Client Server GET /foo.aspx HTTP 1.1 Init Load 200 OK Render <form>[VIEWSTATE]</form>
  25. 25. ASP.NET Client Server GET /foo.aspx HTTP 1.1 Init Load 200 OK Render <form>[VIEWSTATE]</form> POST /foo.aspx HTTP 1.1
  26. 26. ASP.NET Client Server GET /foo.aspx HTTP 1.1 Init Load 200 OK Render <form>[VIEWSTATE]</form> POST /foo.aspx HTTP 1.1 Init Load LinkClicked Redirect Render
  27. 27. ASP.NET Client Server GET /foo.aspx HTTP 1.1 Init Load 200 OK Render <form>[VIEWSTATE]</form> POST /foo.aspx HTTP 1.1 Init Load LinkClicked Redirect 302 Found Render Location: http://www.foobar.com/bar.aspx
  28. 28. ASP.NET Client Server GET /foo.aspx HTTP 1.1 Init Load 200 OK Render <form>[VIEWSTATE]</form> POST /foo.aspx HTTP 1.1 Init Load LinkClicked Redirect 302 Found Render Location: http://www.foobar.com/bar.aspx GET /bar.aspx HTTP 1.1
  29. 29. ASP.NET MVC Client Server
  30. 30. ASP.NET MVC Client Server GET /foo/bar HTTP 1.1
  31. 31. ASP.NET MVC Client Server GET /foo/bar HTTP 1.1 FooController.Bar() View(“Bar”)
  32. 32. ASP.NET MVC Client Server GET /foo/bar HTTP 1.1 FooController.Bar() View(“Bar”) 200 OK
  33. 33. ASP.NET MVC Client Server GET /foo/bar HTTP 1.1 FooController.Bar() View(“Bar”) 200 OK
  34. 34. ASP.NET MVC Client Server GET /foo/bar HTTP 1.1 FooController.Bar() View(“Bar”) 200 OK GET /foos/ball HTTP 1.1
  35. 35. ASP.NET MVC Client Server GET /foo/bar HTTP 1.1 FooController.Bar() View(“Bar”) 200 OK GET /foos/ball HTTP 1.1 FoosController.Ball() View(“Ball”)
  36. 36. ASP.NET MVC Client Server GET /foo/bar HTTP 1.1 FooController.Bar() View(“Bar”) 200 OK GET /foos/ball HTTP 1.1 FoosController.Ball() View(“Ball”) 200 OK
  37. 37. Request Flow Request URL Http Controller Response Routing Handler Route View Route View Handler Factory
  38. 38. CODE!
  39. 39. View Engines <table> <% foreach (ScheduleListing listing in schedule) { %> <tr> <td> <%=listing.StartTime %> - <%=listing.EndTime %><br /> <%= listing.Purpose %> </td> <% foreach (TrackListing track in tracks) { %> <td> <% SessionListing session = listing[track]; if (session != null) { %> <%= session.Title%><br /> (<%= session.Speaker.DisplayName%>) <% } else { %> <i>None</i> <% } %> </td> <% } %> </tr> <% } %> </table>
  40. 40. NHaml #foo - foreach (var product in ViewData) - if (product.Category.CategoryName != null) %h2=product.Category.CategoryName - break %ul.productlist - foreach (var product in ViewData) %li = Html.Image(quot;/Content/Images/quot; + product.ProductID + quot;.jpgquot;, product.ProductName) .productdetail =Html.ActionLink(product.ProductName, quot;Detailquot;, new { ID=product.ProductID }) %br Price: =String.Format(quot;{0:C2}quot;, product.UnitPrice) %span.editlink ( =Html.ActionLink(quot;Editquot;, quot;Editquot;, new { ID=product.ProductID }) )
  41. 41. NHaml #foo - foreach (var product in ViewData) - if (product.Category.CategoryName != null) %h2=product.Category.CategoryName - break %ul.productlist - foreach (var product in ViewData) %li = Html.Image(quot;/Content/Images/quot; + product.ProductID + quot;.jpgquot;, product.ProductName) .productdetail =Html.ActionLink(product.ProductName, quot;Detailquot;, new { ID=product.ProductID }) %br Price: “.productdetail” =String.Format(quot;{0:C2}quot;, product.UnitPrice) %span.editlink ( =Html.ActionLink(quot;Editquot;, quot;Editquot;, new { ID=product.ProductID }) ) becomes <div id=”productdetail”>
  42. 42. Spark <ul class=quot;productlistquot;> <var styles='new[] {quot;oddquot;, quot;evenquot;}'/> <li each=quot;var product in ViewData.Modelquot; class=quot;${styles[productIndex%2]}quot;> <ProductImage style='quot;float:left;quot;'/> <p> <a href=quot;/Products/Detail/${product.ProductID}quot;>${product.ProductName}</a> <br /> Price: ${String.Format(quot;{0:C2}quot;, product.UnitPrice)} <span class=quot;editlinkquot;> (${Html.ActionLink[[ProductsController]](c=>c.Edit(product.ProductID), quot;Editquot;)}) </span> </p> <div style=quot;clear:both;quot;></div> </li> </ul>
  43. 43. Spark <ul class=quot;productlistquot;> <var styles='new[] {quot;oddquot;, quot;evenquot;}'/> <li each=quot;var product in ViewData.Modelquot; class=quot;${styles[productIndex%2]}quot;> <ProductImage style='quot;float:left;quot;'/> <p> <a href=quot;/Products/Detail/${product.ProductID}quot;>${product.ProductName}</a> <br /> Price: ${String.Format(quot;{0:C2}quot;, product.UnitPrice)} <span class=quot;editlinkquot;> (${Html.ActionLink[[ProductsController]](c=>c.Edit(product.ProductID), quot;Editquot;)}) </span> </p> <div style=quot;clear:both;quot;></div> </li> </ul> <li each=quot;var product in ViewData.Modelquot; class=quot;${styles[productIndex%2]}quot;>
  44. 44. Testability
  45. 45. What is Testability?
  46. 46. What is Testability? The ability to test.
  47. 47. Testability Involves... • A design approach • Explicitly defining dependencies • Isolating functionality
  48. 48. Testable? private void linkAddClick(object sender, EventArgs e) { string SQLInsert = quot;INSERT INTO [Tabell] ([user], [password]) VALUES (@user, @password)quot;; using (SqlConnection connection = new SqlConnection(connectionString)) { SqlCommand command = new SqlCommand(SQLInsert, connection); command.Parameters.AddWithValue(quot;@userquot;, txtUser.Text.Trim()); command.Parameters.AddWithValue(quot;@passwordquot;, txtPassword.Text.Trim()); connection.Open(); command.CommandType = CommandType.Text; command.ExecuteNonQuery(); connection.Close(); } }
  49. 49. Testable? private void linkAddClick(object sender, EventArgs e) { string SQLInsert = quot;INSERT INTO [Tabell] ([user], [password]) VALUES (@user, @password)quot;; using (SqlConnection connection = new SqlConnection(connectionString)) { SqlCommand command = new SqlCommand(SQLInsert, connection); command.Parameters.AddWithValue(quot;@userquot;, txtUser.Text.Trim()); command.Parameters.AddWithValue(quot;@passwordquot;, txtPassword.Text.Trim()); connection.Open(); command.CommandType = CommandType.Text; command.ExecuteNonQuery(); connection.Close(); } }
  50. 50. Testable? public class UserController : Controller { private IUserRepository _repository; public UserController(IUserRepository repository) { _repository = repository; } public ActionResult Show(string id) { User user = _repository.Load(id); return View(quot;Userquot;, user); } }
  51. 51. Testable? public class UserController : Controller { private IUserRepository _repository; public UserController(IUserRepository repository) { _repository = repository; } public ActionResult Show(string id) { User user = _repository.Load(id); return View(quot;Userquot;, user); } }
  52. 52. Let’s Test It public class UserRepositoryStub : IUserRepository { public User Load(string id) { return new User(id, quot;Aaronquot;, quot;Lerchquot;); } } [Test] public void show_action_should_call_user_view() { IUserRepository repository = new UserRepositoryStub(); UserController controller = new UserController(repository); var result = controller.Show(quot;aaronlerchquot;); Assert.That(result, Is.Not.Null); Assert.That(result.ViewName, Is.EqualTo(quot;Userquot;); }
  53. 53. AJAX “An AJAX-ified website is a requirement for being ‘Web 2.0’ certified, making bajillions of dollars, becoming hugely famous, regrowing your lost hair, and retiring to Tahiti.”
  54. 54. CODE!
  55. 55. Questions? Comments? Concerns?
  56. 56. Give MVC a Try! • Download ASP.NET MVC at http://www.codeplex.com/aspnet • TONS of resources linked from http://www.asp.net/mvc/ • MVCContrib.com • CodeCampServer.com Contact Me • aaronlerch@gmail.com http://www.aaronlerch.com/blog/

×