Tuesday, May 3, 2011

Building simple ASP.NET MVC Application in 10 minutes using NuGet package

I will try to illustrate a very simple ASP.NET MVC application using NuGet. My goal is to illustrate how easy and straightforward can be to create a simple application. In a few words, I will create a brand new application, which at this stage will be able only to list, create, edit and delete code snippets. I will use Visual Studio 2010, ASP.NET 4 and SQL Server Express in my example.

1. Create an empty ASP.NET MVC 3 application.


2. Create an empty class into the 'Model' folder of the MVC project.


3. Open the Package Manager Console and write the following command:
    Install-Package MvcScaffolding

The output should look like:

'T4Scaffolding (≥ 1.0.0)' not installed. Attempting to retrieve dependency from source...
Done.
'EntityFramework (≥ 4.1.10311.0)' not installed. Attempting to retrieve dependency from source...
Done.
You are downloading EntityFramework from Microsoft, the license agreement to which is available at http://go.microsoft.com/fwlink/?LinkID=211010. Check the package for additional dependencies, which may come with their own license agreement(s). Your use of the package and dependencies constitutes your acceptance of their license agreements. If you do not accept the license agreement(s), then delete the relevant components from your device.
Successfully installed 'EntityFramework 4.1.10331.0'.
Successfully installed 'T4Scaffolding 1.0.0'.
Successfully installed 'MvcScaffolding 1.0.0'.
Successfully added 'EntityFramework 4.1.10331.0' to SnippIt.
Successfully added 'T4Scaffolding 1.0.0' to SnippIt.
Successfully added 'MvcScaffolding 1.0.0' to SnippIt.

Remember that this command will alter your project, add some references, etc... You should perform this step in every solution that you want to use this package.

4. Now it's time to define your model class. Open the CodeSnippet.cs file that we previously created and write its definition. Here is a sample:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;

namespace SnippIt.Models
{
    public class CodeSnippet
    {
        public int Id { get; set; }

        [Required]
        public string Title { get; set; }

        [Required]
        public string Body { get; set; }
    }
}

Note that we have marked the 'Title' and 'Body' property as required. This attribute is defined in the System.ComponentModel.DataAnnotations and you can find there some other useful attributes that will help you to validate your Model class.

5. And this is the magic step ... Open your Package Manager Console and write the following command

Scaffold Controller CodeSnippet

And the output will look like:

Scaffolding CodeSnippetsController...
Added database context 'Models\SnippItContext.cs'
Added 'CodeSnippets' to database context 'SnippIt.Models.SnippItContext'
Added controller Controllers\CodeSnippetsController.cs
Added Create view at 'Views\CodeSnippets\Create.cshtml'
Added Edit view at 'Views\CodeSnippets\Edit.cshtml'
Added Delete view at 'Views\CodeSnippets\Delete.cshtml'
Added Details view at 'Views\CodeSnippets\Details.cshtml'
Added Index view at 'Views\CodeSnippets\Index.cshtml'
Added _CreateOrEdit view at 'Views\CodeSnippets\_CreateOrEdit.cshtml'

And all is done!

Let's look what actually happened here.
  • Since, I choose Razor to be my default view engine, all the generated view are written with Razor.
  • Open your database server and you will notice that a new database is created. It probably will be named 'SnippIt.Model.SnippItContext'. Of course, you can tweak a little the Scaffolding command and change this name.
  • While we are still in the database, take a look at the 'CodeSnippets' table that is also auto-generated. As you can suppose the 'Title' and 'Body' columns are marked as not nullable. What is more interesting is that the 'Id' column is marked as primary key is set as Identity with seed=1 and increment=1. The Scaffolding package is smart enough to do this by default.
  • Now let's open the site itself. All the work here is already done for you, too. There is a 'Create new' link and 'Edit', 'Delete' and 'Details' links for every code snippet that you have added.

    While you add your first code snippet you will notice that there is validation added automatically for your required fields and the primary key column is hidden from the user interface perspective. When you try to delete an entity a nice confirmation screen is displayed. Everything is almost as I would do it, just a little more work is needed to make this application a real world web site.
  • If you are curious enough and open the CodeSnippetController.cs file in the Controllers you will again notice that your entities are retrieved and saved by the Id column. It will look similar to:

            //
            // GET: /CodeSnippets/Edit/5
     
            public ActionResult Edit(int id)
            {
                CodeSnippet codesnippet = context.CodeSnippets.Single(x => x.Id == id);
                return View(codesnippet);
            }
    
            //
            // POST: /CodeSnippets/Edit/5
    
            [HttpPost]
            public ActionResult Edit(CodeSnippet codesnippet)
            {
                if (ModelState.IsValid)
                {
                    context.Entry(codesnippet).State = EntityState.Modified;
                    context.SaveChanges();
                    return RedirectToAction("Index");
                }
                return View(codesnippet);
            }
    

    Also, the post method is strongly typed, which is great and will help you in writing more durable code.

All this was done in 5 simple steps and 15 minutes (including the time to read this post). Most of the actions can be customized to fit your specific needs. This Scaffolding package will save a lot of your precious time by doing the dummy work and leave you to deal with the business logic that you have to implement. It guarantees that the generated code is consistent in all layers - database, presentation, etc. I hope this will be useful to you.