Best Practices For ASP - Net MVC - ASP
Best Practices For ASP - Net MVC - ASP
NET and Web Tools Developer Content Team - Site Home - MSDN Blogs
http://blogs.msdn.com/b/aspnetue/archive/2010/09/17/second_2d00_post.aspx?Redirected=true 1/19
Microsoft
Translator
Translate this page
Spanish
Best Practices for ASP.NET MVC
28 ASPNETUE 17 Sep 2010 4:14 PM
[This post is based on a document authored by Ben Grover (a senior developer at Microsoft). It is our intention to
integrate this information into the MVC 3 documentation on MSDN. We hope to hear from you and welcome any
suggestions you might have.]
This document presents a set of coding guidelines aimed at helping the ASP.NET MVC developer create solid
applications. Of course, it's up to you as the developer to decide which of these guidelines are appropriate for
your application.
Model Recommendations
The model is where the domain-specific objects are defined. These definitions should include business logic (how
objects behave and relate), validation logic (what is a valid value for a given object), data logic (how data objects
are persisted) and session logic (tracking user state for the application).
DO separate the model its own project with a distinct assembly.
For applications with a large complex model, it's a good idea to create a separate assembly for the model to
avoid accidently mixing concerns. You can then reference the model assembly in your ASP.NET MVC project.
DO put all business logic in the model.
If you put all business logic in the model, you shield the view and controller from making business decisions
concerning data. You also reap the following benefits:
Less duplicated business logic.
The view is easier to read when there is no business logic present.
Testing business rules is isolated to the model.
For example, if you have a business requirement to display a user's name with the last name first, you could put
the logic in the view as follows:
<% if (String.Compare((string)TempData["displayLastNameFirst"], "on") == 0)
{ %>
Welcome, <%= Model.lastName%>, <%= Model.firstName%>
<% }
else
{ %>
Welcome, <%= Model.firstName%> <%= Model.lastName%>
4/22/2014 Best Practices for ASP.NET MVC - ASP.NET and Web Tools Developer Content Team - Site Home - MSDN Blogs
http://blogs.msdn.com/b/aspnetue/archive/2010/09/17/second_2d00_post.aspx?Redirected=true 2/19
<% } %>
However, you would have to duplicate this logic in every place this business requirement was needed. Instead, you
could put the business logic the the "display last name first" rule in the model by adding a property to the model
that encapsulates the business logic as follows:
public string combinedName
{
get
{
return (displayLastNameFirst ? lastName + " " + firstName : firstName + " " + lastName);
}
private set
{
;
}
}
This would greatly simplify the view as shown:
<% Welcome, <%= Model.combinedName %> %>
DO put all validation logic in the model.
All input validation should occur in the model layer. This includes client side validation, which is essential to
performance. However, client side validation can be circumvented (with, for example, tools like Fiddler).
You can use ModelState to add validation checking. The following example shows how to add validation checks to
ModelState explicitly:
if (String.IsNullOrEmpty(userName))
{
ModelState.AddModelError("username", Resources.SignUp.UserNameError);
}
However, given the advances in .NET Framework, the System.ComponentModel.DataAnnotations should be the
preferred method for validation. These annotations are added as attributes to the properties of a model class, as
the following example shows:
public class User
{
[Required(ErrorMessageResourceName = "nameRequired", ErrorMessageResourceType = typeof(Resources.User))]
public String userName { get; set; }
...
}
DO define interfaces for data access
.
It is preferred that interfaces be used to expose methods on a provider for data access. This reinforces the
loosely coupled component design of ASP.NET MVC.
4/22/2014 Best Practices for ASP.NET MVC - ASP.NET and Web Tools Developer Content Team - Site Home - MSDN Blogs
http://blogs.msdn.com/b/aspnetue/archive/2010/09/17/second_2d00_post.aspx?Redirected=true 3/19
Consider using the Entity Framework or LINQ to SQL as the means of creating wrappers around calls to a
database. Both Entity Framework and LINQ to SQL allow the use of stored procedures as well.
DO put all session logic in the model.
It is beyond the scope of this document to explore in depth the various mechanisms for storing session state in
the model. As a starting point, here are a few of possibilities of session state storage:
Technique Strengths Weaknesses
In Process No additional setup
required.
Does not work if the web
site needs to scale.
Session State
Service
Lightweight sertvice
runs on each machine
in a web farm.
Faster than database
session storage.
Session data is lost if the
service goes down.
Database Session data is
persisted.
Slower than session
state.
Management cost is
relatively high.
View Recommendations
The primary concern of a view is presentation of the model. The view is chosen by the controller. Business logic
does not belong in the view, because business logic is the concern of the model layer. The view mechanism can be
extremely flexible. For example, a view of the model for a web page can be rendered using HTML. Another view of
the same model (same data), can be presented in XML and act as a web service.
DO put HTML in Views and Partial Views (not in a controller).
A strength of the view pattern is the readability of view template files. For the default view engine, ASP.NET offers
the following types of view files: full HTML view (.aspx), partial HTML view (.ascx), and master page (.master). A
master page enables you to specify an overall layout for a view. Master pages can be nested several times to
create a hierarchy of available layout types.
The following example, shows a view which calls a partial view:
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>