ASP.
NET MVC Best Practices
Simone Chiaretta
Solution Developer, Avanade
http://codeclimber.net.nz
Twitter: @simonech
21 Ottobre 2009
Thanks to the Sponsors
Who the hell am I?
► Simone Chiaretta
► Work for Avanade Italy
► Microsoft MVP ASP.NET
► Blogger – http://codeclimber.net.nz
► Founder of UGIALT.NET
► OpenSource developer
► Climber
► All Around Nice Guy
Agenda
ASP.NET MVC Best Practices
Would you like someone to tell you the
final a movie before you watch it?
4
What ASP.NET MVC is?
► It’s an advanced session... You should
already know
Just in case
The
Controller
asks the
The request Model for
hits the data
controller 2 Model
1 3
Controlle The Model gives
r the data back to
the Controller
Bro The controller
wse formats the data and
4
r passes them to the
View View
5
The view renders
the HTML that needs
to be sent to the
client
6
Controller
Delete “AccountController”
Best Practice n° 1
1 – Delete “AccountController”
► You will probably never use these account
management pages
► Keeping demo code in a production
application is EVIL
► Delete it
Isolate controllers from the external
World
Best Practice n° 2
2 - Isolate controllers from the
outside World
► HttpContext
► Data Access classes
► Configuration management
► Logging
► Clock
► Etc…
2 - Isolate controllers from the
outside World
► Not testable application
► Not flexible application
Use a IoC Container
Best Practice n° 3
What’s Dependency Injection
14
What’s Dependency Injection
BAD
What’s Dependency Injection
BETTER
What’s Dependency Injection
BUT
Inversion of Control
With IoC
IoC inside ASP.NET MVC
► Extend ControllerFactory
► Many ControllerFactory ready available
– StructureMap
– Spring
– Unity
– Windsor
– Ninject
– ...
IoC inside ASP.NET MVC using Ninject
v2
► Global.asax inherits from
NinjectHttpApplication
► Helper to configure all controllers:
– RegisterAllControllersIn(“assemblyName”);
Don’t use “Magic strings”
Best Practice n° 4
Say NO to Magic Strings
► Never use ViewData[“key”]
► Always create a ViewModel for each View
► View must inherit from
– System.Web.Mvc.ViewPage<ListViewModel>
Build your own “personal” conventions
Best Practice n° 5
Build your own “personal” conventions
► ASP.NET MVC is the base on which to build
your own reference architecture
► Controllers (and views) inherint from your
own base class
Pay attention to Verbs
Best Practice n° 6
Pay attention to Verbs
What happens when you refresh (or go back)
after you submit a form?
26
PRG Pattern
► View sends data in POST
► Controller validates
– Renders the View with errors (POST)
– Redirect in GET
► View renders the results in GET
Pay attention to Verbs
► Show data in GET
► Modify data in POST
Model
DomainModel != ViewModel
Best Practice n° 7
DomainModel != ViewModel
► DomainModel
– Data + Behaviours
– hierarchical, complex types
► ViewModel
– Only Data
– Flat, only strings
DomainModel != ViewModel
► How to avoid getting bored writing tedious
mapping code?
AutoMapper
Mapper.Map<Post, ShowPostModel>(post)
Use ActionFilter for “shared” data
Best Practice n° 8
Components in ASP.NET MVC
► RenderPartial
– The Controller must “create” all data needed by
all the partials
► RenderAction (futures)
– Smells (view calls a controller)
– More difficult to test
► Custom HtmlHelpers
– Ok for some HTML, but must not have logic
Action Filtes
► Defined as Attributi
► Allow you to execute “code”
– During the Autenthorization phase
– If an exception occurs
– Before an Action
– After an Action
– Before the rendering of a view
– After the rendering of a view
► “Core” filters
– Authorize
– OutputCache
Action Filter + Render Partial
► Controller:
– Has code for his “main concern” and “create”
the main data
► View:
– Renders the main output
– Calls the various PartialViews
► Action Filters:
– Load data for the partial views
► Partial views
– Render data loaded via Action Filters
View
Do NOT use code-behind
Best Practice n° 9
Do NOT use code-behind
NEVER
Write HTML when you can
Best Practice n° 10
Write HTML when you can
► You MUST learn HTML
► Do never use HtmlHelpers that ONLY
abstract HTML awat
<%= Html.Submit(“Salva”) %>
vs
<input type=“submit” value=“Salva” />
If there is an if, write an HtmlHelper
Best Practice n° 11
If there is an if, write an
HtmlHelper
► View must not have logic
► Allowed: if - foreach
► When possible, “hides” them in HtmlHelpers
Choose your View Engine carefully
Best Practice n° 12
Choose your View Engine carefully
► The default is WebFormViewEngine
► Not the best available
► Choose the one that most suits you
Choose your View Engine carefully
► Spark View Engine
– The flow is managed by HTML
– It’s a templating engine
► Other Features
– Renders PDF
– Evaluates templates also with Javascript
Beginning ASP.NET MVC
► Simone Chiaretta &
Keyvan Nayyeri
► TOC:
– MVC
– Testing
– And more...
http://bit.ly/BeginningASPNETMVC
Contacts – Simone Chiaretta
► MSN: [email protected]
► Blog:
– English: http://codeclimber.net.nz/
– Italian: http://blogs.ugidotnet.org/piyo/
► Twitter: @simonech
48
Credits
► These talk has been inspired by Sebastien
Lambla (founder of Caffeine IT) and his
ASP.NET MVC Best Practices
► Watch his talk (which is way better than
mine):
http://serialseb.blogspot.com/2009/05/my-m
vc-best-practices-talk.html
► Read his blog:
http://serialseb.blogspot.com/
49
Q&A
50