MVC Scaffolding

MVC Scaffolding is a based on T4 Templating. It’s goal is to generate the framework for your code,  it’s extensible and customisable. The scaffolds included with the MVC build Controllers and Views, but it can do so much more.

How to install MvcScaffolding from NuGet

First create a new MVC project.

In the Package Manager Console, type install-package MvcScaffolding. You should see results similar to this:

PM> install-package MvcScaffolding
Attempting to resolve dependency 'T4Scaffolding'.
Attempting to resolve dependency 'T4Scaffolding.Core'.
Attempting to resolve dependency 'EntityFramework'.
Installing 'T4Scaffolding.Core 1.0.0'.
Successfully installed 'T4Scaffolding.Core 1.0.0'.
Installing 'T4Scaffolding 1.0.8'.
Successfully installed 'T4Scaffolding 1.0.8'.
Installing 'MvcScaffolding 1.0.9'.
Successfully installed 'MvcScaffolding 1.0.9'.
Adding 'T4Scaffolding.Core 1.0.0' to TestWeb2.
Successfully added 'T4Scaffolding.Core 1.0.0' to TestWeb2.
Adding 'T4Scaffolding 1.0.8' to TestWeb2.
Successfully added 'T4Scaffolding 1.0.8' to TestWeb2.
Adding 'MvcScaffolding 1.0.9' to TestWeb2.
Successfully added 'MvcScaffolding 1.0.9' to TestWeb2.

As you can see it resolves dependancies for T4Scaffolding and EntityFramework and will install them if necessary.

Creating a controller and views

Create a data model called Book :

public class Book
{
    [Key]
    public int Id { get; set; }
    [Required]
    public string Title { get; set; }
    public decimal Price { get; set; }
    public string Publisher { get; set; }
    public string ISBN { get; set; }
}

In the Package Manager Console type scaffold controller Book

PM> scaffold controller book
Scaffolding BooksController...
Added database context 'Models\TestWeb2Context.cs'
Added 'Books' to database context 'TestWeb2.Models.TestWeb2Context'
Added controller Controllers\BooksController.cs
Added Create view at 'Views\Books\Create.cshtml'
Added Edit view at 'Views\Books\Edit.cshtml'
Added Delete view at 'Views\Books\Delete.cshtml'
Added Details view at 'Views\Books\Details.cshtml'
Added Index view at 'Views\Books\Index.cshtml'
Added _CreateOrEdit view at 'Views\Books\_CreateOrEdit.cshtml'

This will create a new database context for the project, if one doesn’t already exist, and add a DbSet<> for the Book Model. It will then create a controller, and views for the standard CRUD operations.

Using Switches

Because we are doing this from the command line, we have more power to change things, using switches.

There are two types of command line switches:

  • Boolean Switches,  which for the  controller scaffold include Repository, Force, ForceMode, ReferenceScriptLibaries and NoChildItems. These default to false, and including them on a command line switches them on.
  • String Switches, which for the  controller scaffold include ControllerName, ModelType, DbContextType, Project, Layout, CodeLanguage, Area, ViewScaffolder, Layout, PrimarySectionName, SectionNames, TemplateFolders. These are values that are applied to the command like DbContextType to change the name of the DbContext class.

If you delete the existing context file from the Models folder and then in the Package Manager Console type:

scaffold controller Book –DbContextType LibraryDbContext

You should see this:

PM> scaffold controller Book –DbContextType LibraryDbContext 
Scaffolding BooksController...
Added database context 'Models\LibraryDbContext.cs'
Added 'Books' to database context 'TestWeb2.Models.LibraryDbContext'
Controllers\BooksController.cs already exists! Pass -Force to overwrite. Skipping...
Views\Books\Create.cshtml already exists! Pass -Force to overwrite. Skipping...
Views\Books\Edit.cshtml already exists! Pass -Force to overwrite. Skipping...
Views\Books\Delete.cshtml already exists! Pass -Force to overwrite. Skipping...
Views\Books\Details.cshtml already exists! Pass -Force to overwrite. Skipping...
Views\Books\Index.cshtml already exists! Pass -Force to overwrite. Skipping...
Views\Books\_CreateOrEdit.cshtml already exists! Pass -Force to overwrite. Skipping...
PM>

This will create the DbContext file with the name LibraryDbContext, and skip over the already created controller and views.

If rather than have the controller go straight to the database we would use the Repository pattern, then we can add the –repository switch. Also to force the controller to change to use the new repository we should use the –force switch.

If we want to use a repository add the switch –Repository

scaffold controller Book –DbContextType LibraryDbContext –repository –force

PM> scaffold controller Book –DbContextType LibraryDbContext –repository –force
Scaffolding BooksController...
LibraryDbContext already has a member called 'Books'. Skipping...
Added repository 'Models\BookRepository.cs'
Added controller Controllers\BooksController.cs
Added Create view at 'Views\Books\Create.cshtml'
Added Edit view at 'Views\Books\Edit.cshtml'
Added Delete view at 'Views\Books\Delete.cshtml'
Added Details view at 'Views\Books\Details.cshtml'
Added Index view at 'Views\Books\Index.cshtml'
Added _CreateOrEdit view at 'Views\Books\_CreateOrEdit.cshtml'
PM>

This will create the controller, views and DbContext file as before but will also create an interface IBookRepository and concrete implementation BookRepository.

    public class BookRepository : IBookRepository
    {
        LibraryDbContext context = new LibraryDbContext();

        public IQueryable<Book> All
        {
            get { return context.Books; }
        }

        public IQueryable<Book> AllIncluding(params Expression<Func<Book, object>>[] includeProperties)
        {
            IQueryable<Book> query = context.Books;
            foreach (var includeProperty in includeProperties) {
                query = query.Include(includeProperty);
            }
            return query;
        }

        public Book Find(int id)
        {
            return context.Books.Find(id);
        }

        public void InsertOrUpdate(Book book)
        {
            if (book.Id == default(int)) {
                // New entity
                context.Books.Add(book);
            } else {
                // Existing entity
                context.Entry(book).State = EntityState.Modified;
            }
        }

        public void Delete(int id)
        {
            var book = context.Books.Find(id);
            context.Books.Remove(book);
        }

        public void Save()
        {
            context.SaveChanges();
        }

        public void Dispose() 
        {
            context.Dispose();
        }
    }

    public interface IBookRepository : IDisposable
    {
        IQueryable<Book> All { get; }
        IQueryable<Book> AllIncluding(params Expression<Func<Book, object>>[] includeProperties);
        Book Find(int id);
        void InsertOrUpdate(Book book);
        void Delete(int id);
        void Save();
    }

It will also change the controller to use the repository:

 

   public class BooksController : Controller
    {
        private readonly IBookRepository bookRepository;

        // If you are using Dependency Injection, you can delete the following constructor
        public BooksController() : this(new BookRepository())
        {
        }

        public BooksController(IBookRepository bookRepository)
        {
            this.bookRepository = bookRepository;
        }

        //
        // GET: /Books/

        public ViewResult Index()
        {
            return View(bookRepository.AllIncluding(book => book.Authors));
        }
.
.
.
}

 

Advertisements

About John

Software developer, lately specialising in Full Stack Web Development using c#, ASP.Net WebAPI 2, and Angular.
This entry was posted in Development and tagged , , . Bookmark the permalink.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s