Вы находитесь на странице: 1из 9

ASP.NET MVC.

Template introduction - CodeProject

1 of 9

http://www.codeproject.com/Articles/820836/ASP-NET-MVC-Templat...

Articles Web Development ASP.NET General

ASP.NET MVC.Template introduction


Muchiachio, 26 Oct 2015

MIT

4.80 (64 votes)


MVC.Template is a starter template for ASP.NET MVC based solutions

Introduction
As the name implies, it's a project starter template for ASP.NET MVC based solutions (mainly for multi-paged enteprise
solutions, which could change in the future if there will be need for it).
This project was born after working on maintaining and improving few MVC projects and seeing how much of a headache these
projects were bringing with them. All because of a bad project foundation, which in the long run started to ruin program's
design and maintainability even more and more. Even though there are a lot of examples of good ASP.NET MVC practises on
the web, collecting them all and applying in the first applications is not an easy task.

Background
There are few rules this project will try to follow:
Simplicity - a good indicator of any program is it's simplicity thus resulting in lack of code. Any new ideas or findings on
making code simplier to understand and use will be incorporated first. Hard to understand code should be reported to
the issue police at GitHub along with reasoning on why it was hard to understand and use (suggestions are welcome in
the comments).
Activity - by now there are a lot of good projects which are no longer actively developed (dead). And it is very sad.
MVC.Template will try to be in the loop for years to come.
Open - this project will always be open sourced with MIT license. Use it, like it, hate it, do whatever.
Up to date - any new releases of frameworks used in the project will always be updated to their newest releases. So
even though we all love MVC5, it will not be supported after vNext release will be sufficient to replace it and so on.

Features
Model-View-ViewModel architectural design.
Lowercase or normal ASP.NET urls.
Custom membership providers.
Protection from CSRF, XSS, etc.
Easy project renaming.
Dependency injection.
Custom error pages.
Globalization.
Audit log.

27/10/2015 22:14

ASP.NET MVC.Template introduction - CodeProject

2 of 9

http://www.codeproject.com/Articles/820836/ASP-NET-MVC-Templat...

Site map.
Tests.

Project structure
MvcTemplate - is used for keeping any project specific implementation, which can not reside in other projects. Mainly it
will be custom project components, which can not be easily reused because of hard dependencies to other solution
projects, like data access layer.
MvcTemplate.Components - should only contain reusable components. It means no references to any
MvcTemplate.Xxxxx project, with an exception of MvcTemplate.Resources. This assembly is intented to keep all the
reusable "goodies" which are born while implementing a specific project. So that it can be reused in the next projects
and save us some more time for programming more interesting code.
MvcTemplate.Controllers - separates controllers and their routing configuration from other assemblies. It's known that
separation of controllers has some disadvantages (like not being able to generate strongly typed helpers with T4MVC).
But until someone proves this approach wrong, controllers will be separated.
MvcTemplate.Data - hides data access layer implementation from other assemblies. So that assemblies which are using
data access layer would not have to reference frameworks like EntityFramework. Or, know implementation details about
domain model mappings with view models.
MvcTemplate.Objects - contains all domain and view model classes in one place. Any other classes should not be here.
MvcTemplate.Resources - keeps all our "beloved magic strings" in healthy environment. It is also used for easy solution
globalization.
MvcTemplate.Services - is the assembly which does the main job. And by the main job I mean managing program state,
like creating, editing, deleting domain entities; sending emails; eating CPU cycles and what not. This is where the
processing logic should be, not in the controller. Controllers should only act as a brainless routing switch based on
services and validation outputs.
MvcTemplate.Tests - yet another main reason why MVC applications become as bad as they are. One of the main
problem MVC architecture is trying to address is testability, and not testing MVC application should be considered a sin.
This assembly covers most (~99%) of the solution asemblies code base. Mainly through unit testing.
MvcTemplate.Validators - separates all domain validation logic from controllers and their services. So it can be reused
in other controllers if needed (e.g. account registration and profile update shares same validation concepts).
MvcTemplate.Web - and finally web assembly, which is kind of empty. Because it mainly consists of UI representation
views, styling sheets, scripts and other client side components.

Installation
Download one of the release versions from GitHub, or clone develop branch to your computer.
Before opening the project run "Rename.exe" located in the project's root folder (running it later can cause some
compilation problems, because of generated dll's and such). It will:
Remove unnecessary files like CONTRIBUTION.md.
Set initial assembly version to 0.1.0.0.
Rename solution and projects.
Rename root namespace.
Rename company name.
It will ask for your desired root namespace and company's name. So entering project's root namespace "Oyster" and
company's name "Tegram". Would result in project structure like this:

27/10/2015 22:14

ASP.NET MVC.Template introduction - CodeProject

3 of 9

http://www.codeproject.com/Articles/820836/ASP-NET-MVC-Templat...

Namespaces like:
namespace Oyster.Controllers.Administration
namespace Oyster.Services
namespace Oyster.Objects
And company name will be visible in assembly declarations:

Next, open solution and build project but not run it, so that NuGet packages can be restored.
After NuGet packages are restored, set Web as default start up project.
Open Package Manager Console and run "update-database", on Data project. This creates initial database in local
SQLEXPRESS instance.
Project uses some of commonly used VS extensions, you should download them if you don't have them already:
Web Essentials 201X - css files are generated by using "Web Essentials" build in less compiler. Other then that
Web Essentials provides other good VS extensions for modern web developers.
You may have already seen a lot of red text in "Package Manager Console", especially those who are using
VS2013. It comes from T4Scaffolding not fully supporting VS2013.
If you are using VS2013, download and install Windows Management Framework 4.0. Which is needed for
VS2013 scaffolding to work.
If you area using VS2015, remove T4Scaffolding.Core package, because VS2015 does not support this
kind of scaffolding.
Depending on your machine configuration you may need to enable powershell scripts to be run on your
machine by using "Set-ExecutionPolicy" command.
After all this your project should compile and run. Default admin username and password can be found in
EntityFramework configuration class under ~/Root namespace/Data/Migrations/Configuration.cs.

Using the code


Models
As you might know in traditional MVC, models are the ones to hold all business logic. But in this template they are just POCOs

27/10/2015 22:14

ASP.NET MVC.Template introduction - CodeProject

4 of 9

http://www.codeproject.com/Articles/820836/ASP-NET-MVC-Templat...

for representing database tables. The same applies to representation models also known as view models.
public class Account : BaseModel // All domain models should inherit base model with shared Id and
CreationDate columns
{
[Required]
[StringLength(128)]
[Index(IsUnique = true)]
public String Username { get; set; } // Only member declarations, no business logic
[Required]
public Boolean IsAdmin { get; set; }
}
public class AccountView : BaseView // All view models should inherit base view with shared Id and
CreationDate columns
{
[Required]
[StringLength(128)]
[Index(IsUnique = true)]
public String Username { get; set; } // Only member declarations, no business logic
// Declaring only user visible fields. So that "IsAdmin" property can not be edited or
over-posted by the user
}

Database
Registering newly created model with the database is relatively easy. First of all, new DbSet has to be added to the main Context
class:
public class Context : DBContext
{
...
protected DbSet<Account> Accounts { get; set; } // protected is used, so that testing context
can inherit the same database structure
...
}
MVC.Template is using code first approach for database management, so after adding new DbSet to the context you will need
to run "Add-Migration <your_migration_name>", followed by "update-database" command in "Package Manager Console".
Another thing needed to be done in database layer is to create a map between domain and view models using AutoMapper. In
most cases it's just writing two lines of code in ObjectMapper class, you can always check out AutoMapper's documentation for
more:
public static class ObjectMapper
{
...
public static void Map()
{
Mapper.CreateMap<Account, AccountView>(); // Creating automatic map from account model to
account view
Mapper.CreateMap<AccountView, Account>(); // Creating automatic map from account view to
account model
}
...
}

Controllers
27/10/2015 22:14

ASP.NET MVC.Template introduction - CodeProject

5 of 9

http://www.codeproject.com/Articles/820836/ASP-NET-MVC-Templat...

Any new controller should inherit BaseController, which can be used as an extension point for every controller. Also it keeps
shared controller methods, like authorization and redirection to static pages (e.g. "404 not found", "403 unauthorized"). Other
controller bases include:
ServicedController - for controllers with injected service instance,
ValidatedController - for controllers with injected service and validator instances.
The one to choose should be obvious from your needs in a controller. All these controller bases are under [GlobalizedAuthorize]
attribute, so they will all be authorized by default.
public class AccountsController : ValidatedController<IAccountValidator, IAccountService> // Using
ValidatedController, because contoller will be using validator and service instances
{
...
[HttpGet]
public ActionResult Edit(String id)
{
return NotEmptyView(Service.Get<AccountView>(id)); // Getting view from service, and
returning account view only if account with given id still exists, otherwise redirecting to not
found page.
}
[HttpPost]
[ValidateAntiForgeryToken] // Validate antiforgery token on all post actions
public ActionResult Edit(AccountView account) // Action accepting AccountView class from the
request
{
if (!Validator.CanEdit(account)) // One call to validate everything about the model
return View(account); // Return to same model view, if any validation failed
Service.Edit(account); // Otherwise perform model mutation by using the service
return RedirectIfAuthorized("Index"); // Redirecting to "Index" action, only then current
user is authorized to view it, otherwise redirect to home page
}
...
}

Services
Services are ment to keep business logic for changing domain model or doing other business tasks. One service class should
only "serve" one domain model, thus the name of the service should generally be <Domain model name>Service (e.g.
AccountService, RoleService). In addition to that, every service should have an interface which inherits IService.
public interface IAccountService : IService // Inheriting shared service interface
{
...
TView Get<TView>(String id) where TView : BaseView; // Defining generic GetView method, so that
account model can be automatically mapped to any mapped view
void Edit(AccountView view); // Defining edit action for account view
...
}
public AccountService : IAccountService
{
...
public TView Get<TView>(String id) where TView : BaseView
{
return UnitOfWork.GetAs<Account, TView>(id); // Getting account domain model with given id
from the database, and mapping it to TView type

27/10/2015 22:14

ASP.NET MVC.Template introduction - CodeProject

6 of 9

http://www.codeproject.com/Articles/820836/ASP-NET-MVC-Templat...

}
public void Edit(AcountView view)
{
Account account = UnitOfWork.To<Account>(view); // Mapping view back to model
UnitOfWork.Update(account); // Updating account
UnitOfWork.Commit(); // Commiting transaction
}
...
}

Validators
Validators, unlike services are ment to hold all business validation logic for domain models. Validator implementation follow the
same pattern as services. Validation class for one domain model with validator interface.
public interface IAccountValidator : IValidator // Inheriting shared validator interface
{
// Other account validator interface code
Boolean CanEdit(AccountView view); // Defining needed validation methods for account view
// Other account validator interface code
}
public AccountValidator : IAccountValidator
{
...
public Boolean CanEdit(AcountView view)
{
Boolean isValid = IsUniqueUsername(view); // Making any custom validation to the view
isValid &= ModelState.IsValid; // Always include ModelState validation check, so that
controller never has to call ModelState.IsValid
return isValid;
}
...
}

Views
Views should always be written for view models like "AccountView", "RoleView", but never for domain models.
@model AccountEditView
<div class="col-xs-12">
<div class="widget-box">
<div class="widget-title">
<span class="widget-title-icon fa fa-th-list"></span>
<h5>@Headers.AdministrationAccountsEdit</h5>
<div class="widget-title-buttons">
@if (Html.IsAuthorizedFor("Details"))
{
<a class="btn" href="@Url.Action("Details", new { id = Model.Id })">
<i class="fa fa-info"></i><span class="text">@Actions.Details</span>
</a>
}
</div>
</div>
<div class="widget-content">

27/10/2015 22:14

ASP.NET MVC.Template introduction - CodeProject

7 of 9

http://www.codeproject.com/Articles/820836/ASP-NET-MVC-Templat...

@using (Html.BeginForm())
{
@Html.AntiForgeryToken() @* Validating anti forgery token on all post actions. *@
<div class="form-group">
<div class="control-label col-sm-12 col-md-3 col-lg-2">
@Html.FormLabelFor(model => model.Username) @* Custom label helper to add
required '*' spans and localizing labels. *@
</div>
<div class="control-content col-sm-12 col-md-9 col-lg-5">
@Html.FormTextBoxFor(model => model.Username) @* Custom text box helper to
add necessary attributes, like readonly on not editable fields. *@
</div>
<div class="control-validation col-sm-12 col-lg-5">
@Html.ValidationMessageFor(model => model.Username)
</div>
</div>
<div class="form-group">
<div class="form-actions col-sm-12 col-lg-7">
<input class="btn btn-primary" type="submit" value="@Actions.Submit" />
</div>
</div>
}
</div>
</div>
</div>

Globalization
Currently default language is English, in addition to that Lithuanian was added, just for an example of multiple languages with
different number and date formats in the system. You can easily disable Lithuanian language by removing it from the
Globalization.xml file (and then you have time, removing it's resources or replacing them with your language of choice).
<?xml version="1.0" encoding="utf-8" ?>
<globalization>
<language name="English" culture="en-GB" abbrevation="en" default="true" />
</globalization>
Leaving one language will remove any language selections in the system automatically.

Summary
In this article, I introduced you to MVC.Template, a starting project template for ASP.NET MVC based solutions. And explained
starting project structure, it's installation and basic code usage. More examples can always be found in MVC.Template's
codebase at GitHub. This project will be actively develop by me and my colleagues at work. And hopefully become ASP.NET
MVC project starting point for new and experienced developers alike.

History
2015.10.26 Updates, accordingly with v1.5.
2015.07.06 Updates, accordingly with v1.4.
2015.04.12 Updates, accordingly with v1.3.
2015.01.05 Updates, accordingly with v1.2.
2014.11.09 Updates, accordingly with v1.1.
2014.09.22 Initial article for v1.0.

27/10/2015 22:14

ASP.NET MVC.Template introduction - CodeProject

8 of 9

http://www.codeproject.com/Articles/820836/ASP-NET-MVC-Templat...

License
This article, along with any associated source code and files, is licensed under The MIT License

Share
About the Author
Muchiachio
Software Developer
Niue

No Biography provided

You may also be interested in...


Introduction to ASP.NET
Boilerplate

From Dev to Ops: An


Introduction

Introduction to Anthem.NET

Add HTML5 Document Viewer


to ASP.NET MVC 5 Project

Introduction to .NET

Is SQL Server killing your


applications performance?

Comments and Discussions


205 messages have been posted for this article Visit http://www.codeproject.com/Articles/820836/ASP-NETMVC-Template-introduction to post and view comments on this article, or click here to get a print view with messages.
Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.151024.1 | Last Updated 26 Oct 2015

Selecione o idioma

Article Copyright 2014 by Muchiachio


Everything else Copyright CodeProject, 1999-2015

27/10/2015 22:14

ASP.NET MVC.Template introduction - CodeProject

9 of 9

http://www.codeproject.com/Articles/820836/ASP-NET-MVC-Templat...

27/10/2015 22:14