You are on page 1of 49

https://blog.udemy.

com/a-step-by-step-asp-net-tutorial-for-beginners/

A Step-by-Step ASP.NET Tutorial for


Beginners
SEPTEMBER 1, 2015 BY UDEMYTUTORIALS

By Moshfegh Hamedani for Udemy

Interested in more than just a guide? Check out a full ASP.NET course.
TABLE OF CONTENTS: CLICK TO JUMP TO A SPECIFIC SECTION
What Were Going to Build
Setting Up the environment
Displaying the List of Videos

Step
1:
Building
the
Model
Step
2:
Generating
the
Database
Step
3:
Populating
the
Table
Step 4: Creating a Page to Display Videos in the Database
Adding a New Video

Step
1:
Creating
a
Page
to
Step 2: Saving the Video to the Database

Add

Video

Editing an Existing Video

Step 1: Creating a Page Populated with Video Details


Step 2: Updating a Video in the Database
Deleting a Video

Step
1:
Creating
a
Page
to
Confirm
Step 2: Deleting a Video from the Database

Deletion

Review

A Step-by-Step ASP.NET MVC Tutorial for


Beginners
In this tutorial, Im going to teach you the fundamentals of ASP.NET MVC 5
and Entity Framework 6.
Before we get started, Im assuming you already have some experience with
C# and Visual Studio. At a minimum, you should be able to write code and
have very basic understanding of databases. However, no prior knowledge
of ASP.NET MVC or Entity Framework is required. So, lets get started.

What Were Going to Build


As part of this tutorial, well be building a simple web application for a
video rental store. We want the admins to have a page to see the list of all
videos in the store, as well as the ability to add, edit and delete videos. Im
going to exclude advanced features such as dealing with the stock, renting a
video or returning it, calculating cost, etc., so we can focus on the core
concepts of ASP.NET MVC. Ill be covering those advanced scenarios in my
comprehensive ASP.NET MVC course that will be published on Udemy
soon.
So, as part of building this app, youre going to learn how to:
Create a data entry form to add, update and delete records
in a database. In this tutorial, well build a form for managing

videos, but you can take what you learn from this tutorial and apply it
in any real-world scenarios.
Display a list of records. Again, here well display a list of videos,
but you can apply what youll learn here to any real-world scenarios.
You can use these techniques to display lists of tweets, photos, blog
posts, and literally anything else.
Use Entity Framework to query or update your database.
Entity Framework is an Object/Relational Mapper (ORM) that sits on
top of a database. This frees you from having to work directly with
database connections, writing SQL queries and commands, etc. You
ask Entity Framework to load or save a set of objects, and Entity
Framework will take care of all the dirty work for you.
Generate your database using code. This is what we call Code
First workflow (more on this later).
By the end of this tutorial, youll have a good understanding of ASP.NET
MVC and Entity Framework fundamentals. Not only will you be able to
build simple applications, but youll also be able to follow other tutorials
more easily. So, lets get started.

Setting Up the environment


To build this application, you need Visual Studio 2013. Any edition would
work. You can get a free community edition of Visual Studio here:
https://www.visualstudio.com/en-us/news/vs2013-community-vs.aspx
Once you have Visual Studio ready, launch it. Then go to File > New >
Project. In the New Project dialog, on the left side, under Templates,
select Visual C# > Web.On the right side, select ASP.NET Web
Application.

In the Name field, type Beaver. This is the code name for our video rental
store application. In the Location box, specify a location to create the files
on the disk. Preferably, use a local drive and not a network drive.
Otherwise, sometimes you may run into security or performance issues.
Finally, click OK.
On the next page, select MVC from templates. On the bottom right, make
sureHost in the cloud is not checked, as were not going to cover
deployment in this tutorial.

Next, wait a few seconds until Visual Studio creates your project template.
Now that our application is created, we can run it by
pressing Ctrl+F5. Visual Studio will launch your browser and take you to
an address likehttp://localhost:1234 where 1234 is the port number. The
port number on your machine might be different from mine, but that
doesnt matter.

Beginners Question: What is localhost? Every web application needs


to be hosted by a web server. Localhost is a mini web server running on
your machine. In the real world, you often publish an ASP.NET application
to a full-fledged IIS server. Web hosting companies take care of installation
of IIS for you. So you never have to worry about it. All you do is upload your
files.

Now we have an application with some basic functionality. You can register
a new account, log in, log out, change your password, etc. All this
functionality comes with the ASP.NET MVC template. So, you never have to
write code for these repetitive features that nearly every application needs.
Lets test-drive our sample application. On the top right, click Register.
Fill out the form with an email address and password, and click Register.

Note that youre automatically logged in with the email address you
supplied.

You can also log out.


All this functionality comes out of the box with a package called ASP.NET
Identity. If the default registration form doesnt work for you, you can
always customize it. That is beyond the scope of this tutorial, and Im going
to cover it in my comprehensive ASP.NET MVC course.

Lets recap: we built an ASP.NET MVC application using the template in


Visual Studio. Now, its time to implement some functionality specific to
our video rental store. Over the next few sections, in each section, well add
a new function to our application.

Displaying the List of Videos


The first feature Id like to implement here is a page with a plain list of
videos. Its much easier to build this than a form to add or update a video.
So, to build this page, first we need a database populated with some
records.
The traditional workflow is to create a database, design the tables using
table designers, and then generate domain classes based on these tables.
This approach or workflow is called Database First. But in this tutorial, Im
going to teach you the modern way of working with a database. This
approach is called Code First, which simply means code first, and let the
tools create the database for you. Thus, were never going to use table
designers to create our database.
At this point, you might ask, What tooling do we need to auto-generate the
database? The answer is: Entity Framework, which comes automatically
with our default ASP.NET MVC template.
Here is an overview of what were going to do in this section.
1. Were going to create a domain class that represents a video. This
class
is
going
to
have
properties
such
as Name, Description and Genre.
2. We use Entity Framework to generate the database.
3. We populate our table with some video records.
4. We build a web page to display the list of videos in the database.
Step 1: Building the Model
Back to Visual Studio, go to Solution Explorer. If its not visible, open it
from View > Solution Explorer. Right-click the Models folder in the
project and select Add > Class In the Add Class dialog, type Video in
the Name field. Now, declare these properties in the Video class.
public class Video
{

public
public
public
public

int Id { get; set; }


string Title { get; set; }
string Description { get; set; }
Genre Genre { get; set; }

}
public enum Genre
{
Comedy = 1,
Horror,
SciFi,
Romance,
Documentary,
Kids
}

Here, we use the Id property to uniquely identify each video. This Id will be
generated by the database.
Next, open IdentityModels.cs from the Models folder. This code is
automatically generated as part of the project template. Inside this file, we
have two classes:ApplicationUser, which represents a user,
and ApplicationDbContext. A DbContext is an abstraction over the
database which hides all the complexity of working with a database, such as
opening and closing connections, running commands, reading and writing
data, etc. Here is the auto-generated code forApplicationDbContext:
public class ApplicationDbContext : IdentityDbContext
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}

Note the constructor of this class. The constructor calls the base constructor
and passes DefaultConnection.
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}

DefaultConnection is the name of the connection string for the database


and is declared in Web.config, which is the configuration file for our

application. Lets have a quick look at the connection string. Going back to
the Solution Explorer, open Web.config in the project root.
Under <connectionStrings>, note
the
element
with
the
name DefaultConnection.Look
at
the
value
of
the connectionString attribute. This is the actual connection string to the
database:
<add name="DefaultConnection" connectionString="Data
Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnetBeaver-20150822102023.mdf;Initial Catalog=aspnet-Beaver20150822102023;Integrated Security=True"

Let me break this down for you:


Data Source: specifies the instance of your SQL Server. LocalDb is a
lightweight version of SQL Server that is used for development, which
is automatically installed with Visual Studio 2013. So you dont need
a full installation of SQL Server on your machine to do your
development.
AttachDbFilename: this is the path to the database file.
Here DataDirectoryrepresents the App_Data folder in your
project. So if you look inside this folder, youre going to see a file
named aspnet-Beaver-xxxx. The value of xxxx depends on the
date/time you create this project.
Initial Catalog: is the name of the database. In this case, it is the
same name as the database file itself.
Integrated Security = True means you can connect to the
database using your current Windows credentials, so you dont need a
separate username/password to connect to SQL Server.
Lets quickly recap what weve done up to this point. We created
a Video class and had a quick look at the auto-generated DbContext as well
as the connection string for the database.
The last part of this step is to make a slight modification to our DbContext.
Go back to IdentityModels.cs, and modify ApplicationDbContext as
follows:
public class ApplicationDbContext :
IdentityDbContext<ApplicationUser>
{

public DbSet<Video> Videos { get; set; }


public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}

Here I added a property of type DbSet<Video> called Videos. DbSet is a


generic class that comes with Entity Framework. As the name implies, it
represents a set (or a table) in a database. We work with this DbSet like a
collection in memory. We add Video objects to it, we remove an object, or
modify it and then when we ask Entity Framework to write changes to the
database. Entity Framework keeps track of changes in this collection in
memory, and based on those changes it will generate corresponding SQL
commands and runs them on the database.
We built our model in this step. Next, were going to generate the database.
Step 2: Generating the Database
In this step, youre going to learn how to use Entity Framework Code First
workflow to generate a database. But before we get started, let me explain
the process first, and then well do it together. The Code First workflow
includes three steps:
Enabling migrations: The very first time you need to use Code
First workflow, you need to enable migrations. With this, you instruct
Entity Framework to keep track of changes in your domain classes.
o

Adding a migration: Once migrations are enabled, every


time you make a change to your domain classes (e.g., adding a new
class, modifying an existing one, etc.), you create a new migration. A
migration is a class with some auto-generated code that is used to
upgrade or downgrade the database. Since Entity Framework is now
aware of changes in your domain classes, it will automatically
generate the code to migrate the database. For example, if you create
a new class like Video and then add a migration, Entity Framework
will generate code to create a new table called Videos.

Updating the database: With this step, you tell Entity Framework
to run migrations youve created on the database. Entity Framework
will compare the migrations you have in your project with the ones

that are run on the database, and if there are any new migrations, it
will run them sequentially to bring your database up to date.
So this is the process. Now, its time to do the steps. We do all these steps
inPackage Manager Console. Go to Tools > NuGet Package
Manager > Package Manager Console.
First, we need to run the Enable-Migrations command.
PM> Enable-Migrations

When you run this command, a new folder called Migrations will be
added to your project. Inside this folder, youll see a file
like [DATETIME]_InitialCreate.cs. Here,
the
value
of DATETIME depends on the date/time you run this command.
What is this file? Lets open it and see. You see a migration class
calledInitialCreate which derives from DbMigration and has two
methods: Up andDown, which are executed when upgrading or
downgrading the database, respectively. So with Entity Framework Code
First, you get full versioning of your database. At any time, you can upgrade
it to the latest version, or downgrade it to an earlier version. This is
extremely useful in the real world, where you may need to maintain
multiple versions of an application.
Lets take a look at the Up method in our migration class. Inside this
method, you see a number of calls to CreateTable method. Each of these
calls aims to create a table in the database. When you run migrations,
Entity Framework will read all this code and generate corresponding SQL
statements to execute on your database. This migration aims to create
tables such as AspNetRoles, AspNetUserRoles, AspNetUsers, etc.
These are the tables used internally by ASP.NET Identity to manage user
registration, login, etc.
Now, back to our migration process. I mentioned that every time you make
a change to your domain model, you need to add a new migration. Thus, we
created the Video class and added a DbSet<Video> to our DbContext. By
adding this DbSet to our DbContext, we tell Entity Framework that this
Video class needs to be stored in the database. Now, at this point, we dont
have any tables in the database for our videos. So, we need to add a new
migration.
Back to Package Manager Console, run this command:

PM> Add-Migration AddVideosTable

This command takes an argument, which is the name of your migration, in


this case AddVideosTable. This name is arbitrary, and you can call it
anything. There is no magic behind it. Its just a way to organize your
migrations so you know how each migration affects your database. I tend to
name my migrations based on the changes that should happen in the
database. In this case, because the Video class is a new class, I expect Entity
Framework to generate a migration to add a new table called Videos. This is
why I called this migration AddVideosTable.
When you run this command, Entity Framework will create a new
migration
file
in
the Migrations folder,
called [DATETIME]_AddVideosTable. Lets take a look at this file.
So, you see another migration class that derives from DbMigration. Look at
the Up method. Note the call to CreateTable, which tries to create a table
called Videos.
public override void Up()
{
CreateTable(
"dbo.Videos",
c => new
{
Id = c.Int(nullable: false, identity: true),
Title = c.String(),
Description = c.String(),
Genre = c.Int(nullable: false),
})
.PrimaryKey(t => t.Id);
}

Ive highlighted the key areas here that you need to understand. Note the
name of this table: Videos. Entity Framework uses convention over
configuration. Thus, there are certain conventions built into it that work in
most cases. In this case, because we have a class called Video, it assumes
the table should be called Videos.
Similarly, because we have four properties in our Video class, it will create
four columns with the same name and type in the database: Id, Title,
Description andGenre.
Also, look at the last line in this method:
.PrimaryKey(t => t.Id);

Again, based on the convention, it assumes that the Id property or column


represents a unique key for a video. Hence, it marks this column as the
primary key.
As you see, the convention is useful and works in most cases. But if it
doesnt work for you, you can always override it. For example, some
developers prefer singular names for their database tables. You can always
supply additional configuration to override the default conventions. This is
beyond the scope of this tutorial, but its something Ive covered in my
Entity Framework course that will be published on Udemy soon.
Back to our migration process. We enabled the migrations, and added a
new migration. Entity Framework detected that we have a new class, called
Videos, and generated the corresponding code to create a new table in the
database. The third step of the process is to run the migrations.
Open up Package Manager Console again and run:
PM> Update-Database

At this point, Entity Framework runs any pending migrations on your


database. By pending, I mean any migrations that have not been run on the
database before. So, lets take a look at the database.
In Solution Explorer, expand App_Data folder. You should see your
database file with MDF extension. If you dont see it, its because its not
part of the project, and by default, Visual Studio hides files on the disk that
are not in your project. To see all files, click the Show All Files button in
the toolbar on Solution Explorer.

You should see your database file in App_Data folder. Double-click it. A
new panel called Server Explorer pops out of the left side. Expand
the Tables.

The _MigrationHistory table is used by Entity Framework to keep track


of migrations that have been run on the database. Tables starting
with AspNet are used by ASP.NET Identity to manage authentication. And
finally, we have ourVideos table.
As you saw in this step, with the Code First workflow, we never wasted our
time with table designers. Instead, we focused on our code, which is what
we programmers do anyway. We modify our domain model, then add a
migration and update the database. Entity Framework will take care of
bringing the database up to date. With this, not only can we get things done
faster, but we also get full versioning of our database. We can upgrade or
downgrade our database to any version. When it comes to deploying our
application to production, we can ask Entity Framework to generate a SQL
script based on all migrations in our project. Then we can take this script
and run it on the production database.
In this step you learned about Code First migrations. Now that we have our
domain class and the corresponding table, its time to populate this table
with some data so we can display it to the user.
Step 3: Populating the Table
In Server Explorer, right-click the Videos table and go to Show Table
Data. Then add a few records to this table. Note that the Id column is an
IDENTITY column, so you dont need to supply any values for it. Again, by

convention, Entity Framework marks the primary key of a table as an


identity column.

Step 4: Creating a Page to Display Videos in the Database


In this step, youre going to learn how to create new web pages with
ASP.NET MVC. Were going to create a simple page to display all videos in
the database.
Again, before getting into the mechanics, let me give you some background
on the process and how everything fits together.
ASP.NET MVC is based on the Model View Controller (MVC) pattern. MVC
is one of the architectural patterns that aims to provide better separation of
concerns in your application, which results in better maintainability.
To understand MVC, think of a restaurant. When you go to a restaurant,
there is a waiter/waitress, a chef, one or more kitchen hands, a manager,
etc. Every person in the restaurant is responsible for only one thing.
Imagine what the restaurant would be like if all these people did
everything! What would it be like if the chef came to you, took the order,
then went shopping, and asked the cashier to cook your food? Youd
probably run away! The same concept applies in software. Clean software is
like a well-managed restaurant, where everyone has one and only role.
Architectural patterns like MVC help us to achieve this by promoting
separation of tasks. Therefore, different parts of your application will be
responsible for only one thing. In MVC terms, we have:
Views: which are purely responsible for presenting data. This is
where we write our HTML markup. Views should only have logic
related to viewing data, not for processing inputs. For example, you
can use a foreach block to render a list of objects in a view. But youre
not supposed to use any other kind of logic for processing user input
or controlling application flow.

Controllers: responsible for processing user input, application flow,


etc.
Models: classes that represent the state of the application. In
practical terms, this often means the domain model of an application.
In our application, the Video class we created is part of the
application domain. When we load data from the database, we create
one or more Video objects that represent thestate of the application.
As you see, with this structure, we get a clean separation. Every component
is responsible for one thing.
Earlier, we created our domain model. In this step, were going to create a
Controller and a View.
Right-click the Controllers folder and go to Add > Controller. In the
dialog box, select the first item (MVC 5 Controller Empty).

There are other templates here that automatically generate some code for
us, but in this tutorial I want to teach you how to write all this code by hand
so you have a good understanding of how everything works.
Click Add. Name
this
controllerVideosController and
click Add again. Visual Studio will create a basic empty controller like this:
public class VideosController : Controller
{
// GET: Videos
public ActionResult Index()

{
return View();
}
}

Our VideosController derives from the Controller class. Controller is


part of ASP.NET MVC and encapsulates the basic functionality that every
controller in the application might need.
Here, we have a method called Index which returns an ActionResult. In
ASP.NET MVC, Methods in a controller are referred to as Actions. The job
of an action is to handle a request. So, when an HTTP request comes into
the ASP.NET runtime, it will be routed to an action for processing. This
routing is based on convention, but you can always override it. The
convention determines the name of a controller and an action from the
URL of the request. So, as an example, if the URL of a request
equals /videos/index, it should be handled by a controller
calledVideosController with the Index method (or action). Ill explain
routing in a bit more detail later on.
Here in this method: we need to write code to handle a request for the
URL/videos/index. This means that we need to get the list of videos from
the database and display them in a view. Change the code as follows, and
then Ill explain how everything works:
using System.Linq;
using System.Web.Mvc;
using Beaver.Models;
public class VideosController : Controller
{
private ApplicationDbContext _dbContext;
public VideosController()
{
_dbContext = new ApplicationDbContext();
}
// GET: Videos
public ActionResult Index()
{
var videos = _dbContext.Videos.ToList();
return View(videos);
}
}

Whats going on here? First, I added two using statements on the top to
import the required namespaces.

Next, I declared a private field of type ApplicationDbContext in the


controller and initialized it in the constructor.
In the Index action, we use _dbContext to get the videos from the
database. Remember how earlier we added a DbSet<Video> to
our AppicationDbContext? I told you that this DbSet represented a set
(or a table) in the database. So, here_dbContext.Videos represents the
set of videos. The ToList method is an extension method provided by LINQ.
When we call this method, Entity Framework runs a query on the database
and pulls out all videos from the database. If you need to better understand
LINQ and extension methods, check out my C# Advanced course on
Udemy.
As you see, with Entity Framework, getting data from the database can be
as simple as one line of code. We never have to worry about working with
plain ADO.NET objects such as SQL connections, commands, etc. Our
DbContext takes care of all this complexity.
Finally, in the last line of our Index action, we call the View method and
pass the videos object to it. This method is a helper method that is defined
in the base Controller. It returns an instance of the ViewResult class. By
returning an instance of a ViewResult, we tell ASP.NET MVC runtime to
return a view upon processing this request. In a more complex application,
we dont always return a view from an action. Sometimes we may want to
redirect the user to a new URL, or return a JSON object. This is the reason
the return type of our Index action isActionResult. This is an abstract
class
that
specific
action
results
inherit
from.
For
example, ViewResult, RedirectResult and JsonResult all
inherit
fromActionResult. By using the base class as the return type, this method
can return any of its derivatives. Its common convention to return an
ActionResult from controller actions.
Lets recap: we built a controller with one action that returned a view
populated by the list of videos from the database. But where is the actual
view? Were going to create it now.
Back in the Solution Explorer, expand the Views folder, right-click
the Videos and go to Add > View By convention, since we have a
controller
called Videos, we
should
have
a
folder
here
called Videos, which includes all the views this controller is going to use.
In the Add View dialog, set the view name to Index. Again, here by
convention, since our action is called Index, we can create a view with the
same name. We dont have to follow this convention. We can always create

a view with a different name, but following the convention helps us write
less code to achieve the same thing.
Make sure Use a layout page is ticked and click .

In the new dialog, in the Project folders pane on the left, navigate
to Views
>
Shared.
On
the
right,
select
the
first
item: _Layout.cshtml and click OK. Click Add to finish adding a new
view.

So, what is a layout? Its a template or a master page for all our views. By
using a layout, we can ensure that all views have the same look and feel.
The default ASP.NET MVC project template already has a layout that you
saw when previewing the site. We can always change this layout to
customize it for our own needs.
Lets take a look at the newly generated view:

@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>

In ASP.NET MVC, our views are files with the cshtml extension. Inside
these files we can write both HTML and C# code. To write C# code, you
need to prefix it with @ or @{ } if your code is more than one line. This
syntax is based on what we call Razor Views. So, in ASP.NET MVC we have
a view engine that knows how to parse these views with this special syntax,
and generate raw HTML from our C# code.
Look at the top of this file:

@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}

Here we have a code block indicated by @{ }. The first line specifies the
title of this view. This title is what we see in the browser title bar when we
access this page. The second line specifies the layout file that you selected in
the Add View dialog. So you can always come back here and change the
layout if you want.
Next, we need to display the list of videos in this view. First, we need to add
this line on the very top of the view:
@model IEnumerable<Beaver.Models.Video>

With this line, we tell the view engine that the model behind this view is an
instance of IEnumerable<Video>. What is IEnumerable? Its an
interface used for enumerating a list of objects. Earlier in the controller, we
used the ToList method to get the list of videos from the database:
var videos = _dbContext.Videos.ToList();

Here, this videos object is a List<Video>. A list in C# implements


the IEnumerableinterface, which allows us to iterate the list using the
foreach block. Alternatively, in the view, we could set the model
to List<Video> instead ofIEnumerable<Video>. Is there a difference?
Yes, a tiny one. When you use a concrete class like List<Video>, your model
has to be of that type. But if you use an interface, your model can be of any
type that implements that interface. In this example, if we use
IEnumerable and later we decide to pass an object of a different type to this
view (e.g., a SortedList or Dictionary), everything will continue to work,
because those types implement the IEnumerable interface as well. Hence,
with interfaces, your application will be more loosely coupled and breaks
less as a result of internal changes.
Back to the view: we specified the model passed to the view. Next, change
the heading of the view from:
<h2>Index</h2>

to:

<h2>Videos</h2>

Now, write the following piece of code after the heading:


<ul>
@foreach (var video in Model)
{
<li>@video.Title (@video.Genre)</li>
}
</ul>

Here, were using a UL (unordered list) to display the list of videos.


As you see, the code includes a mix of HTML and C# code, thanks to the
Razor view engine! Note that our C# code is prefixed with @. This tells the
view engine that this is C# code and needs to be executed.
We use a LI (list item) to render each video. Again, in this line, we have a
mix of HTML and C# code. Here we simply display the Title and Genre of
each video. In a more complex application, you can have a complex UL/LI
structure with lots of child elements and display lots of attributes to the
user. But the process is exactly the same as what weve done here. Thus, you
can take this knowledge and apply it to a difference scenario.
Note that as you were typing:
@video.Title

IntelliSense showed you the properties of the video object when you used
the dot notation. This is because we set the model of this view at the top of
the view. If you didnt do that, IntelliSense wouldnt work, and in some
cases you would even get a runtime exception.
Thats all you had to do to get the list of videos from the database and show
them to the user. We created a controller and wrote a couple of lines of code
in the Index action, then created a view and used a foreach block to display
videos.
Lets run the application and see the result. Press Ctrl+F5 to run the
application.
Your
browser
will
launch
and
navigate
to /Videos/Index. This is because you pressed Ctrl+F5 when you were
viewing the Index view in the Videos folder.

Look at the content of the page. You see the list of videos. So we
successfully built the first feature of our application. In the next section,
well implement the ability to add a new video to the database.

Adding a New Video


In this section, youre going to learn how to create a data entry form and
save data to the database using Entity Framework. We will be building a
form for adding a new video to the database.

Im going to break this section into two steps:


Creating a page to add a video
Saving the video to the database
Step 1: Creating a Page to Add a Video
Before we get started, lets take a closer look at routing.
Earlier I told you that the routing engine determines the name of the
controller and the action from the URL of the request. The default rule (or
the
default
convention)
targets
a
URL
with
the
pattern /controller/action/id. Here bothaction and id are
optional.
If action is not specified, Index is assumed as the action name. Take a
look at the following table for a few examples:
URL

Controller

Action

/videos

VideosController

Index()

/videos/index

VideosController

Index()

/videos/new

VideosController

New()

/videos/edit/1

VideosController

Edit(int id)

For the purpose of this section, we need a new page for the user to add a
new video. To do this, were going to create a new action that responds to a
URL like/videos/new. Inside this action, well return a view which will
include a data entry form for adding a video.
First, go to VideosController and create a new action like this:
public ActionResult New()
{
return View();
}

All we do here is simply return a view. Lets create the corresponding view.
In
Solution
Explorer,
expand
the Views folder,
right-click
the Videos folder, and go to Add > View. Set the name of the view
to New and make sure _Layout.cshtmlis selected as the layout (similar
to the last section).

Next, set the model behind this view on the top:


@model Beaver.Models.Video

We set the model to the Video because were going to capture a Video
object in this form.
Now, write the following code in the view to create an HTML form element:
@using (Html.BeginForm("Add", "Videos", FormMethod.Post, new { @class
= "form" }))
{
}

Here we are using Razor syntax (note the @) to write C#


code. Html.BeginForm is a helper method, which we use to render an
HTML form element. It returns an instance of MvcForm, which is a
disposable object. By wrapping it inside a usingblock, we can ensure that it
will be properly disposed.
The first and second arguments specify the name of the action and
controller that will be called when we post this form. In this case, we expect

an action named Addin our VideosController to be called. We havent


created this action yet, but well do so soon.
The third argument specifies the form method. In HTML forms, we have
two methods: GET and POST. When sending data for modification to the
server, we should always use the POST method.
The last argument is an anonymous object ( new {} ) that specifies any
additional attributes to add to the HTML markup. So, when this code is
executed, the view engine will render something like this:
<form action=/videos/add method=post class=form>
</form>

We use the form CSS class to give a nice, modern look to our forms. This
CSS class is defined in Bootstrap, which is a CSS framework for building
modern and responsive (mobile- and tablet-friendly) web applications.
When you create an ASP.NET MVC project in Visual Studio, Bootstrap is
automatically added for you.
We added the form. Now, we need to add three input fields in this form:
Title, Description and Genre. Write this code inside the using block:
<div class="form-group">
@Html.LabelFor(m => m.Title)
@Html.TextBoxFor(m => m.Title, new { @class = "formcontrol" })
</div>
<div class="form-group">
@Html.LabelFor(m => m.Description)
@Html.TextAreaFor(m => m.Description, new { @class = "formcontrol", rows = 4 })
</div>
<div class="form-group">
@Html.LabelFor(m => m.Genre)
@Html.EnumDropDownListFor(m => m.Genre, new { @class = "formcontrol" })
</div>

Here we have three sections, each wrapped with a div with a formgroup class.Again, this is one of the classes that is defined in Bootstrap. If
you follow Botostraps markup, you always get a nice, clean form that
renders well both on the desktop and on mobile devices.
Inside each form-group, we have a label and an input field. Look at the
first form-group.

<div class="form-group">
@Html.LabelFor(m => m.Title)
@Html.TextBoxFor(m => m.Title, new { @class = "form-control" })
</div>

Were using Html.LabelFor to render a label for the Title property of


the Videoclass.
@Html.LabelFor(m => m.Title)

The expression m => m.Title is a lambda expression that we use to access


a property in the model of this view. If youre not familiar with lambda
expressions, check out my C# Advanced course on Udemy. When this line is
executed by the view engine, well get an HTML markup like this:
<label for=Title>Title</label>

Next, we use Html.TextBoxFor helper method to render a text box.


@Html.TextBoxFor(m => m.Title, new { @class = "form-control" })

Again, we use a lambda expression to specify the target property. Also, note
that the second argument to this method is an anonymous object that
specifies any additional attributes to add to the markup, in this case formcontrol CSS class. This is another Bootstrap class that gives our text boxes
a bit of padding, round corners and a nice effect when the input is in focus.
The result will be HTML markup like this:
<input
type=text
control></input>

id=Title

name=Title

class=form-

Now you read the second form-group.


<div class="form-group">
@Html.LabelFor(m => m.Description)
@Html.TextAreaFor(m => m.Description, new { @class = "formcontrol", rows = 4 })
</div>

Its very similar to the first one, except that here we use
the Html.TextAreaForhelper method to render a textarea input element

instead of a text box. This allows the user to write a description that is more
than one line.
And finally, in the third form-group, we use a different helper method
(Html.EnumDropDownListFor) to render a drop-down list for the
Genre property, which is an enum:
<div class="form-group">
@Html.LabelFor(m => m.Genre)
@Html.EnumDropDownListFor(m => m.Genre, new { @class = "formcontrol" })
</div>

For the last step, we need a button to submit the form. Add this markup
inside theusing block, after all form groups:
<input type="submit" class="btn btn-primary" value="Save" />

Here, btn and btn-primary are both Bootstrap classes that make our
buttons look cool and modern.
Your entire using block should look like this:
@using (Html.BeginForm("Add", "Videos", FormMethod.Post, new { @class
= "form" }))
{
<div class="form-group">
@Html.LabelFor(m => m.Title)
@Html.TextBoxFor(m => m.Title, new { @class = "formcontrol" })
</div>
<div class="form-group">
@Html.LabelFor(m => m.Description)
@Html.TextAreaFor(m => m.Description, new { @class = "formcontrol", rows = 4 })
</div>
<div class="form-group">
@Html.LabelFor(m => m.Genre)
@Html.EnumDropDownListFor(m => m.Genre, new { @class = "formcontrol" })
</div>
<input type="submit" class="btn btn-primary" value="Save" />
}

Now its time to review what we have done. Run the application with
Ctrl+F5 and look at the form weve built:

Note how the input fields and the button look. This is all because of the
beautiful styles defined in Bootstrap.
In this step, we added a new action to our controller that returned a view.
We created a view with a form to add a video. In the next step, were going
to save this video to the database.

Step 2: Saving the Video to the Database


Earlier in the last step, we defined a form with the following code:
using (Html.BeginForm("Add", "Videos", FormMethod.Post, new { @class
= "form" }))
{
}

As I explained before, when this form is posted, the Add action in


the Videoscontroller will be executed. So in this step, were going to
implement this action.
Open up VideosController and create a new action as follows:
public ActionResult Add(Video video)
{
_dbContext.Videos.Add(video);
_dbContext.SaveChanges();
return RedirectToAction("Index");
}

This action takes a Video object populated with the values that the user
enters into the form.
The first line adds the Video object to our DbSet. Remember DbSet? Its a
collection of objects in memory that is tracked by Entity Framework. When
we add an object to this collection, nothing is saved to the database yet.
Everything is in memory. When we call _dbContext.SaveChanges(),
Entity Framework will look at all the changed objects in memory and will
automatically run the right SQL statements to update the database.
In the last line, we are using the RedirectToAction helper method to
redirect the user to the Index action. This means that once the video is
saved, the user will be redirected to /videos/index where they will see the
list of all videos in the database. The RedirectToAction method returns
a RedirectToRouteResult which derives from ActionResult. So, by
using ActionResult as the return type of our actions, we can return an
instance of any classes that derive from ActionResult. So far, youve
seen RedirectToRouteResult and ViewResult. There are a few other
ActionResults which are beyond the scope of this tutorial.
Its time to test our application. Run the application with Ctrl+F5 and in the
browser, change the URL to go to /videos/new.

Fill out the form, and click the Save button. The new video should appear in
the list.
Before we finish this step, it would be nice to add a link to the Add Video
page in the list of videos. Open up Views > Videos > Index and type the
highlighted code:
<h2>Videos</h2>
<p>
@Html.ActionLink("Add Video", "New")
</p>
<ul>
@foreach (var video in Model)
{
<li>@video.Title (@video.Genre)</li>
}
</ul>

Here, Html.ActionLink is yet another helper method that we use to


generate hyperlinks. The first argument is the text for the link, and the
second argument is the name of the target action. We could optionally
supply a third argument that would be the name of the controller, but in
this case because were in a view for the Videos controller, its not
necessary. Itll be assumed by convention.
Now, you might ask, Why do we use these helper methods to generate
HTML markup? Why dont we just use raw HTML elements? We can use
raw HTML, but the benefit of using these helper methods is that they are
aware of routing configuration. In this case, when we tell this method to
render a link for the New action, it will generate a link that points
to /videos/new. If you override the default routing and map your New
action to another route (eg /videos/create), this code will continue to
work. It will generate a link to /videos/create.However, if we used a raw
HTML anchor element (e.g., <a href=/videos/new>), the link will break
because we no longer have an action that responds to/videos/new. So, we
prefer to use helper methods to generate HTML markup.
Run the application again, and you should see the link.

Next, lets add the ability to edit existing videos.

Editing an Existing Video


In this section, youre going to learn how to use partial views in ASP.NET
MVC (for promoting re-usability) and how to update data using the Entity
Framework.

Similar to the last section, were going to implement this feature in two
steps. First, were going to add a link in front of each video that would take
us to a page populated with the video details. Next, well implement
updating the video in the database.
Step 1: Creating a Page Populated with Video Details
In this step, were going to add an edit link in front of each video. The link
should take us to a URL like /videos/edit/{id} where {id} is the ID of the
video.
Open up Index view inside Views > Videos and change the <li> as
follows:
<li>@video.Title (@video.Genre) @Html.ActionLink("Edit", "Edit", new
{ id = video.Id })</li>

Again, here were using the ActionLink helper method you saw in the last
step. The first argument is the label for the link, the second argument is the
target action, and the third argument is an anonymous object used to
supply additional parameters to the route. In this case, were passing the ID
of each video. With this, ActionLink will return markup like:
<a href=/videos/edit/1>Edit</a>

When the user clicks on this link, we need to take them to a page with a
form populated with the video details. We need an action to handle this
request. Inside this action, were going to fetch the video with the given ID
from the database, and put it on the view. Create a new action in
the VideosController as follows:
public ActionResult Edit(int id)
{
var video = _dbContext.Videos.SingleOrDefault(v => v.Id == id);
if (video == null)
return HttpNotFound();
return View(video);
}

In the first line, were using our DbSet (_dbContext.Videos) but this
time, instead of using the ToList method (to get all videos), we
use SingleOrDefault. Both of these methods are LINQ extension
methods. If youre not familiar with LINQ, checkout my C# Advanced

course. With this method, we get a single object from the database. Default
means that if no object matching the criteria is found, null is returned. Note
that the argument to this method is a lambda expression that specifies the
criteria.
If the video is not found, we call the HttpNotFound method and return its
value.
if (video == null)
return HttpNotFound();

This
method
returns HttpNotFoundResult which
is
yet
another ActionResult.With this line, the user will automatically be
redirected to a standard Page Not Found page in your application.
Finally, if the video is found, we return a view and populate it with the
video object:
return View(video);

Now, lets go ahead and create this view. Inside the Views folder, rightclickVideos and go to Add > View Set the name of this view
to Edit and ensure that the layout is selected.
We want to display a form to edit a video. This form looks identical to the
form we created earlier for adding a video. Following the DRY principle
(Dont Repeat Yourself) of software engineering, lets refactor our existing
code and prevent code duplication.
Right-click the Videos folder again, and go to Add > View Set the name
of this view to _VideoForm (note the underscore) and make sure to
tick Create as a partial view.

When you tick this option, the layout checkbox becomes disabled. A partial
view is like a small view that we can reuse in many views. It doesnt have a
layout, so its not a full view. In this case, were going to extract our video
form and put it in this partial view so we can reuse it in both the add and
edit views.
Open up New.cshtml. Select all the markup inside the using block
(excluding the using block), and then cut and paste it
into _VideoForm.cshtml. This is the markup you need to move to the
partial view:
<div class="form-group">
@Html.LabelFor(m => m.Title)
@Html.TextBoxFor(m => m.Title, new { @class = "form-control" })
</div>
<div class="form-group">
@Html.LabelFor(m => m.Description)
@Html.TextAreaFor(m => m.Description, new { @class = "formcontrol", rows = 4 })
</div>
<div class="form-group">
@Html.LabelFor(m => m.Genre)
@Html.EnumDropDownListFor(m => m.Genre, new { @class = "formcontrol" })
</div>
<input type="submit" class="btn btn-primary" value="Save" />

Make sure to set the model for this partial view at the top of the view:
@model Beaver.Models.Video

Back to New.cshtml, change the using block as follows:


@using (Html.BeginForm("Add", "Videos", FormMethod.Post, new { @class
= "form" }))
{
Html.RenderPartial("_VideoForm");
}

Here were using RenderPartial helper method to include the markup in


another view, in this case _VideoForm. Note that by convention, partials
are prefixed with an underscore.
Also, note that the call to RenderPartial is terminated by a semicolon
because unlike the other helper methods youve seen so far (e.g.,
Html.LabelFor, Html.TextBoxFor), this method directly writes markup to
the
response,
whereas
the
other
helper
methods
return
an MvcHtmlString which is then converted to a string by the view engine.
Now were going to reuse this partial view in our Edit Video page. Copy the
entire using block in New.cshtml and paste it into Edit.cshtml. Then
change the action name from Add to Update. Your Edit.cshtml should
look like this:
using (Html.BeginForm("Update", "Videos", FormMethod.Post, new
{ @class = "form" }))
{
Html.RenderPartial("_VideoForm");
}

Run the application with Ctrl+F5. Youll see a runtime error because Visual
Studio redirects you to /videos/edit without specifying the ID of the video
to edit. Change the address in the browser and navigate to /videos to see
the list of videos. Click the edit link in front of one of the videos. Youll be
redirected to the edit form populated with the video you selected.
In the next step, were going to save the changes to the database.
Step 2: Updating a Video in the Database

In the last step, when we created our Edit view, we set the target action
toUpdate. In this step, we need to implement this action to update the
video. Add a new action to VideosController as follows:
[HttpPost]
public ActionResult Update(Video video)
{
var videoInDb = _dbContext.Videos.SingleOrDefault(v => v.Id ==
video.Id);
if (videoInDb == null)
return HttpNotFound();
videoInDb.Title = video.Title;
videoInDb.Description = video.Description;
videoInDb.Genre = video.Genre;
_dbContext.SaveChanges();
return RedirectToAction("Index");
}

The code should be very familiar, except for a few minor differences.
First, Ive decorated this action with the [HttpPost] attribute. This tells
the MVC runtime that this action can only be called when there is an HTTP
POST request.

Beginners question: What is HTTP POST, and why/when should we use


it? HTTP requests have different verbs, and each verb has a different
meaning. We have GET (for reading data), POST and PUT (for
inserting/updating data), and DELETE for deleting data. As a best practice,
whenever youre changing data in ASP.NET MVC, you need to mark your
actions as HttpPost. If you dont do this, it is possible that when a search
engine spider (like Google) is crawling your website, it modifies or deletes
your data without you being aware of that. Because these spiders use HTTP
GET to navigate to different parts of your website, when you use HTTP
POST, youre preventing a simple HTTP GET from modifying/deleting data
in
your
database.

Back to our action: in the first line, we get the video with the given ID from
the database.

var videoInDb
video.Id);

_dbContext.Videos.SingleOrDefault(v

=>

v.Id

==

Note that I named this variable videoInDb to distinguish it from the video
object passed as a result of posting the form.
Next, we check to see if the video was found or not, just like before.
if (videoInDb == null)
return HttpNotFound();

Then
we
update
the Title,
Description and Genre properties
of videoInDb and call_dbContext.SaveChanges() to update the
database.
videoInDb.Title = video.Title;
videoInDb.Description = video.Description;
videoInDb.Genre = video.Genre;
_dbContext.SaveChanges();

DbContext will issue an UPDATE SQL statement based on the properties


we have updated. Finally, we redirect the user to the list of videos.
return RedirectToAction("Index");

Lets run the application and see if everything is working. Navigate


to /videos, andclick the Edit in front of the first video. Make some
changes, and click the Save button. Youll be redirected to the 404 Not
Found page. Why is that? This is one of those issues that you may
encounter when you forget to add a hidden field in your form. Lets go back
to our action and see why exactly this happened:
var videoInDb
video.Id);

_dbContext.Videos.SingleOrDefault(v

=>

v.Id

==

If you run the application in the debug mode and put a breakpoint here,
youll see that the value of video.Id is 0. Thus, the request that is sent to
the server does not have a value for the ID of the video. It only includes
values for Title, Descriptionand Genre, which come from the input

fields on the form. To send the value of Video.ID, we need to add a hidden
field.
Open up _VideoForm.cshtml and add a hidden field before the Save
button:
@Html.HiddenFor(m => m.Id)
<input type="submit" class="btn btn-primary" value="Save" />

You can add this hidden field anywhere here, but my personal convention is
to add them before the submit button. This way, I always know where to
look when Im looking for hidden fields.
Run the application again, try to edit a video, make a few changes, and save.
Everything should work.
Next, well add the ability to delete a video.

Deleting a Video
In this section, youll learn how to delete data in the database using the
Entity Framework.
Again, were going to implement this feature in two steps: first, were going
to add a Delete link in front of each video in the video list. When the user
clicks this link, theyll see a page with the details of the video to delete. This
is the delete confirmation page. Next, well be focusing on actually deleting
the video from the database.
Step 1: Creating a Page to Confirm Deletion
This step is very similar to what weve done before. Add a Delete link in
front of each video in the list. When this link is clicked, display a view with
the details of the video to delete. Use a UL/LI to display different attributes
of a video. Dont worry about deleting the video from the database yet. After
trying this, take a look at my solution:
First, we need to add the Delete link in front of each video. So open
upIndex.cshtml in Views > Videos, and change the LI as follows:
<li>
@video.Title (@video.Genre)
@Html.ActionLink("Edit", "Edit", new {id = video.Id}) |
@Html.ActionLink("Delete", "Delete", new {id = video.Id})
</li>

Note that I added a vertical separator between Edit and Delete to separate
them.
Next, we should create a new action in the VideosController as follows:
public ActionResult Delete(int id)
{
var video = _dbContext.Videos.SingleOrDefault(v => v.Id == id);
if (video == null)
return HttpNotFound();
return View(video);
}

Nothing should be new to you at this point. Were just pulling out the video
to show to the user before deleting it.
Now, lets create the corresponding view. Add a new view
called Delete insideViews > Videos. Make sure its not a partial view and
has a layout. Write the following code inside the view.
@model Beaver.Models.Video
@{
ViewBag.Title = "Delete";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Delete</h2>
<p>
Are you sure you would like to delete this video?
</p>
<ul>
<li>Title: @Model.Title</li>
<li>Description: @Model.Description</li>
</ul>

Here I am using a simple UL/LI to display the attributes of the video. You
can use anything to lay out the details of a video. It doesnt really matter
from the perspective of learning ASP.NET MVC.
Next, write this code in the view:
@using (Html.BeginForm("DoDelete", "Videos", FormMethod.Post))
{
@Html.HiddenFor(m => m.Id)

<input type="submit" class="btn btn-danger" value="Yes, Delete


it!" />
@Html.ActionLink("No, back to videos", "Index")
}

You might wonder why Im using Html.BeginForm when we dont really


have a data entry form here. The reason is that we need to call the Delete
action using HTTP POST method. Again, anytime we need to modify data
in ASP.NET MVC, we should use HTTP POST to prevent accidental data
modification. In ASP.NET MVC, the only way to use HTTP POST is by
creating a form. In this example, our form only has a submit button and no
input fields.
Note that in this form, we also have a hidden field to render the ID of the
video in our markup.
@Html.HiddenFor(m => m.Id)

This way, when we post to the server, well have the ID of the video to
delete.
Ive used the btn-danger Bootstrap class to make our delete button red.
<input type="submit" class="btn btn-danger" value="Yes, Delete it!"
/>

Now, run the application. Youll see a delete link in front of each video.
Click one of them. Look at the new page we just built.

Click No, back to the videos. So, we have a nice navigation between
these two pages. The only thing remaining is to actually delete a video from
the database. Thats what were going to do in the next step.
Step 2: Deleting a Video from the Database
The form we created in the last step posts to an action named DoDelete.

@using (Html.BeginForm("DoDelete", "Videos", FormMethod.Post))

Lets go to VideosController and create this action:


[HttpPost]
public ActionResult DoDelete(int id)
{
var video = _dbContext.Videos.SingleOrDefault(v => v.Id == id);
if (video == null)
return HttpNotFound();
_dbContext.Videos.Remove(video);
_dbContext.SaveChanges();
return RedirectToAction("Index");
}

Again, the code should look very familiar to you. Ill just highlight the
important aspects.
Ive decorated this action with [HttpPost] to make sure an HTTP GET
caused by a web crawler will not delete our records.
Inside the method, first we need to read the video from the database and
then call the Remove method of our DbSet. This is how you ask Entity
Framework to delete records in the database. You cannot directly delete a
record in the database. You should always read that record first, remove it
from the memory and then callSaveChanges. This way, Entity
Frameworks change tracker will realize that an object is deleted and will
issue a DELETE FROM SQL statement to the database.
Lets run the application and test the delete functionality. Delete one of the
videos.

Review
If you made it this far, well done. I hope youve enjoyed this tutorial and
learned the basics of ASP.NET MVC.
Lets quickly review what youve learned and what the next step is. In this
tutorial,
You learned and used the core building blocks of ASP.NET MVC
(Models, Views and Controllers).
You created a model using the Entity Framework Code First
workflow.

You used Code First migrations to generate your database.


You built a controller with different actions for viewing lists of videos,
adding a new video, and editing and deleting an existing one.
You learned about the routing engine in ASP.NET MVC and how
URLs get mapped to controllers and actions.
You used Razor syntax to mix HTML and C# code in your views.
You refactored your code by extracting the reusable view code into a
partial view.
You learned about the difference between HTTP GET and HTTP
POST, and now youre able to build more reliable applications.
You used many HTML helper methods in views such as ActionLink,
LabelFor, TextBoxFor, TextAreaFor and BeginForm.
You used many helper methods in actions such as View,
RedirectToAction and HttpNotFound.
Whats next? ASP.NET MVC is more than what youve read, and thats why
Im planning to create a comprehensive course to teach you lots of things
you can do with ASP.NET MVC. In particular, Ill be teaching you:

Authentication and authorization


Prevention of common security attacks
Data validation
Caching
Real-time connections
Working with Javascript libraries
Ajax
Creating RESTful services with ASP.NET Web API

And more
If you enjoyed my teaching style and would like to learn more from
me, subscribe to my newsletter. Ill send out an announcement once my
course is ready.

You might also like