Professional Documents
Culture Documents
com/a-step-by-step-asp-net-tutorial-for-beginners/
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
Step
1:
Creating
a
Page
to
Confirm
Step 2: Deleting a Video from the Database
Deletion
Review
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.
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.
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.
public
public
public
public
}
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)
{
}
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"
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:
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);
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.
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();
}
}
Whats going on here? First, I added two using statements on the top to
import the required namespaces.
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();
to:
<h2>Videos</h2>
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.
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).
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" }))
{
}
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>
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-
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.
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>
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
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.
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.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)
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.
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.
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.