Friday, December 28, 2012

Learn MVC


Learn MVC (Model View Controller)

Contents

So, what’s the agenda?

As the article name says, learn MVC; so the agenda is simple, we are going to learn ASP.NET MVC in 7 days.
The way we will learn MVC in this series of articles is by doing labs, looking at detailed steps of how to achieve those labs, and also looking at demonstrative videos.
This article series is divided into 7 days with 35 hands-on labs and every day we will do 5 labs which will help us achieve our goals.
So get ready for day 1. For day 1, shown below is our agenda. We will start with an introduction, do a simple Hello World, and finally in the 6th lab, we will create a simple customer data entry screen using HTML Helper classes.
Lab No.Lab descriptionYouTube video demonstration
1Introduction, Why MVC?NA.
2A simple Hello World ASP.NET MVC application.http://youtu.be/KAKxm4eQP24?hd=1
3In this lab we will see how we can share data between the controller and the view using view data.http://youtu.be/Fu9v2MIDlTA?hd=1
4In 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
5In this lab we will create a simple customer data entry screen with some validation on the view.http://youtu.be/1dlxtHuRw34?hd=1
6This lab will demonstrate how to expedite your MVC development process using HTML Helper classes.Pending…
Here you can watch my .NET interview questions and answers videos on various topics like WCF, Silverlight, LINQ, WPF, Design Patterns, Entity Framework, etc.

Other Parts of MVC Step by Step in 7 days

  • Get Part 2 of the MVC step by step article.
  • Get Part 3 of the MVC step by step article.

So why MVC when ASP.NET code-behind is so good?

I am sure all ASP.NET developers love the code-behind concept. Accepting something new like MVC will not be easy for them. So let’s analyze the problems with the current code-behind concept.
When we generally talk about ASP.NET applications built on a tiered architecture they are divided in four parts: UI (ASPX pages), code-behind (ASPX.CS pages), middle tier (.NET classes), and finally the Data layer.
If you look from the aspect of code distribution, the major code which has logic is in the middle tier or in the code-behind (ASPX.CS files). The UI or ASPX files are HTML files which are more about UI design, and data access logic is pretty much standard components like enterprise data blocks, entity data contexts, etc.
Let’s try to analyze the problems.

Problem number 1: Unit Testing

From the aspect of unit testing we can exclude the data logic and the UI HTML. The data logic classes are already time tested components like enterprise data block, entity data context, or LINQ data context. So we really do not have to put a lot of effort on testing the DAL separately. In case you have a custom data access layer it will still be easy to test them as they are simple .NET classes.
There is no logic in testing an ASPX HTML as it’s more about look and feel.
The middle tier is again a simple .NET class like data logic so you can easily do unit testing using VSTS or NUNIT.
Now comes the most important one: the code-behind. The code-behind has a lot of action, and testing it is one of the most important things. The only way to invoke these codes is by doing a manual test. From a time perspective this would not be a great choice.
Even though Microsoft has always boasted about how the ASP.NET code-behind is separate from the UI, in practical sense, it’s very difficult to decouple ASP.NET code-behind and do unit testing on it.
The ASP.NET code-behind is completely tied up with the ASP.NET HttpContext object which makes unit testing very difficult. Just think os how to unit test the below ASP.NET code-behind. How do I create an HttpCcontext object, how do I simulate the sender and EventArgs objects of the button clicks, etc.
FYI: Many developers talk about mock tests, rhino mocks, etc., but still it is cryptic and the complication increases with session variables, view data objects, and ASP.NET UI controls creating further confusion.

Problem 2: The reality of separation of code and UI

As said previously, the ASPX and the ASPX.CS cannot be decoupled in reality, thus reducing reusability. Yes, Microsoft did say first that the code-behind is different from the UI, but then they are probably separate physical files only and one cannot just exist without the other.
For instance let’s say the same button click code when called via HTTP POST should display using displayinvoice.aspxand when called via HTTP GET should display in a tree view. In other words we would like to reuse the code-behind. Just think of how can we do this using the current code-behind.

Our HERO MVC (Model, View, and Controller)

That’s where MVC comes to rescue. The code-behind is moved to a simple .NET class called Controller. Any user request first comes to the Controller class, the Controller class then invokes the model, and attaches the model to the view for display to the end user.
As this controller class is a simple .NET class we can reuse and also do unit testing easily. So let’s see how we can create MVC application using MVC template provided by visual studio.

Pre-requisite for MVC

Before we start the day let's ensure that you have all the ingredients to create an MVC application.
  • Visual Studio 2010 or the free Visual Web Developer 2010 Express. These include the ASP.NET MVC 2 template by default.
  • Visual Studio 2008 SP1 (any edition) or the free Visual Web Developer 2008 Express with SP1. These do not include ASP.NET MVC 2 by default; you must also download and install ASP.NET MVC 2 fromhttp://www.asp.net/mvc/.
So once you have all your pre-requisites it is time to start the first lab.

Lab 1: Creating a simple Hello World ASP.NET MVC application

In this lab we will create a simple Hello World program using an MVC template. We will create a simple controller, attach the controller to a simple index.aspx page, and view the display on the browser.

Video demonstration for lab 1

In case you want to spend more time with your family rather than reading the complete article you can watch the following 5 minute YouTube video: http://youtu.be/KAKxm4eQP24?hd=1.

Step 1: Create project

Create a new project by selecting the MVC 2 empty web application template as shown in the below figure.
Once you click OK, you have a readymade structure with the appropriate folders where you can add controllers, models, and views.

Step 2: Add controller

So let’s go and add a new controller as shown in the below figure.
Once you add the new controller, you should see some kind of code snippet as shown below:
public class Default1Controller : Controller
{
    //
    // GET: /Default1/
    public ActionResult Index()
    {
        return View();
    }
}

Step 3: Add view

Now that we have the controller we need to go and add the view. So click on the Index function which is present in the control and click on the Add View menu as shown in the below figure.
The add view pops up a modal box to enter the view name which will be invoked when this controller is called as shown in the figure below. For now, keep the view name same as the controller name and also uncheck the master page check box.
Once you click on the OK button of the view, you should see a simple ASPX page with the below HTML code snippet. In the below code snippet I have added “This is my first MVC application”.
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Index</title>
</head>
<body>
<div>
This is my first MVC application
</div>
</body>
</html>

Step 4: Run the application

If you do a CTRL + F5 you should see an error as shown in the below figure. This error is obvious because we have not invoked the appropriate controller / action.
If you append the proper controller on the URL you should be able to see the proper view.

So what’s in the next lab?

Now that we have created a simple MVC Hello World, it’s time to see how we can pass data from the controllers to the views. The first hit comes to the controller which will load your business objects or model and you would like to transfer these objects to the view to display them.

Lab 2: Passing data between controllers and views

The controller gets the first hit and loads the model. Most of the time we would like to pass the model to the view for display purposes. As an ASP.NET developer your choice would be to use session variables, view state, or some other ASP.NET session management object.
The problem with using the ASP.NET session or view state object is the scope. ASP.NET session objects have session scope and view state has page scope. For MVC we would like to see the scope limited to the controller and the view. In other words we would like to maintain data when the hit comes to the controller and reaches the view and after that the scope of the data should expire.
That’s where the new session management technique has been introduced in the ASP.NET MVC framework, i.e., ViewData.

Video demonstration for lab 2

Below is a simple YouTube video which demonstrates the lab for the view data. In this video we will see how we can share data between the controller and the view using view data. So we will create a simple controller, record the current data in a view data variable, and then display the same in the view using the percentage tag:http://youtu.be/Fu9v2MIDlTA?hd=1.

Step 1: Create project and set view data

So the first step is to create a project and a controller. In the controller, set the viewdata variable as shown in the below code snippet and kick off the view.
public class DisplayTimeController : Controller
{
    //
    // GET: /DisplayTime/

    public ActionResult Index()
    {
        ViewData["CurrentTime"] = DateTime.Now.ToString();
        return View();
    }
}

Step 2: Display view data in the view

The next thing is to display data in the view by using the percentage tag. One important point to note is, the view does not have a code-behind. So to display the view we need to use the <%: tag in the ASPX page as shown in the below code snippet.
<body>
<div>
<%: ViewData["CurrentTime"] %>
</div>
</body>

So what’s in the next lab?

So now that we know how to pass data using view data, the next lab is to create a simple model and see all the three MVC entities (i.e., model, view, and controller) in action.

Lab 3: Creating a simple model using MVC

In this lab we will create a simple customer model, flourish it with some data, and display it in a view.

Video demonstration for Lab 3

Below is a video demonstration: http://youtu.be/0-UdqWy9lVc?hd=1.

Step 1: Create a simple class file

The first step is to create a simple customer model which is nothing but a class with three properties: code, name, and amount. Create a simple MVC project, right click on the model folder, and click on Add New Item, as shown in the below figure.
From the templates, select a simple class and name it as Customer.
Create the class with three properties as shown in the below code snippet.
public class Customer
{
    private string _Code;
    private string _Name;
    private double _Amount;

    public string Code
    {
        set
        {
            _Code = value;
        }
        get
        {
            return _Code;
        }
    }

    public string Name
    {
        get
        {
            return _Name;
        }
        set
        {
            _Name = value;
        }
    }

    public double Amount
    {
        set
        {
            _Amount = value;
        }
        get 
        {
            return _Amount;
        }
    }
}

Step 2: Define the controller with action

The next step is to add the controller and create a simple action display customer as shown in the below code snippet. Import the model namespace in the controller class. In the action, we create an object of the customer class, flourish with some data, and pass it to a view named “DisplayCustomer”.
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);
    }
}

Step 3: Create strongly typed view using the class

We need to now join the points of MVC by creating views. So right click on the view folder and click Add View. You should see a dropdown as shown in the below figure. Give a view name, check Create a strongly typed view, and bind this view to the customer class using the dropdown as shown in the below figure.
The advantage of creating a strong typed view is you can now get the properties of the class in the view by typing the model and “.” as shown in the below figure.
Below is the view code which displays the customer property value. We have also put an if condition which displays the customer as a privileged customer if above 100 and a normal customer if below 100.
<body>
<div>
The customer id is <%= Model.Id %> <br />

The customer Code is <%= Model.CustomerCode %> <br />

<% if (Model.Amount > 100) {%>
This is a priveleged customer
<% } else{ %>
This is a normal customer
<%} %>

</div>
</body>

Step 4: Run your application

Now the “D” thing, hit Ctrl + F5 and pat yourself for one more lab success.

So what’s in the next lab?

In this sample we flourished the customer object from within the controller. In the next lab we will take data from an input view and display it. In other words we will see how to create data entry screens for accepting data from views.

Lab 4: Creating a simple MVC data entry screen

Every project small or big needs data entry screens. In this lab we will create a simple customer data entry screen as shown in the below figure using an MVC template.
As soon as the end user enters details and submits data it redirects to a screen as shown below. If the entered amount is less than 100 it displays normal customer, else it displays privileged customer.

Video demonstration for lab 4

Here is a simple video demonstration for this lab: http://youtu.be/1dlxtHuRw34?hd=1.

Step 1: Creating your data entry ASPX page

The first step is to create the data entry page using the simple HTML form action tag as shown in the below code snippet. The most important point to note in the below code snippet is that the action is pointing to the controller action, i.e., ‘DisplayCustomer’.
<form action="DisplayCustomer" method="post">
Enter customer id :- <input type="text" name="Id" /> <br />
Enter customer code :- <input type="text" name="CustomerCode" /><br />
Enter customer Amount :-<input type="text" name="Amount" /><br />
<input type="submit" value="Submit customer data" />
</form>

Step 2: Creating the controller

The above defined form action will post to the controller class and on the function “DisplayCustomer”. So we need to get the data from the HTML controls, flourish the object, and send the object to the view.
Below is the code snippet of DisplayCustomer which flourishes the customer object by collecting data fromRequest.Form and sends the object to the view DisplayCustomer.
public class CustomerController : Controller
{
    …..
    ….
    [HttpPost]
    public ViewResult DisplayCustomer()
    {
        Customer objCustomer = new Customer();
        objCustomer.Id = Convert.ToInt16(Request.Form["Id"].ToString());
        objCustomer.CustomerCode = Request.Form["Id"].ToString();
        objCustomer.Amount = Convert.ToDouble(Request.Form["Amount"].ToString()); ;
        return View("DisplayCustomer", objCustomer);
    }
}

Step 3: Create the view to display the customer object

The next step is to create the “DisplayCustomer” view. So right click on the view folder and click Add view. You should see a dropdown as shown in the below figure. Give a view name, check Create a strongly typed view, and bind this view to the customer class using the dropdown, as shown in the below figure.
The advantage of creating a strong typed view is you can now get the properties of the class in the view by typing the model and “.” as shown in the below figure.
Below is the view code which displays the customer property value. We have also put an if condition which displays the customer as a privileged customer if above 100 and normal customer if below 100.
<body>
<div>
The customer id is <%= Model.Id %> <br />

The customer Code is <%= Model.CustomerCode %> <br />

<% if (Model.Amount > 100) {%>
This is a priveleged customer
<% } else{ %>
This is a normal customer
<%} %>

</div>
</body>

Step 4: Finally run the project

The final step is to run the project and see the output.
You should also be able to test above 100 and below 100 scenarios.

So what’s in the next lab?

In this lab we created a simple data entry screen which helped us flourish the customer object. This customer object was then passed to the view for display. If you closely watch the current lab we have done a lot of coding, i.e., creating the HTML screens, flourishing the object, etc. It would be great if there was some kind of automation. In the next lab we see how HTML helper classes help to minimize many of these manual coding and thus increase productivity.

Lab 5: Using HTMLHelper to create views faster

In our previous lab we created a simple customer data entry screen. We completed the lab successfully but with two big problems:
  • The complete HTML code was written manually. In other words, it was less productive. It’s like going back to the dark ages where developers used to write HTML tags in Notepad.
  • <form action="DisplayCustomer" method="post">
    Enter customer id :- <input type="text" name="Id" /> <br />
    Enter customer code :- <input type="text" name="CustomerCode" /><br />
    Enter customer Amount :-<input type="text" name="Amount" /><br />
    <input type="submit" value="Submit customer data" />
    </form>
  • Added to that, a lot of manual code was also written in the controller to flourish the object and send data to the MVC view.
  • public class CustomerController : Controller
    {
        …..
        ….
        [HttpPost]
        public ViewResult DisplayCustomer()
        {
            Customer objCustomer = new Customer();
            objCustomer.Id = Convert.ToInt16(Request.Form["Id"].ToString());
            objCustomer.CustomerCode = Request.Form["Id"].ToString();
            objCustomer.Amount = Convert.ToDouble(Request.Form["Amount"].ToString()); ;
            return View("DisplayCustomer", objCustomer);
        }
    }
In this lab we will see how to use MVC HTMLHelper classes to minimize manual coding and increase productivity.

Step 1: Create the Customer class

Create a simple customer class, please refer to Lab 5 for details.

Step 2: Creating the input HTML form using helper classes

HTML helper classes have readymade functions by which you can create HTML controls with ease. Go to any MVC view and see the intellisense for the HTMLHelper class, and you should see something as shown in the below figure.
By using the HTMLHelper class you can create any HTML control like TextBoxLabelListBox, etc., just by invoking the appropriate function.
In order to create the form tag for HTML we need to use “Html.BeginForm”. Shown below is the code snippet for that:
<% using (Html.BeginForm("DisplayCustomer","Customer",FormMethod.Post)) 
{%>
-- HTML input fields will go here 
<%} %>
The above code will generate the below HTML:
<form action="DisplayCustomer" method="post">
…..
…..
</form>
The HTML helper “beginform” takes three input parameters: action name (method inside the controller), controller name (actual controller name), and HTTP posting methodology (POST or GET).
If you want to create a text box, simply use the “TextBox” function of the HTMLHelper class as shown in the below code. This way you can create HTML controls using the HTMLHelper class functions.
Enter customer id :- <%= Html.TextBox("Id",Model)%> <br />
The above code snippet will generate the below HTML code:
Enter customer id :- <input type="text" name="Id" /> <br />
To create a data entry screen like the one shown below, we need to the use the below code snippet.
<% using (Html.BeginForm("DisplayCustomer","Customer",FormMethod.Post))
{ %>
Enter customer id :- <%= Html.TextBox("Id",Model)%> <br />
Enter customer code :- <%= Html.TextBox("CustomerCode",Model) %><br />
Enter customer Amount :- <%= Html.TextBox("Amount",Model) %><br />
<input type="submit" value="Submit customer data" />
<%} %>

Step 3: Create a strong typed view by using the customer class

So once you have created the view using the HTMLHelper classes it’s time to attach the customer class with the view; please refer to lab 5 for details.

Step 4: Creating the controller class

The final thing is the controller code. The controller code now becomes very simple. The customer object will be auto flourished as we have used the HTML Helper classes. You will create the controller class as we did in Lab 4 but we do not need to write any kind of code for connecting the HTML screens with the controller, it’s all hidden and automated.
[HttpPost]
public ActionResult DisplayCustomer(Customer obj)
{
    return View(obj);
}
Enjoy your output for different conditions of customer amounts entered.


Lab 7:- Understanding MVC routing
        Introduction
        Step 1:- Take the MVC project created in Day 1.
        Step 2 :- Change global.asax.cs 
        Step 3:- Run the application
        So what’s in the next Lab 

Lab 8:- Validating and setting default values to MVC URLS
        Step 1:- Create a simple customer model
        Step 2:- Create the controller class
        Step 3:- Apply validation using regex on the MVC routes
        Step 4:- Test if it works
        So what’s in the next lab

Lab 9:- Understanding MVC outbound URLs
        Introduction
        Step 1:- Create views
        Step 2 :- Create controller for the views
        Step 3:- Provide actions in the link
        Step 4:- Enjoy your navigation
      
What’s for third day?          

So, what’s the agenda?

This article is continuation to Learn MVC step by step in 7 days you can read the first day from Click here for Day 1 article.
Get Part 3 of the MVC Step by Step article.

In day 2 we will look in do the following 4 labs. 

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

In case you are completely a fresher I will suggest to start with the below 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
1A simple Hello world ASP.NET MVC application.http://youtu.be/KAKxm4eQP24?hd=1
2In this Lab we will see how we can share data between controller and the view using view data.http://youtu.be/Fu9v2MIDlTA?hd=1
3In 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 
4In 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 object?
• The below complete code runs under HttpContext object, how do I mimic them?
• What about ASP.NET UI controls , how do I access them ?
• What about other ASP.NET object like session object, application, how do I access them?.

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


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

Step1:- 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 project please create one using the link above.


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.
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 what exactly 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 we would request to see this article to get a hang of unit testinghttp://www.codeproject.com/KB/cs/VSTSTesting.aspx  . Add a new project to your solution using the test project solution template.



Step 3:- Add appropriate project references

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




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




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 as ‘DisplayCustomer’ which is attributed by ‘TestMethod’ attribute as shown in the below code snippet.

If you see the below code snippet we are creating 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.
[TestMethod]
public void DisplayCustomer()
{
CustomerController obj = new CustomerController();
var varresult = obj.DisplayCustomer();
Assert.AreEqual("DisplayCustomer", varresult.ViewName);
}


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.




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




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




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 to achieve the same. So be ready to get routed in our next tutorial.

Lab 7:- Understanding MVC routing

Introduction

At the end of the day MVC is nothing but 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.


Adding further to the complication we can have multiple URL’s 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  andwww.questpond.com/aboutus  mapped to a single controller called as “AboutUsController”.


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.




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” behind code file. So the first step is we need to go and change this file.


All routing mapping are stored in to a collection called as ‘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.



“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 “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.
//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 displaycustomer function.
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.
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.



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

"{controller}/{action}/{id}" defines that 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.
//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 MVC URL. All actions to MVC come via MVC URL and even 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 URL’s.

For instance let’s consider the MVC URL http://localhost/Customer/ViewCustomer  . If anyone wants to view customer details for 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 likehttp://localhost/Customer/ViewCustomer/Shiv  is invalid. 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 is to create a simple customer class model which will be invoked by the controller.
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 collection of the customer model object which was created in step 1.
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.
[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 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 regular expression on the route map. If you go to global.asax file and see the maproute function on the inputs to this function is the constraint as shown in the below figure.


In case you are new to regular expression we would advise you to go through this video on regular expressionshttp://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 maximum of length 1 or 2 , i.e. between 0 to 99.

You can specify 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.
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.



If you try to specify value more than 100 you would get 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.



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.



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 the other page. In MVC everything is an action and those actions invoke the views or pages. We can not specify direct hyperlinks likewww.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 URL’s.

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

Lab 9:- Understanding MVC outbound URLs

Introduction

When we talk about web applications end users would like to navigate from one page to other 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 hyper link page name and things should be fine.

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



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

Lets create three views as shown in the below figure “Home”,”About” and “Product”.



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


Step 2 :- Create controller for the views

Next step is to define controller actions which will invoke these views. In the below code snippet we have defined 3 actions “GotoHome” (this invokes home view), “Aboutus” ( this invokes the about view) and “SeeProduct” ( this invokes product view).
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.
<%= 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.
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.




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

No comments:

Post a Comment