Intro to ASP.NET MVC 4
Getting Started
Start
by running Visual Studio Express 2012 or Visual Web Developer 2010
Express. Most of the screen shots in this series use Visual Studio
Express 2012, but you can complete this tutorial with Visual Studio
2010/SP1, Visual Studio 2012, Visual Studio Express 2012 or Visual Web
Developer 2010 Express. Select New Project from the Startpage.
Visual
Studio is an IDE, or integrated development environment. Just like you
use Microsoft Word to write documents, you'll use an IDE to create
applications. In Visual Studio there's a toolbar along the top showing
various options available to you. There's also a menu that provides
another way to perform tasks in the IDE. (For example, instead of
selecting New Project from the Start page, you can use the menu and select File > New Project.)

Creating Your First Application
You
can create applications using either Visual Basic or Visual C# as the
programming language. Select Visual C# on the left and then select ASP.NET MVC 4 Web Application. Name your project "MvcMovie" and then click OK.
In the New ASP.NET MVC 4 Project dialog box, select Internet Application. Leave Razor as the default view engine.

Click OK.
Visual Studio used a default template for the ASP.NET MVC project you
just created, so you have a working application right now without doing
anything! This is a simple "Hello World!" project, and it's a good place
to start your application.
From the Debug menu, select Start Debugging.

Notice that the keyboard shortcut to start debugging is F5.
F5
causes Visual Studio to start IIS Express and run your web application.
Visual Studio then launches a browser and opens the application's home
page. Notice that the address bar of the browser says
localhost
and not something like example.com
. That's because localhost
always
points to your own local computer, which in this case is running the
application you just built. When Visual Studio runs a web project, a
random port is used for the web server. In the image below, the port
number is 41788. When you run the application, you'll probably see a
different port number.
Right
out of the box this default template gives you Home, Contact and About
pages. It also provides support to register and log in, and links to
Facebook and Twitter. The next step is to change how this application
works and learn a little bit about ASP.NET MVC. Close your browser and
let's change some code.
Adding a Controller
MVC stands for model-view-controller.
MVC is a pattern for developing applications that are well architected,
testable and easy to maintain. MVC-based applications contain:
- Models: Classes that represent the data of the application and that use validation logic to enforce business rules for that data.
- Views: Template files that your application uses to dynamically generate HTML responses.
- Controllers: Classes that handle incoming browser requests, retrieve model data, and then specify view templates that return a response to the browser.
We'll be covering all these concepts in this tutorial series and show you how to use them to build an application.
Let's begin by creating a controller class. In Solution Explorer, right-click the Controllers folder and then select Add Controller.

Name your new controller "HelloWorldController". Leave the default template as Empty MVC controller and click Add.

Notice in Solution Explorer that a new file has been created named HelloWorldController.cs. The file is open in the IDE.

Replace the contents of the file with the following code.
using System.Web; using System.Web.Mvc; namespace MvcMovie.Controllers { public class HelloWorldController : Controller { // // GET: /HelloWorld/ public string Index() { return "This is my <b>default</b> action..."; } // // GET: /HelloWorld/Welcome/ public string Welcome() { return "This is the Welcome action method..."; } } }
The controller methods will return a string of HTML as an example. The controller is named
HelloWorldController
and the first method above is named Index
.
Let’s invoke it from a browser. Run the application (press F5 or
Ctrl+F5). In the browser, append "HelloWorld" to the path in the address
bar. (For example, in the illustration below, it's http://localhost:1234/HelloWorld.)
The page in the browser will look like the following screenshot. In the
method above, the code returned a string directly. You told the system
to just return some HTML, and it did!
ASP.NET
MVC invokes different controller classes (and different action methods
within them) depending on the incoming URL. The default URL routing
logic used by ASP.NET MVC uses a format like this to determine what code
to invoke:
/[Controller]/[ActionName]/[Parameters]
The first part of the URL determines the controller class to execute. So /HelloWorld maps to the
HelloWorldController
class. The second part of the URL determines the action method on the class to execute. So /HelloWorld/Index would cause the Index
method of the HelloWorldController
class to execute. Notice that we only had to browse to /HelloWorld and the Index
method was used by default. This is because a method namedIndex
is the default method that will be called on a controller if one is not explicitly specified.
Browse to http://localhost:xxxx/HelloWorld/Welcome. The
Welcome
method runs and returns the string "This is the Welcome action method...". The default MVC mapping is /[Controller]/[ActionName]/[Parameters]
. For this URL, the controller is HelloWorld
and Welcome
is the action method. You haven't used the [Parameters]
part of the URL yet.
Let's modify the example slightly so that you can pass some parameter information from the URL to the controller (for example, /HelloWorld/Welcome?name=Scott&numtimes=4). Change your
Welcome
method to include two parameters as shown below. Note that the code uses the C# optional-parameter feature to indicate that thenumTimes
parameter should default to 1 if no value is passed for that parameter.public string Welcome(string name, int numTimes = 1) { return HttpUtility.HtmlEncode("Hello " + name + ", NumTimes is: " + numTimes); }
Run your application and browse to the example URL (http://localhost:xxxx/HelloWorld/Welcome?name=Scott&numtimes=4). You can try different values for
name
and numtimes
in the URL. The ASP.NET MVC model binding system automatically maps the named parameters from the query string in the address bar to parameters in your method.
In
both these examples the controller has been doing the "VC" portion of
MVC — that is, the view and controller work. The controller is returning
HTML directly. Ordinarily you don't want controllers returning HTML
directly, since that becomes very cumbersome to code. Instead we'll
typically use a separate view template file to help generate the HTML
response. Let's look next at how we can do this.
Adding a View
In this section you're going to modify the
HelloWorldController
class to use view template files to cleanly encapsulate the process of generating HTML responses to a client.
You'll create a view template file using the Razor view engine introduced with ASP.NET MVC 3. Razor-based view templates have a .cshtml file
extension, and provide an elegant way to create HTML output using C#.
Razor minimizes the number of characters and keystrokes required when
writing a view template, and enables a fast, fluid coding workflow.
Currently the
Index
method returns a string with a message that is hard-coded in the controller class. Change theIndex
method to return a View
object, as shown in the following code:public ActionResult Index() { return View(); }
The
Index
method above uses a view template to generate an HTML response to the browser. Controller methods (also known as action methods), such as the Index
method above, generally return an ActionResult (or a class derrived from ActionResult), not primitive types like string.
In the project, add a view template that you can use with the
Index
method. To do this, right-click inside the Index
method and click Add View.
The Add View dialog box appears. Leave the defaults the way they are and click the Add button:
The MvcMovie\Views\HelloWorld folder and the MvcMovie\Views\HelloWorld\Index.cshtml file are created. You can see them in Solution Explorer:
The following shows the Index.cshtml file that was created:

Add the following HTML under the
<h2>
tag.<p>Hello from our View Template!</p>
The complete MvcMovie\Views\HelloWorld\Index.cshtml file is shown below.
@{ ViewBag.Title = "Index"; } <h2>Index</h2> <p>Hello from our View Template!</p>
Note: If you are using Internet Explorer 9 and you don't see the
in IE to make the icon change from an outline
to a solid color
. Alternatively you can view this tutorial in FireFox or Chrome.
<p>Hello from our View Template!</p>
markup above in yellow highlight, click the Compatibility View button 


If you are using Visual Studio 2012, in solution explorer, right click the Index.cshtml file and select View in Page Inspector.

Alternatively, run the application and browse to the
HelloWorld
controller (http://localhost:xxxx/HelloWorld). TheIndex
method in your controller didn't do much work; it simply ran the statement return View()
,
which specified that the method should use a view template file to
render a response to the browser. Because you didn't explicitly specify
the name of the view template file to use, ASP.NET MVC defaulted to
using the Index.cshtml view file in the\Views\HelloWorld folder. The image below shows the string "Hello from our View Template!" hard-coded in the view.
Looks
pretty good. However, notice that the browser's title bar shows "Index
My ASP.NET A" and the big link on the top of the page says "your logo
here." Below the "your logo here." link are registration and log in
links, and below that links to Home, About and Contact pages. Let's
change some of these.
Changing Views and Layout Pages
First,
you want to change the "your logo here." title at the top of the page.
That text is common to every page. It's actually implemented in only one
place in the project, even though it appears on every page in the
application. Go to the /Views/Shared folder in Solution Explorer and open the _Layout.cshtml file. This file is called a layout pageand it's the shared "shell" that all other pages use.

Layout
templates allow you to specify the HTML container layout of your site
in one place and then apply it across multiple pages in your site. Find
the
@RenderBody()
line. RenderBody
is
a placeholder where all the view-specific pages you create show up,
"wrapped" in the layout page. For example, if you select the About link,
theViews\Home\About.cshtml view is rendered inside the RenderBody
method.
Change the site-title heading in the layout template from "your logo here" to "MVC Movie".
<div class="float-left"> <p class="site-title">@Html.ActionLink("MVC Movie", "Index", "Home")</p> </div>
Replace the contents of the title element with the following markup:
<title>@ViewBag.Title - Movie App</title>
Run the application and notice that it now says "MVC Movie ". Click the About link,
and you see how that page shows "MVC Movie", too. We were able to make
the change once in the layout template and have all pages on the site
reflect the new title.

Now, let's change the title of the Index view.
Open MvcMovie\Views\HelloWorld\Index.cshtml.
There are two places to make a change: first, the text that appears in
the title of the browser, and then in the secondary header (the
<h2>
element). You'll make them slightly different so you can see which bit of code changes which part of the app.@{ ViewBag.Title = "Movie List"; } <h2>My Movie List</h2> <p>Hello from our View Template!</p>
To indicate the HTML title to display, the code above sets a
Title
property of the ViewBag
object (which is in theIndex.cshtml view
template). If you look back at the source code of the layout template,
you’ll notice that the template uses this value in the <title>
element as part of the <head>
section of the HTML that we modified previously. Using this ViewBag
approach, you can easily pass other parameters between your view template and your layout file.
Run the application and browse to http://localhost:xx/HelloWorld.
Notice that the browser title, the primary heading, and the secondary
headings have changed. (If you don't see changes in the browser, you
might be viewing cached content. Press Ctrl+F5 in your browser to force
the response from the server to be loaded.) The browser title is created
with the
ViewBag.Title
we set in the Index.cshtml view template and the additional "- Movie App" added in the layout file.
Also notice how the content in the Index.cshtml view template was merged with the _Layout.cshtml view
template and a single HTML response was sent to the browser. Layout
templates make it really easy to make changes that apply across all of
the pages in your application.

Our
little bit of "data" (in this case the "Hello from our View Template!"
message) is hard-coded, though. The MVC application has a "V" (view) and
you've got a "C" (controller), but no "M" (model) yet. Shortly, we'll
walk through how create a database and retrieve model data from it.
Passing Data from the Controller to the View
Before
we go to a database and talk about models, though, let's first talk
about passing information from the controller to a view. Controller
classes are invoked in response to an incoming URL request. A controller
class is where you write the code that handles the incoming browser
requests, retrieves data from a database, and ultimately decides what
type of response to send back to the browser. View templates can then be
used from a controller to generate and format an HTML response to the
browser.
Controllers
are responsible for providing whatever data or objects are required in
order for a view template to render a response to the browser. A best
practice: A view template should never perform business logic or interact with a database directly.
Instead, a view template should work only with the data that's provided
to it by the controller. Maintaining this "separation of concerns"
helps keep your code clean, testable and more maintainable.
Currently, the
Welcome
action method in the HelloWorldController
class takes a name
and a numTimes
parameter
and then outputs the values directly to the browser. Rather than have
the controller render this response as a string, let’s change the
controller to use a view template instead. The view template will
generate a dynamic response, which means that you need to pass
appropriate bits of data from the controller to the view in order to
generate the response. You can do this by having the controller put the
dynamic data (parameters) that the view template needs in a ViewBag
object that the view template can then access.
Return to the HelloWorldController.cs file and change the
Welcome
method to add a Message
and NumTimes
value to the ViewBag
object. ViewBag
is a dynamic object, which means you can put whatever you want in to it; the ViewBag
object has no defined properties until you put something inside it. The ASP.NET MVC model binding systemautomatically maps the named parameters (name
and numTimes
) from the query string in the address bar to parameters in your method. The complete HelloWorldController.cs file looks like this:using System.Web; using System.Web.Mvc; namespace MvcMovie.Controllers { public class HelloWorldController : Controller { public ActionResult Index() { return View(); } public ActionResult Welcome(string name, int numTimes = 1) { ViewBag.Message = "Hello " + name; ViewBag.NumTimes = numTimes; return View(); } } }
Now the
ViewBag
object contains data that will be passed to the view automatically.
Next, you need a Welcome view template! In the Build menu, select Build MvcMovie to make sure the project is compiled.
Then right-click inside the
Welcome
method and click Add View.
Here's what the Add View dialog box looks like:
Click Add, and then add the following code under the
<h2>
element in the new Welcome.cshtml file. You'll create a loop that says "Hello" as many times as the user says it should. The complete Welcome.cshtml file is shown below.@{ ViewBag.Title = "Welcome"; } <h2>Welcome</h2> <ul> @for (int i=0; i < ViewBag.NumTimes; i++) { <li>@ViewBag.Message</li> } </ul>
Run the application and browse to the following URL:
http://localhost:xx/HelloWorld/Welcome?name=Scott&numtimes=4
Now data is taken from the URL and passed to the controller using the model binder. The controller packages the data into a
ViewBag
object and passes that object to the view. The view then displays the data as HTML to the user.
In the sample above, we used a
ViewBag
object
to pass data from the controller to a view. Latter in the tutorial, we
will use a view model to pass data from a controller to a view. The view
model approach to passing data is generally much preferred over the
view bag approach. See the blog entry Dynamic V Strongly Typed Views for more information.
Well,
that was a kind of an "M" for model, but not the database kind. Let's
take what we've learned and create a database of movies.
Adding a Model
In
this section you'll add some classes for managing movies in a database.
These classes will be the "model" part of the ASP.NET MVC application.
You’ll use a .NET Framework data-access technology known as the Entity Framework to
define and work with these model classes. The Entity Framework (often
referred to as EF) supports a development paradigm called Code First.
Code First allows you to create model objects by writing simple
classes. (These are also known as POCO classes, from "plain-old CLR
objects.") You can then have the database created on the fly from your
classes, which enables a very clean and rapid development workflow.
Adding Model Classes
In Solution Explorer, right click the Models folder, select Add, and then select Class.

Enter the class name "Movie".
Add the following five properties to the
Movie
class:public class Movie { public int ID { get; set; } public string Title { get; set; } public DateTime ReleaseDate { get; set; } public string Genre { get; set; } public decimal Price { get; set; } }
We'll use the
Movie
class to represent movies in a database. Each instance of a Movie
object will correspond to a row within a database table, and each property of the Movie
class will map to a column in the table.
In the same file, add the following
MovieDBContext
class:public class MovieDBContext : DbContext { public DbSet<Movie> Movies { get; set; } }
The
MovieDBContext
class represents the Entity Framework movie database context, which handles fetching, storing, and updating Movie
class instances in a database. The MovieDBContext
derives from the DbContext
base class provided by the Entity Framework.
In order to be able to reference
DbContext
and DbSet
, you need to add the following using
statement at the top of the file:using System.Data.Entity;
The complete Movie.cs file is shown below. (Several using statements that are not needed have been removed.)
using System; using System.Data.Entity; namespace MvcMovie.Models { public class Movie { public int ID { get; set; } public string Title { get; set; } public DateTime ReleaseDate { get; set; } public string Genre { get; set; } public decimal Price { get; set; } } public class MovieDBContext : DbContext { public DbSet<Movie> Movies { get; set; } } }
Creating a Connection String and Working with SQL Server LocalDB
The
MovieDBContext
class you created handles the task of connecting to the database and mapping Movie
objects
to database records. One question you might ask, though, is how to
specify which database it will connect to. You'll do that by adding
connection information in the Web.config file of the application.
Open the application root Web.config file. (Not the Web.config file in the Views folder.) Open the Web.config file outlined in red.

Add the following connection string to the
<connectionStrings>
element in the Web.config file.<add name="MovieDBContext" connectionString="Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Movies.mdf;Integrated Security=True" providerName="System.Data.SqlClient" />
The following example shows a portion of the Web.config file with the new connection string added:
<connectionStrings> <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-MvcMovie-2012213181139;Integrated Security=true" providerName="System.Data.SqlClient" /> <add name="MovieDBContext" connectionString="Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Movies.mdf;Integrated Security=True" providerName="System.Data.SqlClient" /> </connectionStrings>
This small amount of code and XML is everything you need to write in order to represent and store the movie data in a database.
Next, you'll build a new
MoviesController
class that you can use to display the movie data and allow users to create new movie listings.Accessing Your Model's Data from a Controller
By Rick Anderson|August 28, 2012
In this section, you'll create a new
MoviesController
class and write code that retrieves the movie data and displays it in the browser using a view template.
Build the application before going on to the next step.
Right-click the Controllers folder and create a new
MoviesController
controller. The options below will not appear until you build your application. Select the following options:- Controller name: MoviesController. (This is the default. )
- Template: MVC Controller with read/write actions and views, using Entity Framework.
- Model class: Movie (MvcMovie.Models).
- Data context class: MovieDBContext (MvcMovie.Models).
- Views: Razor (CSHTML). (The default.)

Click Add. Visual Studio Express creates the following files and folders:
- A MoviesController.cs file in the project's Controllers folder.
- A Movies folder in the project's Views folder.
- Create.cshtml, Delete.cshtml, Details.cshtml, Edit.cshtml, and Index.cshtml in the new Views\Movies folder.
ASP.NET
MVC 4 automatically created the CRUD (create, read, update, and
delete) action methods and views for you (the automatic creation of CRUD
action methods and views is known as scaffolding). You now have a fully
functional web application that lets you create, list, edit, and delete
movie entries.
Run the application and browse to the
Movies
controller by appending /Movies to the URL in the address bar of your browser. Because the application is relying on the default routing (defined in the Global.asax file), the browser request http://localhost:xxxxx/Movies is routed to the default Index
action method of the Movies
controller. In other words, the browser request http://localhost:xxxxx/Movies is effectively the same as the browser requesthttp://localhost:xxxxx/Movies/Index. The result is an empty list of movies, because you haven't added any yet.
Creating a Movie
Select the Create New link. Enter some details about a movie and then click the Create button.
Clicking the Create button
causes the form to be posted to the server, where the movie information
is saved in the database. You're then redirected to the /Movies URL, where you can see the newly created movie in the listing.

Create a couple more movie entries. Try the Edit, Details, and Delete links, which are all functional.
Examining the Generated Code
Open the Controllers\MoviesController.cs file and examine the generated
Index
method. A portion of the movie controller with the Index
method is shown below.public class MoviesController : Controller { private MovieDBContext db = new MovieDBContext(); // // GET: /Movies/ public ActionResult Index() { return View(db.Movies.ToList()); }
The following line from the
MoviesController
class
instantiates a movie database context, as described previously. You can
use the movie database context to query, edit, and delete movies.private MovieDBContext db = new MovieDBContext();
A request to the
Movies
controller returns all the entries in the Movies
table of the movie database and then passes the results to the Index
view.Strongly Typed Models and the @model Keyword
Earlier in this tutorial, you saw how a controller can pass data or objects to a view template using the
ViewBag
object. The ViewBag
is a dynamic object that provides a convenient late-bound way to pass information to a view.
ASP.NET
MVC also provides the ability to pass strongly typed data or objects to
a view template. This strongly typed approach enables better
compile-time checking of your code and richer IntelliSense in the Visual
Studio editor. The scaffolding mechanism in Visual Studio used this
approach with the
MoviesController
class and view templates when it created the methods and views.
In the Controllers\MoviesController.cs file examine the generated
Details
method. A portion of the movie controller with the Details
method is shown below.public ActionResult Details(int id = 0) { Movie movie = db.Movies.Find(id); if (movie == null) { return HttpNotFound(); } return View(movie); }
If a
Movie
is found, an instance of the Movie
model is passed to the Details view. Examine the contents of theViews\Movies\Details.cshtml file.
By including a
@model
statement
at the top of the view template file, you can specify the type of
object that the view expects. When you created the movie controller,
Visual Studio automatically included the following @model
statement at the top of the Details.cshtml file:@model MvcMovie.Models.Movie
This
@model
directive allows you to access the movie that the controller passed to the view by using a Model
object that's strongly typed. For example, in the Details.cshtml template, the code passes each movie field to theDisplayNameFor
and DisplayFor HTML Helpers with the strongly typed Model
object. The Create and Edit methods and view templates also pass a movie model object.
Examine the Index.cshtml view template and the
Index
method in the MoviesController.cs file. Notice how the code creates a List
object when it calls the View
helper method in the Index
action method. The code then passes thisMovies
list from the controller to the view:public ActionResult Index() { return View(db.Movies.ToList()); }
When you created the movie controller, Visual Studio Express automatically included the following
@model
statement at the top of the Index.cshtml file:@model IEnumerable<MvcMovie.Models.Movie>
This
@model
directive allows you to access the list of movies that the controller passed to the view by using a Model
object that's strongly typed. For example, in the Index.cshtml template, the code loops through the movies by doing a foreach
statement over the strongly typed Model
object:@foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.Title) </td> <td> @Html.DisplayFor(modelItem => item.ReleaseDate) </td> <td> @Html.DisplayFor(modelItem => item.Genre) </td> <td> @Html.DisplayFor(modelItem => item.Price) </td> <th> @Html.DisplayFor(modelItem => item.Rating) </th> <td> @Html.ActionLink("Edit", "Edit", new { id=item.ID }) | @Html.ActionLink("Details", "Details", { id=item.ID }) | @Html.ActionLink("Delete", "Delete", { id=item.ID }) </td> </tr> }
Because the
Model
object is strongly typed (as an IEnumerable<Movie>
object), each item
object in the loop is typed as Movie
.
Among other benefits, this means that you get compile-time checking of
the code and full IntelliSense support in the code editor:
Working with SQL Server LocalDB
Entity Framework Code First detected that the database connection string that was provided pointed to a
Movies
database
that didn’t exist yet, so Code First created the database
automatically. You can verify that it's been created by looking in the App_Data folder. If you don't see the Movies.mdf file, click the Show All Files button in theSolution Explorer toolbar, click the Refresh button, and then expand the App_Data folder.
Double-click Movies.mdf to open DATABASE EXPLORER, then expand the Tables folder to see the Movies table.

Note: If the database explorer doesn't appear, from the TOOLS menu, select Connect to Database, then cancel the Choose Data Source dialog. This will force open the database explorer.
Note: If you are using VWD or Visual Studio 2010 and get an error similar to any of the following following:
- The database 'C:\Webs\MVC4\MVCMOVIE\MVCMOVIE\APP_DATA\MOVIES.MDF' cannot be opened because it is version 706. This server supports version 655 and earlier. A downgrade path is not supported.
- "InvalidOperation Exception was unhandled by user code" The supplied SqlConnection does not specify an initial catalog.
You need to install the SQL Server Data Tools and LocalDB. Verify the
MovieDBContext
connection string specified on the previous page.
Right-click the
Movies
table and select Show Table Data to see the data you created.
Right-click the
Movies
table and select Open Table Definition to see the table structure that Entity Framework Code First created for you.

Notice how the schema of the
Movies
table maps to the Movie
class you created earlier. Entity Framework Code First automatically created this schema for you based on your Movie
class.
When you're finished, close the connection by right clicking MovieDBContext and selecting Close Connection. (If you don't close the connection, you might get an error the next time you run the project).

You
now have the database and a simple listing page to display content from
it. In the next tutorial, we'll examine the rest of the scaffolded code
and add a
SearchIndex
method and a SearchIndex
view that lets you search for movies in this database.
No comments:
Post a Comment