On Tuesday, February 9th, I was scheduled lead a jam session for Come Jam With Us, the software developer study group in Ann Arbor. The session was to be on ASP.NET MVC 2, aimed to give attendees enough of an introduction to the product to empower developers to be able to start coding their own ASP.NET MVC 2 projects. Unfortunately, Mother Nature did not cooperate that day, half of the state of Michigan seemingly shut down under 8" of snow, and the session was cancelled and rescheduled for February 23rd. The goal of these Learn to Code exercises is to give you an introduction to building applications with ASP.NET MVC 2. In the near future, I also hope to provide a screen cast of these same exercises.
This coding exercise is designed to give you an introduction to ASP.NET MVC 2. In this exercise, developers will create their first database-driven ASP.NET MVC 2 application within Visual Studio, primarily using code generation built in to Visual Studio. Developers performing this exercise should be familiar with ASP.NET development and Visual Studio, but no previous experience with ASP.NET MVC is required.
You will need few things for ASP.NET MVC 2 application development and to complete these exercises. Please complete the following prerequisites prior to moving on. The session is designed to be completed in about an hour, but prerequisite setup is not included in that time.
Before any coding can occur, the first thing that we have to do is create a new ASP.NET MVC 2 project from within Visual Studio.
Development within ASP.NET MVC is based on convention over configuration. Certain naming conventions are built in the system to eliminate the amount of boiler-plate code that you need to recreate. That is not to say that you must follow these naming conventions—you may use whatever convention you like—but by straying from the standardized conventions, you will be creating a lot of extra work for yourself. With our new ASP.NET MVC 2 Project, a few of these conventions are immediately visible.
Using the project we just created, we're going to create an application that manage a list of employees, including their name, job title, date of hire, and date of termination. Though the default project is a great help on some applications, it can get in the way on others; we're not going to need any account services in our application, so we need to first trim the project down a little.
#menucontainer { padding-top:40px; }
Like any dynamic web site, we need a storage mechanism. Create a database in SQL Server or SQL Server Express with an Employee table containing columns for name, job title, hired date, and termination date, as well as an identity column for finding records.
The next thing we need to create is our Model. Not only is it the code representation for our business entity (An Employee class contains Name, JobTitle, HiredOn, and TerminatedOn properties), it is also responsible for how to get, save, or delete data from the database. We will be using Microsoft Entity Framework through Visual Studio to generate our model for us.
Now that our model is in place, we need to create a controller. The controller is responsible for managing all interaction between the end-user and the application, including identifying what data to get, save, or delete. (Remember, though the Controller is responsible for what, the Model is responsible for how.)
var _entities = new MvcJamSession.Models.MvcJamSessionEntities(); return View(_entities.Employee.ToList());
We have our Model and we have our Controller, so it is time for our View. The View is responsible for display only—it should contain virtually no logic. Our controller doesn't do anything yet, but we can at least get the base file structure and navigation in place. Since our Model governs how and our Controller governs what, think of the View as governing where, as it is responsible for deciding where each data element gets displayed on your page.
<ul id="menu"> <li><%= Html.ActionLink("Home", "Index", "Home")%></li> <li><%= Html.ActionLink("About", "About", "Home")%></li> <li><%= Html.ActionLink("Employees", "Index", "Employee")%></li> </ul>
New in ASP.NET MVC 2: Strongly Typed HTML Helpers In the previous version of ASP.NET MVC, HTML helpers were simple generic classes. Generated views were full of Magic Strings for each property in your model, such as <%= Html.TextBox("Name") %>, opening the door for a fat-fingered property name. MVC 2 includes strongly-typed HTML helpers on strongly-typed views. For form-based views, use the new strongly-typed "For" methods, such as <%= Html.TextBoxFor(model => model.Name) %> or <%= Html.EditorFor(model => model.Name) %> to eliminate the risk of incorrectly entering a property name. For display fields, use Html.DisplayFor() to provide similar benefits for your read-only data, including the elimination of HTML encoding for each field.
In the previous version of ASP.NET MVC, HTML helpers were simple generic classes. Generated views were full of Magic Strings for each property in your model, such as <%= Html.TextBox("Name") %>, opening the door for a fat-fingered property name. MVC 2 includes strongly-typed HTML helpers on strongly-typed views. For form-based views, use the new strongly-typed "For" methods, such as <%= Html.TextBoxFor(model => model.Name) %> or <%= Html.EditorFor(model => model.Name) %> to eliminate the risk of incorrectly entering a property name. For display fields, use Html.DisplayFor() to provide similar benefits for your read-only data, including the elimination of HTML encoding for each field.
A list of employees is great, but we also need the ability to manipulate that data. First, let's start with the ability to create new data.
public ActionResult Create([Bind(Exclude="Id")] Employee newEmployee)
try { if (!ModelState.IsValid) return View(); var _entities = new MvcJamSession.Models.MvcJamSessionEntities(); _entities.AddToEmployee(employee); _entities.SaveChanges(); return RedirectToAction("Index"); } catch { return View(); }
New in ASP.NET MVC2: Better Verb Attributes In the first version of ASP.NET MVC, HTTP Verb conditions were placed on an Action via the AcceptVerbsAttribute, such as the Create action's [AcceptVerbs(HttpVerbs.Post)]. In ASP.NET MVC 2, these attributes have been simplified with the introduction of the HttpGetAttribute, HttpDeleteAttribute, HttpPostAttribute, and HttpPutAttribute.
In the first version of ASP.NET MVC, HTTP Verb conditions were placed on an Action via the AcceptVerbsAttribute, such as the Create action's [AcceptVerbs(HttpVerbs.Post)]. In ASP.NET MVC 2, these attributes have been simplified with the introduction of the HttpGetAttribute, HttpDeleteAttribute, HttpPostAttribute, and HttpPutAttribute.
The end user can view a list of Employees, and can create new employees, but when the end user clicks the Edit or Detail links, they get an error since these Views haven't been created yet and the Actions are not implemented. One by one, we will get the new views in place.
Go back to the Employee controller. Now that we know what the integer argument is for, we need to retrieve the Employee matching the associated identity and pass it to a view for editing or display.
var _entities = new MvcJamSession.Models.MvcJamSessionEntities(); return View(_entities.Employee.Where(emp => emp.Id == id).First());
public ActionResult Edit(MvcJamSession.Models.Employee employee)
try { if (!ModelState.IsValid) return View(); var _entities = new MvcJamSession.Models.MvcJamSessionEntities(); var _originalEmployee = _entities.Employee.Where(emp => emp.Id == employee.Id).First(); _entities.ApplyPropertyChanges(_originalEmployee.EntityKey.EntitySetName, employee); _entities.SaveChanges(); return RedirectToAction("Index"); } catch { return View(); }
public ActionResult Delete(MvcJamSession.Models.Employee employee)
var _entites = new MvcJamSession.Models.MvcJamSessionEntities(); var originalEmployee = _entites.Employee.Where(emp => emp.Id == deletedEmployee.Id).First(); _entites.DeleteObject(originalEmployee); _entites.SaveChanges(); return RedirectToAction("Index");
We now have a fully-functional ASP.NET MVC application to manage our Employee records. Congratulations!
Remember Me