Introduction
This
article is about the creating of a basic ASP.NET MVC 4 Web
Application that has the task of keeping track of incoming documents. For
the creation of the project the Code First approach is used so we
write the needed Classes and from them create the database. After
the creation of the Database we create the Controllers and Views we
need and wire them up to get a working Web Application were we can
Create,Read,Edit, and Delete records.
This
article consists out of 5 parts:
Creating the basic ASP.NET MVC Web Application
Creating
the Classes
Creating
the Database
Creating
the Controllers and Views
Background
This article is not going to talk about the MVC Model itself or how the Controllers work and so on because a lot is written about that already in other articles. The main goal I have with this article is to show someone who starts with programming to go from nothing to a fully working Web Application with Dynamic data. With Dynamic data I mean that no static lists will be in the HTML code, all data in the lists will come from the database and can be changed if needed.
When this sample is finished it's far from ready because I didn't pay attention to the validation of the data a user enters and so on so it' a rough working model that's ready for the next phase.
That next phase will be changing the look and feel and adding functionality. At the moment I am writing the next addition to the article that I will publish as a separate article that builds further on the code. At the end it will be similar to the version I use myself at home to keep track of the incoming standard mail that is scanned by a standard document scanner and is uploaded to this webite. The Document_uri string in the Document.cs Class in this article is used to link the scanned document and wen clicked present that .PDF in the browser. The end result will be a handy application were documents otherwise is maps are quickly found when needed.
Using the code
I have build this sample in Visual Studio 2012 Professional and after that tested in Visual Studio 2013 Ultimate 90 day's trial version to see if it works as it does so you can use that version also.
Important: Make sure that EntityFramework is installed. To find out click on the created project in the Solution Explorer and go to Manage NuGet Packages... en select the All View in the next Screen, if it's not in the list go to the Online option at the left and you get a list of available packages, select EntityFramework and Click on Install, a reference will be added in your project.
Download Code (MvcDocuments Sample)
Click on the MvcDocuments Sample in OneDrive and select download:
1.Creating
the basic ASP.NET MVC Web Application
The
first step in this project is the creation of the skeleton we are
going to use and we start with the New Project option from the Visual
Studio 2012 menu.
We get the following screen were we select the ASP.NET MVC 4 Web Application in Visual C# ,to get this option select the Web option as shown below ,give the application MVCDocuments as name and then Click on the OK button.
In the next screen we select the Internet Application option and we make sure that as View engine: Razor is selected and again we click on the OK button.
The project skeleton is created and we go to Solution Explorer under the VIEW menu option.
In the Solution Explorer we see the MvcDocuments project and when we open the Models folder. We see that one Model is already there, the AccountModels.cs file that takes care of the Registering and Login process of the Web Application.
At this moment we are not interested in that AccountModels.cs file, first we start Debugging the Web application to see if it works.
If everything is OK we will get the following screen in the Web Browser , as you can see we have a Register and a Login Button at the right top of the screen and a Home , About and Contact button just below them.
Let's test the Register option first and create a User name and Password.
If everything is OK you see that Hello and your User name has replaced the Register Button and the Login Button is replaced by a Log off option.
The just created application works but under the hood happened something else, a database with the name: aspnet-MvcDocuments-20140404125332.mdf is created (the digits are the year and time of creation), there is also a similar named Log file. You can find both files in your projects APP_Data folder when you Right Click on that and Select “Open Folder in File Explorer”
Note: You can view the database also with your Server Explorer that you can find under the VIEW menu option.
2.Creating the Classes
We have created the basic skeleton for our application. The next step is writing the Classes we need. We want the Classes in the Models folder so go to the Solution we Right Click on that folder and select the Menu Option Add and select Class from the options. Make sure you select the Visual C# Class and name it : Company.cs
I now could give you a lot of screens but instead of that I give you the code for the Classes you have to create. All Classes together will later on create the Context of the Documents part of this sample application.
All the Classes belong in the Models folder. Notice that sometimes - while writing the code -referenced Classes do not exist at that moment so a red wave will be visible under those parts in the code, just ignore that for the moment.
1.The Company.cs Class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcDocuments.Models
{
public class Company
{
public int CompanyId { get; set; }
public string Company_name { get; set; }
public string Address { get; set; }
public string Postal_Code { get; set; }
public string City { get; set; }
public int StateId { get; set; }
public virtual State State { get; set; }
public int CountryId { get; set; }
public virtual Country Country { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
public string Website_Uri { get; set; }
public virtual List<Contact> Contacts { get; set; }
public virtual List<Document> Documents { get; set; }
}
}
2.The Contact.cs Class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcDocuments.Models
{
public class Contact
{
public int ContactId { get; set; }
public int CompanyId { get; set; }
public virtual Company Company { get; set; }
public int FunctionId { get; set; }
public virtual Function Function { get; set; }
public int TitleId { get; set; }
public virtual Title Title { get; set; }
public string Surname { get; set; }
public string Last_name { get; set; }
public string Email_address { get; set; }
public string Phone { get; set; }
public string Cellphone { get; set; }
}
}
3.The Costs_group.cs Class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcDocuments.Models
{
public class Costs_group
{
public int Costs_groupId { get; set; }
public string Cost_group_name { get; set; }
}
}
4.The Country.cs Class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcDocuments.Models
{
public class Country
{
public int CountryId { get; set; }
public string Country_name { get; set; }
}
}
5.The Document.cs Class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcDocuments.Models
{
public class Document
{
public int DocumentId { get; set; }
public DateTime Document_date { get; set; }
public int CompanyId { get; set; }
public virtual Company Company { get; set; }
public int Mail_categoryID { get; set; }
public virtual Mail_category Mail_category { get; set; }
public int Costs_groupId { get; set; }
public virtual Costs_group Costs_group { get; set; }
public int Payment_statusId { get; set; }
public virtual Payment_status Payment_status { get; set; }
public string Reference { get; set; }
public string Note { get; set; }
public double AmoutExVat { get; set; }
public double Vat { get; set; }
public double Amount { get; set; }
public string Document_uri { get; set; }
}
}
6.The Function.cs Class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcDocuments.Models
{
public class Function
{
public int FunctionId { get; set; }
public string Function_name { get; set; }
}
}
7.The Mail_category.cs Class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcDocuments.Models
{
public class Mail_category
{
public int Mail_categoryId { get; set; }
public string Mail_category_name { get; set; }
}
}
8.The Payment_status.cs Class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcDocuments.Models
{
public class Payment_status
{
public int Payment_statusId { get; set; }
public string Payment_status_name { get; set; }
}
}
9.The State.cs Class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcDocuments.Models
{
public class State
{
public int StateId { get; set; }
public string State_name { get; set; }
}
}
10.The Title.cs Class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcDocuments.Models
{
public class Title
{
public int TitleId { get; set; }
public string Title_name { get; set; }
}
}
11.The MvcDocumentsContext.cs Class:
All the Above created Classes will form together the so called Context of our application. There is one more Class we need to create in the Models folder and that is the Context Class. We call this Class: MvcDocumentsContext.cs , the code for that Class is:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
namespace MvcDocuments.Models
{
public class MvcDocumentsContext : DbContext
{
public DbSet<Company> Companies { get; set; }
public DbSet<Contact> Contacts { get; set; }
public DbSet<Costs_group> Costs_groups { get; set; }
public DbSet<Country> Countries { get; set; }
public DbSet<Document> Documents { get; set; }
public DbSet<Function> Functions { get; set; }
public DbSet<Mail_category> Mail_categories { get; set; }
public DbSet<Payment_status> Payment_statusses { get; set; }
public DbSet<State> States { get; set; }
public DbSet<Title> Titles { get; set; }
}
}
As you can see one using is added below
using System.Web;
We have added the using System.Data.Entity
to it
Notice also the following line in the code above:
public class MvcDocumentsContext : DbContext
The : DbContext
is new also.
OK I think we are done regarding the creation of the Classes and the needed Context so we can close the Models folder and move on to our next step. Our next step will be the creation of the Database based on our MvcDocumentsContext.cs and the Classes we just wrote.
3.Creating the Database
In this part we are going to create the Database based on the Classes we have written in the previous part. The first thing we are going to do is adding a line in the Webconfig file. You can find that file at the bottom in the Solution Explorer. Open this file and look for this part where it say's: <connectionString>...</connectionStrings>
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-MvcDocuments-20140405094433;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-MvcDocuments-20140405094433.mdf" providerName="System.Data.SqlClient" />
</connectionStrings>
Please add the following line of code:
<add name="MvcDocumentsContext" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-MyDocuments;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-MyDocuments.mdf" providerName="System.Data.SqlClient" />
When done your code should look like this:
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-MvcDocuments-20140405094433;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-MvcDocuments-20140405094433.mdf" providerName="System.Data.SqlClient" />
<add name="MvcDocumentsContext" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-MyDocuments;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-MyDocuments.mdf" providerName="System.Data.SqlClient" />
</connectionStrings>
Be aware that the digits in the first line can vary and don't replace your own code with the code above since your Database won't work in that case). When you are done it's a good idea to rebuild the solution (BUILD menu and Rebuild Solution option).
The next step is creating the Database , we have added a Connection String to work with and we are going to use the Package Manager Console Tool in Visual Studio. You can find this under the TOOLS menu, look for the NuGet Package Manager and select that and click on the Package Manager Console to open it.
Each package is licensed to you by its owner. Microsoft is not responsible for, nor does it grant any licenses to, third-party packages. Some packages may include dependencies which are governed by additional licenses. Follow the package source (feed) URL to determine any dependencies.
Package Manager Console Host Version 2.8.50126.400
Type 'get-help NuGet' to see all available NuGet commands.
PM>
You see some license information and PM> , after that you type the following line:
PM> Enable-Migrations -contexttypename MvcDocuments.Models.MvcDocumentsContext
And you hit the Enter key on you keyboard. If everything is OK you get the following text in the Console:
PM> Enable-Migrations -contexttypename MvcDocuments.Models.MvcDocumentsContext
Checking if the context targets an existing database...
Code First Migrations enabled for project MvcDocuments.
But you wont notice that because a new folder is created in your project with the name Migrations and a File called Configuration.cs also, that's the screen you are looking at:
In the following part of the Configuration.cs code the AutomaticMigrationsEnabled
is default set to = false; , you have to set it to = true; as shown below:
namespace MvcDocuments.Migrations
{
using System;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;
internal sealed class Configuration : DbMigrationsConfiguration<MvcDocuments.Models.MvcDocumentsContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
}
protected override void Seed(MvcDocuments.Models.MvcDocumentsContext context)
{
Now Rebuild your Solution (Menu option BUILD/Rebuild Solution) and go to the Package Manager Console again and type:
PM> Add-Migration “DocumentsDatabaseCreation”
After hitting your Enter key a new Migrations file will be created in your Migrations folder (Digits will be different). Again you won't notice that because the configuration file just created will be visible but go back to the Console and type:
PM> Update-Database
After hitting the Enter key again the Database will be created:
PM> Update-Database
Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
Applying code-based migrations: [201404050752573_DocumentsDatabaseCreation].
Applying code-based migration: 201404050752573_DocumentsDatabaseCreation.
Running Seed method.
PM>
To see if that really happened have a look at your Server Explorer under the VIEW menu in Visual Studio:
As you can see the Database is created and that was the goal of this Part next we are going to create the Controllers and Views and wire things up so we get a working application.
4.Creating the Controllers and Views
In the previous parts we created the MVCDocuments solution skeleton, wrote the Classes and created the Database. In this part we are going to create the Controllers and Views for this application and we are going to wire things up so we get a working Application.
We start with the Controllers folder (two files are already there) and we Right Click on that folder and Select the Add Controller option:
We are going to Add the Controllers for all the Classes we have created so let's start with the Company.cs
Class we have created and name the Controller as shown above: CompanyController
.
Make sure that as the Model class: Company(MvcDocuments.Models)
is selected and that as the Data context class: MvcDocumentsContext (MvcDocuments.Models)
is selected as shown in the picture above.
Make also sure that under Scaffolding options: Mvc controller with read/write actions and views, using Entity Framework
is selected!
As I said you need to create a Controller per Class , so after you click on Add for the creation of the Company Controller you do the same for all of them except for the MvcDocumentsContext.cs
Class.
When you are done with creating the Controllers you will have noticed that automatically Views were created during the creation of the Controllers as you can see in the image above just after the creation of the Company Controller.
If everything went well almost all needed Views were created and our next step will be wiring them up so views will be visible and functioning in our Web Browser when we Debug our application.
Create a new Controller and call this one: ListController
, under Scaffolding options select the Empty MVC controller
and click on the Add button.
You will see the following code on your screen:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcDocuments.Controllers
{
public class ListController : Controller
{
public ActionResult Index()
{
return View();
}
}
}
This controller Class will redirect requests for the List page, Put your cursor at the right side of the return View();
so next to the Comma and Right Click there and select: The Add View... menu option.
In the screen that follows just make sure the default Index is set as the name and leave the res as it is.
A new View folder with the name: List will be created and inside that folder the Index.cshtml file is created and if everything is OK you are presented with it's contents on your screen. We are going to make some changes to this part so I looks like this:
@{
ViewBag.Title = "Lists";
}
<h2>Lists</h2>
<li>@Html.ActionLink("Costs Group", "Index", "Costs_group")</li>
<li>@Html.ActionLink("Country", "Index", "Country")</li>
<li>@Html.ActionLink("Function", "Index", "Function")</li>
<li>@Html.ActionLink("Mail Category", "Index", "Mail_category")</li>
<li>@Html.ActionLink("Payment Status", "Index", "Payment_status")</li>
<li>@Html.ActionLink("State", "Index", "State")</li>
<li>@Html.ActionLink("Title", "Index", "Title")</li>
This will present links to the named pages when the Lists Index.cshtml
page is requested.
The next thing we are going to do is we are going to find the Shared folder in our Views folder and open the _Layout.cshtml
file, and we are going to look for the following part in that:
<ul id="menu">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
The above shown part is shown as Navigation Buttons in the Web Page and you have seen them with the first Debugging session in the beginning.
We are going to change the above shown .cshtml code to this:
<ul id="menu">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("Contacts", "Index", "Contact")</li>
<li>@Html.ActionLink("Companies", "Index", "Company")</li>
<li>@Html.ActionLink("Documents", "Index", "Document")</li>
<li>@Html.ActionLink("List", "Index", "List")</li>
</ul>
As you can see only the “Home” link is kept and we added links to our Contact, Company Document and Link pages.
As you can see the “Index” page will be requested when clicked on the link. Let's see what we have when we hit the F5 button, if everything is OK the application will run and the Web Page is presented as seen below:
As you can see the Contact, Companies, Documents and List buttons are there.
It's important to understand that the content from for example a new Company you add to the Database partly depends on your Lists, have a look at the screen below:
As you can see (or test yourself on the running website) there's nothing in the State or Country list because there no data added yet to either one of them. So first we have to fill in the lists so click on the List button.
Let's enter some data per List so click on the first link and enter a few cost names you can think of such as rent, energy, health care, insurance , add at least a few countries to the list of Countries, for the Function add for example Manager to it and Consultant, for the Mail Category add Bill and Letter and for Payment Status Add Due and Payed, and a few states to the state list and as last add for the Title list Mr. and Mrs. to it.
OK we have entered some data into the Lists so this data should be visible when we go to the Companies and click on the create link.
As you can see the Data we entered is there. As you will understand you first must create a Company before that company will be selectable when you want to add a new document to the database.
Try the other screens a also so create a new Contact, create a Bill and play around with it.
Points of Interest
The created MvcDocuments sample will in the second part:
http://www.codeproject.com/Articles/767635/ASP-NET-MVC-Documents-sample-Part
be extended with taking care of the uploading from .Pdf scans of the Documents and the on screen presentation of them when selected and some other changes regarding the presentation of the data. In that part also search functionality will be added in the Controllers code and implemented in the screens.
I enjoyed creating it for this part and I hope readers will follow the steps above to create this web application. If any questions please ask.
Advised reading on CodeFirst
Code-First (Juli Lerman, Rowan Miller)
History
This is the first version