SlideServe
Menu
Préférences
© SlideServe · v2026

ASP.NET MVC

audra-knowles avatar
20 diapositives · 420 Views · Nov 12, 2014

ASP.NET MVC. Patterns and Anti-Patterns: Lessons from the Trenches. Thanks to Our Host. Anti-Patterns: Things NOT to do. Return un-typed ViewData on a GET Pass low-level data-types on POST Pass FormCollection on POST Magic Strings in Views Logic in Views ‘Fat’ Controllers

ASP.NET MVC - slide 1
01 / 20ASP.NET MVC
1 / 17

Télécharger la présentation

ASP.NET MVC
Une image / un lien ci-dessous est fourni (tel quel) pour télécharger la présentation

Politique de téléchargement : le contenu du site vous est fourni TEL QUEL pour votre information et votre usage personnel ; il ne peut être vendu, concédé sous licence ni partagé sur d’autres sites sans l’accord de son auteur.Le contenu vous est fourni TEL QUEL, pour votre information et votre usage personnel uniquement. Téléchargez la présentation en cliquant sur ce lien. Lors du téléchargement, si vous ne parvenez pas à télécharger une présentation, l’éditeur a peut-être supprimé le fichier de son serveur.Pendant le téléchargement, si vous ne parvenez pas à obtenir une présentation, le fichier a peut-être été supprimé par l’éditeur.

F I N

Plus de contenu associé

Transcription de la présentation
  1. ASP.NET MVC Patterns and Anti-Patterns: Lessons from the Trenches

  2. Thanks to Our Host

  3. Anti-Patterns: Things NOT to do • Return un-typed ViewData on a GET • Pass low-level data-types on POST • Pass FormCollection on POST • Magic Strings in Views • Logic in Views • ‘Fat’ Controllers • Domain Models passed to and from Views • Exposed Primary Keys in URLs • (unverifiable) Convention over Configuration

  4. Return UntypedViewData on a GET public ActionResultRegister() { ViewData["PasswordLength"] = MembershipService.MinPasswordLength; return View(); } <p> Passwords are required to be a minimum of <%=Html.Encode(ViewData["PasswordLength"])%> characters in length. </p>

  5. Pass Low-Level data-types on POST public ActionResultLogOn(string username, string password) { if (!ValidateLogOn(username, password)) { return View(); } }

  6. Pass FormCollection on POST public ActionResultLogOn(FormCollection collection) { if (!ValidateLogOn(collection["userName"], collection["password"])) { return View(); } }

  7. Magic Strings in Views <p> Please enter your username and password. <%= Html.ActionLink("Register", "Register")%> if you don't have an account. </p>

  8. Logic in Views <%if (((DateTime)ViewData["OrderDate"]) >new DateTime(2009, 9, 1)) { foreach(Productproductin (IList<Product>)ViewData["Products"]) {%> <li><%=product.ProductName%></li> <%} }%>

  9. ‘Fat’ Controllers [AcceptVerbs(HttpVerbs.Post)] public ActionResultEdit(intid, FormCollectioncollection) { try { var customer = customerRepository.Get(id); customer.Firstname= collection[("Firstname"]; using(vartx = context.BeginTransaction()) { customerRepository.Save(customer); tx.Commit(); } return RedirectToAction("Index"); } catch { return View(); } }

  10. Domain Models passed betw Views public ActionResultList(intid) { var customer = customerRepository.Get(id); return View("Index", customer); } [AcceptVerbs(HttpVerbs.Post)] public ActionResultEdit(Customercustomer) { customerRepository.Save(customer); return View("Index", customer); }

  11. Exposed Primary Keys in URLs http://host/{Controller}/{Action}/{id} http://localhost/Customer/Edit/34 http://localhost/Product/View/34 http://localhost/Customer/Edit/Bohlen http://localhost/Product/View/WSTV123

  12. (unverifiable) Convention over Configuration public ActionResultRegister() { ViewData["PasswordLength"] = MembershipService.MinPasswordLength; return View(); }

  13. Patterns: Things to DO • Strongly-Typed Model In and Model Out • ViewModels, UpdateModels • Encapsulate View ‘decisions’ in ViewModels • Controller controls the View, NOT the app

  14. Strongly-Typed Model In and Out public ActionResultList(intnumber) { var customer = customerRepository.GetByNumber(number); varcustomerViewModel = newCustomerViewModel(customer); return View(“List", customerViewModel); } [AcceptVerbs(HttpVerbs.Post)] public ActionResultEdit(CustomerUpdateModelupdCustomer) { var customer=customerRepository .GetByNumber(updCustomer.Number); updCustomer.ApplyChangesTo(customer); customerRepository.Save(customer); varcustomerViewModel = newCustomerViewModel(customer); return View("Index", customerViewModel); }

  15. Encapsulate ‘decisions’ in ViewModels <%if (CustomerViewModel.HasRecentOrders) { foreach(Productproductin (CustomerViewModel.Products) {%> <li><%=product.ProductName%></li> <%} }%>

  16. Controller controls the View, not the app [AcceptVerbs(HttpVerbs.Post)] public ActionResultEdit(CustomerUpdateModelupdCustomer) { varcustomerViewModel=customerUpdateService(updCustomer) return View("Index", customerViewModel); }

  17. Suggestions to Extend MVC • MVCContrib (mvccontrib.org) • xVal (xVal.CodePlex.com) • 1000s of JQueryPlugins

  18. Discussion • Other Experiences • Other Challenges • Other Recommendations

  19. Session Wrap-Up • Thoughts and Impressions • Positives and Deltas • Discussion of Topics for Upcoming Meetings