Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Learn MVC (Model view controller) Step by Step in 7 days – Day 2

4.85/5 (136 votes)
15 Nov 2017CPOL15 min read 771.8K  
Learn MVC (Model view controller) Step by Step in 7 days – Day 2

MVC 2 is quiet old and this article was written long years back. We would recommend you to start reading from our fresh Learn MVC 5 step by step series from here: -http://www.codeproject.com/Articles/866143/Learn-MVC-step-by-step-in-days-Day

Contents

So, what’s the agenda?

In day 2 we will look into the following four labs:

  • Writing unit tests on MVC projects.
  • Configure MVC routings.
  • Validating MVC routes.
  • Configure MVC outbound routes.

Get links of other parts of MVC article as below: -

Day 1: -Controllers, strong typed views and helper classes

http://www.codeproject.com/Articles/207797/Learn-MVC-Model-view-controller-Step-by-Step-in-7

Day 2: - Unit test, routing and outbound URLS

http://www.codeproject.com/Articles/259560/Learn-MVC-Model-view-controller-Step-by-Step-in-7

Day 3:- Partial views, Data annotations,Razor, Authentication and Authorization

http://www.codeproject.com/Articles/375182/Learn-MVC-Model-View-Controller-Step-by-Step-in-4

Day 4:- JSON, JQuery, State management and Asynch controllers

http://www.codeproject.com/Articles/667841/Learn-MVC-Model-view-controller-Step-by-Step-in-3

Day 5:- Bundling , Minification , ViewModels,Areas and Exception handling

http://www.codeproject.com/Articles/724559/Learn-MVC-Model-view-controller-Step-by-Step-in-7

Day 6: - Display Modes,MVC OAuth,Model Binders,Layout and Custom view engine

http://www.codeproject.com/Articles/789278/Learn-MVC-Model-view-controller-Step-by-Step-in-d

In case you are completely a fresher I will suggest to start with the below MVC website 4 videos which are 10 minutes approximately so that you can come to MVC quickly.

Lab No.

Lab description

Youtube Video demonstration for the same
1 A simple Hello world ASP.NET MVC application. http://youtu.be/KAKxm4eQP24?hd=1
2 In this Lab we will see how we can share data between controller and the view using view data. http://youtu.be/Fu9v2MIDlTA?hd=1
3 In this lab we will create a simple customer model, flourish the same with some data and display the same in a view. http://youtu.be/0-UdqWy9lVc?hd=1
4 In this lab we will create a simple customer data entry screen with some validation on the view. http://youtu.be/1dlxtHuRw34?hd=1

So let’s start with the above 4 labs one by one.

Lab 6: Unit test MVC projects

When we started this whole MVC series (Day 1) we started with two concerns regarding behind code:

  • How can we do unit testing on the ASP.NET behind code?
  • How can we reuse the ASP.NET behind code with different user interfaces?

In this section, let’s concentrate on the first point, i.e., Unit Testing.

Just a quick recap if we need to unit test the below method btngenerateinvoices_click in ASP.NET behind code, we have the following problems:

  • How do we create the sender and eventargs objects?
  • The below complete code runs under the HttpContext object, how do I mimic it?
  • What about ASP.NET UI controls, how do I access them?
  • What about other ASP.NET objects like session object, application, how do I access them?

FYI: Many developers would talk about mock tests, rhino mocks, etc., but still it's cryptic and the complication increases with session variables, view data objects, ASP.NET UI controls, creating further confusion.

Image 1

So what we will do in this section is we will create a simple MVC application and we will do unit tests on the ASP.NET application using the VSTS unit test framework.

Step 1: Create the simple display customer screen project

The first step is to create a simple MVC project. We will use the same project which we have discussed in MVC (Model View Controller) day 1 LearnMVC.aspx. So in case you do not have any sample projects, please create one using the link above.

Image 2

The controller class at the end of the day is a simple .NET class. For instance, if you watch your project code closely, you can easily see the customer controller class as shown below:

C#
public class CustomerController : Controller
{
...
....
public ViewResult DisplayCustomer()
{
Customer objCustomer = new Customer();
objCustomer.Id = 12;
objCustomer.CustomerCode = "1001";
objCustomer.Amount = 90.34;

return View("DisplayCustomer",objCustomer);
}
}

In simple words because this is a simple .NET class we can easily instantiate the class and create automated unit tests for the same. That’s is exactly what we are going to do in our next steps.

Step 2: Add a simple unit test project

Let’s use our VSTS unit test framework to test the controller class. In case you are a complete fresher to VSTS unit testing, see this article to get a hang of unit testing: http://www.codeproject.com/KB/cs/VSTSTesting.aspx. Add a new project to your solution using the test project solution template.

Image 3

Step 3: Add appropriate project references

We need to add a reference to the MVC application in our unit test project so that we can get hold of the controller class.

Image 4

Once you add the references, you should see the MVC application in your project references as shown in the below figure:

Image 5

Step 4: Write the unit test

Once you have added the references, open the unit test class, i.e., UnitTest1.cs. In this class create a simple test method called DisplayCustomer which is attributed by the TestMethod attribute as shown in the below code snippet.

If you see the below code snippet we are creating an object of the controller class, invoking the controller action, i.e., DisplayCustomer and then checking if the view name is DisplayCustomer. If they are equal that means the test passes, or else it fails.

C#
[TestMethod]
public void DisplayCustomer()
{
CustomerController obj = new CustomerController();
var varresult = obj.DisplayCustomer();
Assert.AreEqual("DisplayCustomer", varresult.ViewName);
}

Image 6

Step 5: Finally run the unit test

Once you have written your test case it’s time to run the test case by clicking on test, windows, and then clicking test view.

Image 7

On the test view, right click on the test and run the selected test case as shown below:

Image 8

If everything goes well you should see a green color indicating that the test has passed, or else you should see a red color with details regarding why the test failed.

Image 9

So what’s in the next lab

In the next lab we will discuss about MVC routing. MVC is all about connecting the actions to the controllers and MVC routing helps us achieve this. So be ready to get routed in our next tutorial.

Lab 7: Understanding MVC routing

Introduction

Image 10

At the end of the day, MVC is nothing but a URL mapped to controllers and controllers mapped to actions.

For example when a user sends a request URL like www.questpond.com/locateproduct from the browser, these actions are mapped with MVC controllers, and MVC controllers finally invokes those functions.

Below is a simple table which shows how the whole thing looks like:

Image 11

Adding further to the complication we can have multiple URLs mapped to one controller or you can have more than one controller mapped to a single URL. For instance you can have www.questpond.com/contactus and www.questpond.com/aboutus mapped to a single controller called AboutUsController.

Image 12

It would be great if we have some kind of mechanism by which we can configure these mappings. That’s what exactly MVC routing is meant for. MVC routing helps to easily configure and map the URL with the controllers.

Image 13

Step 1: Take the MVC project created in Day 1

Let’s take the same customer project we had discussed in the previous section.

Step 2: Change global.asax.cs

All route mappings are stored in the “global.asax.cs” code-behind file. So the first step is we need to go and change this file.

Image 14

All routing mappings are stored into a collection called routes. This collection belongs to the namespace System.Web.Routing. To add a route you need to call the MapRoute method and pass three parameters name, url, and defaults.

Below is a print screen of the snippet of the maproute function.

Image 15

  • Name is the key name by which the route will be identified from the collection.
  • Url defines what kind of URL format we want to connect with the controllers. For instance in the below code snippet we are saying that View/ViewCustomer is the URL format.
  • Defaults defines the controller class and action functions which will be invoked when the URL is called. For instance in the below code, we are saying that when View/ViewCustomer is called, it will invoke the Customer controller class and the action function invoked will be DisplayCustomer.

In case your controller takes parameters, you can use the { brackets. For instance in the below code snippet we have used { to specify that we can have an id parameter. If you want to define the parameter as optional you can use the UrlParameter.Optional enum.

The first thing is comment the default mapping code. We will explain the default mapping code later.

C#
//routes.MapRoute(
// "Default", // Route name
// "{controller}/{action}/{id}", // URL with parameters
// new { controller = "Home", action = "Index", id = 
UrlParameter.Optional }); // Parameter defaults

Put the below code, which means when we call http://localhost/View/ViewCustomer/ it will invoke the customer controller and will call the displaycustomer function.

C#
routes.MapRoute(
"View", // Route name
"View/ViewCustomer/{id}", // URL with parameters
new { controller = "Customer", action = "DisplayCustomer", 
id = UrlParameter.Optional }); // Parameter defaults

Below is the action function DisplayCustomer which will be invoked.

C#
public ViewResult DisplayCustomer()
{
Customer objCustomer = new Customer();
objCustomer.Id = 12;
objCustomer.CustomerCode = "1001";
objCustomer.Amount = 90.34;

return View("DisplayCustomer",objCustomer);
}

Step 3: Run the application

If you run the application you should see the below display.

Image 16

If you remember we commented the default entry route. Let’s understand what exactly this default code meant.

"{controller}/{action}/{id}" defines that the URL will be automatically named with the convention of controller name / function action name / value. So if you have a controller class with Customer and action function as Search then the URL will be structured as http://xyz.com/Customer/Search automatically.

C#
//routes.MapRoute(
// "Default", // Route name
// "{controller}/{action}/{id}", // URL with parameters
// new { controller = "Home", action = "Index", id = 
UrlParameter.Optional }); // Parameter defaults

So what’s in the next lab?

In the next lab, we will discuss how to validate an MVC URL. All actions to MVC come via MVC URL and even the data is fed via MVC URL. So in the next section we will see how we can validate the data passed in the MVC URL.

Lab 8: Validating and setting default values to MVC URLs

MVC is all about action which happens via URL and data for those actions is also provided by the URL. It would be great if we can validate data which is passed via these MVC URLs.

For instance let’s consider the MVC URL http://localhost/Customer/ViewCustomer. If anyone wants to view customer details for the 1001 customer code, he needs to enter http://localhost/Customer/ViewCustomer/1001.

The customer code is numeric in nature. In other words anyone entering a MVC URL like http://localhost/Customer/ViewCustomer/Shiv is invalid. The MVC framework provides a validation mechanism by which we can check on the URL itself if the data is appropriate. In this lab we will see how to validate data which is entered on the MVC URL.

Step 1: Create a simple customer model

The first step is to create a simple customer class model which will be invoked by the controller.

C#
public class Customer
{
public int Id { set; get; }
public string CustomerCode { set; get; }
public double Amount { set; get; }
}

Step 2: Create the controller class

The next step is to create a simple controller class which has a collection of the customer model object which was created in step 1.

C#
public class CustomerController : Controller
{
List<Customer> Customers = new List<Customer>();
//
// GET: /Customer/
public CustomerController()
{
Customer obj1 = new Customer();
obj1.Id = 12;
obj1.CustomerCode = "1001";
obj1.Amount = 90.34;

Customers.Add(obj1);

obj1 = new Customer();
obj1.Id = 11;
obj1.CustomerCode = "1002";
obj1.Amount = 91;
Customers.Add(obj1);

}

[HttpGet]
public ViewResult DisplayCustomer(int id)
{
Customer objCustomer = Customers[id];

return View("DisplayCustomer",objCustomer);
}
}

The controller has a simple DisplayCustomer function which displays the customer using the id value. This function takes the id value and looks up through the customer collection. Below is the downsized reposted code of the function.

C#
[HttpGet]
public ViewResult DisplayCustomer(int id)
{
Customer objCustomer = Customers[id];

return View("DisplayCustomer",objCustomer);
}

If you look at the DisplayCustomer function it takes an id value which is numeric. We would like to put a validation on this ID field with the following constraints:

  • Id should always be numeric.
  • It should be between 0 to 99.

We want the above validations to fire when the MVC URL is invoked with data.

Step 3: Apply validation using regex on the MVC routes

The validation described in the step 2 can be achieved by applying a regular expression on the route map. If you go to the global.asax file and see the maproute function, the input to this function is the constraint as shown in the below figure.

Image 17

In case you are new to regular expressions, we would advise you to go through this video on regular expressions: http://youtu.be/C2zm0roE-Uc?hd=1.

So in order to accommodate the numeric validation we need to the specify the regex constraint, i.e., ‘\d{1,2}’ in the maproute function as shown below. ‘\d{1,2}’ in regex means that the input should be numeric and should be a maximum of length 1 or 2 , i.e., between 0 to 99.

You can specify the default values by saying id=0 as shown in the below code snippet. So just in case if some one does not specify the value to the ID, it will take the value as zero by default.

C#
routes.MapRoute(
"View", // Route name
"View/ViewCustomer/{id}", // URL with parameters
new { controller = "Customer", action = "DisplayCustomer", 
id = 0 }, new { id = @"\d{1,2}" }); // Parameter defaults

Step 4: Test if it works

So now that we are done with the validation using the maproute functions, it’s time to test if these validations work. So in the first test we have specified valid 1 and we see that the controller is hit and the data is displayed.

Image 18

If you try to specify value more than 100 you would get an error as shown below. Please note that the error is confusing but it’s the effect of the regex validation which is specified on the maproute function.

Image 19

If you try to specify a non-numeric value you should again get the same error which confirms that our regex validation is working properly.

Image 20

The most important point to note is that these validations are executed even before the request reaches the controller functions.

So what’s in the next lab

One of the crucial things in any website development is defining navigations from one page to another page. In MVC everything is an action and those actions invoke the views or pages. We can not specify direct hyperlinks like www.questpond.com/home.aspx, this would defeat the purpose of MVC. In other words we need to specify actions and these actions will invoke the URLs.

In the next lab we will look into how to define an outbound URL in MVC views which will help us navigate from one page to another page.

Lab 9: Understanding MVC outbound URLs

Introduction

When we talk about web applications, end users would like to navigate from one page to another page. So as a simple developer your first thought would be to just give page names as shown in the below figure.

So for example if you want to go and browse from home.aspx to about.aspx give the anchor a hyper link page name and things should be fine.

By doing that you are violating MVC principles. MVC principles say that the hit should first come to the controller, but by specifying <a href="/KB/Articles/Home.aspx"> the first hit comes to the view. This bypasses your controller logic completely and your MVC architecture falls flat.

Image 21

Ideally the actions should direct which page should be invoked. So the hyperlink should have actions in the anchor tags and not the page names, i.e., direct view name.

Step 1: Create views

Let's create three views as shown in the below figure Home, About, and Product.

Image 22

Let’s create a simple navigation between these three pages as shown below. From the home view we would like to navigate to the about and product views. From the about and product views we would like to navigate back to the home view.

Image 23

Step 2: Create controller for the views

The next step is to define controller actions which will invoke these views. In the below code snippet we have defined three actions: GotoHome (this invokes the home view), Aboutus (this invokes the about view), and SeeProduct (this invokes the product view).

C#
public class SiteController : Controller
{
//
// GET: /Site/

public ActionResult GotoHome()
{
return View("Home");
}

public ActionResult AboutUs()
{
return View("About");
}

public ActionResult SeeProduct()
{
return View("Product");
}
}

Step 3: Provide actions in the link

To invoke the actions rather than the views we need to specify the actions in the anchor tag as shown in the below code snippet.

This is products
<a href="GotoHome">Go Home</a><br />
<a href="Aboutus">About us</a><br />

If you want to create the anchor links using the HTML helper classes, you can use the action link function as shown in the below code snippet.

ASP.NET
<%= Html.ActionLink("Home","Gotohome") %>

The above code was for the products page, you can do the same type of navigations for the about us and the home page.

XML
This is About us
<a href="GotoHome">Go Home</a><br />
<a href="SeeProduct">See Product</a><br />

This is home page
<br />
<a href="SeeProduct">See Product</a><br />
<a href="Aboutus">About us</a><br />
</div>

Step 4: Enjoy your navigation

Once you have specified the actions inside the link, you navigate between home, about, and products page.

Image 24

Image 25

While navigating you can see how the URLs are pointing to the actions rather than absolute page names like home.aspx, aboutus.aspx, etc., which violates the complete MVC principle.

What’s for the third day?

In the third session, we will talk about Partial views, Validation using data annotations, Razor (MVC 3), MVC Windows Authentication, MVC Forms Authentication and a lot more. The next lab will be a bit more advanced as compared to the second day. Below is the link for the third day: Click here for the day third MVC step by step.

A final note: you can watch my .NET interview questions and answers videos on various topics like WCF, Silverlight, LINQ, WPF, Design Patterns, Entity Framework etc.

For technical training related to various topics including ASP.NET, Design Patterns, WCF, MVC, BI, WPF contact SukeshMarla@gmail.com or visit www.sukesh-marla.com

Start with MVC 5

In case you want to start with MVC 5 start with the below video Learn MVC 5 in 2 days.

Image 26

50 MVC Interview questions with answers

In case you are going for interviews you can read my 50 Important MVC interview questions with answer article http://www.codeproject.com/Articles/556995/Model-view-controller-MVC-Interview-questions-and

For further reading do watch the below interview preparation videos and step by step video series.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)