A step-by-step guide on building a simple web application using the Model-View-Controller (MVC) architectural pattern and .NET technologies. This article will walk you through the fundamental concepts and provide clear instructions for creating your own MVC-based web application from scratch.
Introduction
If you're new to the world of web development and eager to take your first steps into the realm of Model-View-Controller (MVC) architecture, you're in the right place. This article is tailored specifically for absolute beginners, serving as your inaugural journey into the exciting world of MVC.
In the next few minutes, we'll embark on a hands-on exploration of MVC, as I guide you through the creation of a simple project. Our goal is to demystify how control flows seamlessly between the Model, Controller, and View components, laying a strong foundation for you to venture into more complex MVC applications with confidence.
So, whether you're a curious coding novice or simply looking for a refresher, let's dive in and unlock the fundamental principles of building MVC applications.
Topics we are going to cover:
In this article, we'll explore fundamental concepts in MVC (Model-View-Controller) web development. We'll cover the following key topics:
- Understanding the Folder Structure - We'll start by discussing the essential folder structure of an MVC project.
- How MVC Works: Navigating the Control Flow - Next, we'll delve into the core of MVC - the control flow. We'll break down how requests from users are handled, providing you with a clear understanding of how Models, Views, and Controllers work together to create a seamless user experience.
- Building Blocks of MVC: Controllers, Models, and Views - Finally, we'll introduce you to the key components of MVC - Controllers, Models, and Views. We'll explain their roles and guide you through the process of creating them, ensuring you have a strong foundation for developing your own MVC applications.
So let us start by creating a simple project. The description of working of our project is given below.
Functionality of our Application
- Upon launching our application, the home page will prominently feature a hyperlink labeled "click." When users click this hyperlink, a message will be instantly displayed, presenting a warm and welcoming "Hello World!!"
- Taking a significant step forward, our application will transition from displaying a simple message to showcasing a list of individual names. This list, consisting of person names, will be prominently presented, offering a more engaging and interactive user experience.
Understanding the folders
When you create a project a folder structure gets created by default under the name of your project which can be seen in solution explorer. These folders and their respective contents play crucial roles in organizing, structuring, and functioning of a typical MVC application. Understanding their purposes is a fundamental step in working with the Model-View-Controller pattern in web development.
Model
The Model folder is where you define classes that represent your application's data. These classes can interact with a database to retrieve and manipulate data, or they can hold data entered by users via forms for later updates to the database. In other words, the Model handles the data-related logic of your application.
Controllers
Controllers are classes that handle user interactions and perform actions based on those interactions. Each controller contains methods called Actions that respond to user requests and determine what to do with those requests. These actions dictate how the application behaves in response to user input.
Views
The Views folder contains the user interface components of your application. Views are responsible for presenting data from the Model to the end user. They use the data from the Model to populate HTML controls and generate the content that is rendered in the client's web browser. Essentially, Views handle the presentation and user interface aspects of your application.
App_Start
The App_Start folder contains configuration classes for various application settings and behaviors. In the context you've mentioned, it includes classes like FilterConfig
, RoutesConfig
, and WebApiConfig
. The RouteConfig
class is particularly important for defining the URL structure used to navigate between different pages or actions within your application.
Such as:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
Certainly, here's a revised version of the text with a more professional tone and simplified language:
In this context, MapRoute
is an extension method. Its url
property is employed to define the structure of the URL. By default, the specified format is in the following order: {controller's name}/{action's name}/{optional parameter}.
You have the flexibility to modify this format according to your specific requirements. However, it's important to note that this is the standardized format, and the third section of the URL, represented by {id}
, is optional. We'll delve into how this id is utilized in greater detail later in this article.
Control Flow
To facilitate a fundamental understanding of the control flow in Model-View-Controller (MVC), we'll begin with a simplified diagram.
- Controller: The journey commences in the controller. Here, user requests are received and actions are initiated based on those requests. The controller acts as the orchestrator, deciding what specific actions to take.
- Model (if required): Depending on the nature of the request, the controller may need to interact with the model. The model is responsible for handling data-related operations, which can include retrieving, updating, or processing data. This interaction occurs when the request necessitates data manipulation.
- Back to Controller: After interacting with the model, control returns to the controller. This phase involves making decisions based on the results obtained from the model, or for further processing, possibly leading to additional actions.
- View: The final destination of the control flow is the view. The view is responsible for presenting the data processed by the controller and model in a user-friendly manner. It generates the visual components, such as HTML, that are sent to the user's browser for display.
As we progress through the article, you will gain a more in-depth comprehension of the intricate dynamics between controllers, views, and models within the MVC architectural pattern. This fundamental understanding serves as a solid foundation for navigating the complexities of MVC-based web development.
Now, to begin building our application, we need a home page that will be displayed when the application is launched. This home page features a hyperlink labeled "click." At this stage, we'll implement this functionality.
As you may recall from the control flow diagram, the initial step is for control to be directed to the controller. To ensure our application runs as intended, the presence of a controller is essential.
Creating MVC Application
I have used Visual Studio 2013 but you can also work with Visual Studio 2012. In Visual Studio create a new project named Sample.
- Launch Visual Studio.
- Go to "File" and select "New" followed by "Project."
- In the left-hand panel, under the "Web" section, choose "MVC 4 Web Application" under the .NET Framework 4.5. Name your project "Sample" and click "OK."
- In the templates window, select the "Empty Application" template. While the "Internet Application" template is an option, we'll choose the "Empty Application" for simplicity.
- Select the "Razor" engine as your View Engine. You might wonder what a view engine is?
- A view engine, in ASP.NET MVC, acts as an intermediary between your view and the browser. It ensures that the output from your view is rendered as valid HTML in the browser.
- The .NET Framework offers two View Engines: "Razor" and "ASPX." They have differences in namespaces, file extensions, and syntax:
- Razor uses .cshtml (in C#) and .vbhtml (in VB) extensions.
- ASPX uses .aspx for views, .ascx for UserControls, and .master for Master Pages.
- Click "OK," and your application will be created.
Now, we'll take it step by step according to the "Functionality of our application" heading. Let's begin with the first step:
When we run our application, it should contain a hyperlink on the home page named click. On clicking the hyperlink, a message should be displayed, i.e., "Hello World!!"
For this initial step, we'll focus on creating a homepage. To determine which of the three components (Model, View, Controller) to use, consider that a homepage presents content to users using HTML elements. In this case, the correct component to create our homepage is the "View."
Creating View
- Inside the Views folder, create a new folder named Person.
- Right-click on the Person folder, select "Add," and then click on "View" from the expanded options. Name the view "Home" and click "OK." This action will add a view named Home.cshtml within the Person folder, and it's important to note that the extension for Razor view engine views is .cshtml.
- In the Home.cshtml view, you'll find default code generated by the .NET Framework. Replace the content within the
<h2></h2>
HTML element with the following code:
@Html.ActionLink("click","Message","Person")
This line of code creates a hyperlink named click . Take note of the @
symbol; in the Razor view engine, it's used to include code. Html
is a helper class used for creating HTML controls like textboxes, labels, hyperlinks, and more. To create a hyperlink, we use the ActionLink
method of the Html
helper class.
- There are multiple overloads of the
ActionLink
method, but in this case, we're using the 4th overload: Html.ActionLink(string linkText, string actionName, string controllerName)
. linkText
is set as click
. actionName
is the name of the action method that should be executed when the link is clicked; let's name it Message
. controllerName
is the name of the controller that contains the Message
action method; we'll name it Person
.
Important Note: It's possible for multiple controllers to contain action methods with the same name.
This HTML component (ActionLink
) will be rendered but won't function as expected when clicked because we haven't yet created the controller and action specified in the ActionLink
method (i.e., Person
and Message
).
As you might recall, controllers contain actions. Therefore, for our application, the Person
controller will contain the Message
action. To resolve this, let's start by creating the controller.
Creating Controller
- In Solution Explorer, right-click on the Controller folder. Select "Add" and then choose "Controller" from the expanded options. Name the controller "Person."
- Remember to include the word 'Controller' at the end of the name, so the controller's name should be
PersonController
. Click "OK." - Inside the
PersonController
, you'll find some default code, including an Index action. Delete this method, as our PersonController
should have a Message
action. Let's create it. - An action in an MVC controller is a method. Within the
PersonController
class, create an empty method named Message
. For now, keep the return type of this method as void. - We'll define the functionality of the
Message
action. Our goal is to have this action display the message "Hello World!!" for users. To display this message, we need a view. Therefore, we will return a view from the Message
action. Since we are returning something from the Message
action, its return type should not be void. - A view is represented by the
ViewResult
class, which inherits from the ActionResult
class. Thus, the return type of the Message
action will be ActionResult
. - Our
PersonController
with the Message
action will look like this:
class PersonController
{
public ActionResult Message()
{
return view();
}
}
The return type of the action may vary depending on the specific requirements. For instance, when returning JSON-formatted content, the return type would be "JsonResult." To return a view, we use ActionResult
. The Message
action will return a view named Message
, which will contain the message "Hello World!!"
To achieve this, you must create another view with the same name as the action returning it, which is "Message." Add this view to the same folder where you added the "Home" view, namely, the Person folder.
Important Note: The name of the folder created in the Views folder should match the controller name for which these views are added.
To display the "Hello World" message, you can use an HTML heading element like this:
<h2>Hello World!!</h2>
Apart from the Message
action, we'll also need another action, let's call it "Home." This action is intended to display the homepage.
Remember, as per the control flow, the first point of contact is the controller, which executes the actions. So, to open our view with the homepage when our application runs, we need an action that can be implemented using the controller's actions.
Create the Home
action in a similar manner as the Message
action. It will have the same definition as of Message
action. Only the difference is their name.
Adjusting Route Configuration
Now run your application press Ctrl + F5. You will see the following page:
The reason behind the control not displaying our homepage is related to the RouteConfig
class. When you open the RouteConfig
class in the App_Start folder, you'll notice that the default URL specifies the controller as "Home" and the action as "Index." However, in our project, we don't have a controller named Home or an action named Index. This default URL is executed when our application runs, but we want our custom homepage to be displayed.
To achieve this, we need to make some minor changes in our RouteConfig
class. Specifically, set the controller to Person
and the action to Home
.
Note: In the controller parameter, you don't need to provide PersonController
in its entirety. The .NET framework automatically appends the word Controller after the controller name you provide. So, when you run the application, it understands Person
as PersonController
.
This URL now directs control to PersonController
and, within it, to the Home
action, which contains a return statement.
You might wonder how the control knows which view to return since we haven't explicitly provided the view's name in the return statement. Well, it determines the view to return based on the action name. That's why it's crucial for the action and view names to match, within a folder whose name corresponds to the controller that contains those actions.
This is why we organize views within a folder named Person (matching the controller's name). If there were other controllers with different views, we would create separate folders for those views, each named after the respective controller.
With these adjustments, execute the application, and it will work as expected.
The application's flow is as follows: PersonController -> Home action -> Home view -> Click hyperlink -> PersonController -> Message action -> Message view.
This basic flow can be enhanced by parameter passing to the action and using the id
part of the URL defined in the RouteConfig
class.
Avoid hardcoded message in the view
To make the message in the view more flexible and avoid hardcoding it, you have a few options:
1. Pass the Message as an Argument
You can pass the message as an argument directly to the Message
action:
public ActionResult Message()
{
return view("Hello World!!");
}
This approach provides a straightforward way to customize the message displayed in the view.
2. Pass the message as an id in the URL
Alternatively, you can pass the message as an id in the URL. In the Home view, use the ActionLink
method to pass the message as a parameter:
@Html.ActionLink("click","Message","Person", new { id = "Hello World!!"});
In the Person
controller's Message
action, receive the passed parameter from the ActionLink
method as an argument to the Message
action:
public ActionResult Message(string id)
{
return view(id);
}
and in the view, you can use the model to display the message:
@model string
<h2>@Model</h2>
This method allows you to dynamically change the message by altering the URL.
3. Directly Load the Page Using URL
You can also load the page directly using the URL structure: {controller}/{action}/{id}. In your case, it would be Person/Message/Hello World!!
If you want to use a parameter name other than id (e.g., message), you need to change the name in the RouteConfig
class:
defaults: new { controller = "Person", action = "Home", message = UrlParameter.Optional }
Here, the message parameter is set as optional. You can also provide a default value if you don't want it to be optional. This change allows you to use a different parameter name while maintaining the desired functionality.
Moving Further
Instead of displaying a message, let's now focus on showing a list of person names. The procedure remains similar to what we've done before. The only difference is that instead of passing a message to the view, we'll be passing a list of names to be displayed.
Let's add another hyperlink to the homepage for displaying the list of persons. You already know how to create a hyperlink using the ActionLink
method. Name this hyperlink List_of_Person.
For the actionName
parameter of the ActionLink
method, specify the name of the action that will handle this task when the hyperlink is clicked. Let's create a separate action specifically for displaying the list of persons and name it ShowPerson
.
@Html.ActionLink( "List_of_Person", "ShowPerson" , "Person" )
In order to display a list of person names when the List_of_Person
link is clicked, we'll adhere to object-oriented principles. For this purpose, we need a class that will provide the necessary data. In the MVC architecture, these classes are known as Models. Therefore, we'll create a model class named Person
to serve as our data source.
The sequence of data flow follows this path: Controller -> Model (if needed) -> Controller (again) -> View -> Controller.
Unlike earlier scenarios where Models were not required, here, a Model is essential to supply the list of person names to the View. Our Person
model class will consist of two properties: FirstName
and LastName
.
This Model will enable us to provide the data needed to display the list of person names effectively.
Creating a Model
Great, let's proceed with creating the model and the associated view for displaying a list of persons:
- In the Solution Explorer, right-click on the Models folder and select "Add" -> "Class."
- Name the class file Person.cs and click the "Add" button.
- Inside the
Person
class file, define two automated properties for first name and last name:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
This Person
class will represent individual persons and their names.
Now, let's create an action named ShowPerson
in the PersonController
to display a list of persons. This action will populate a list of Person
objects and pass it to the view.
public ActionResult ShowPerson()
{
List<person> persons = new List<person>()
{
new Person { FirstName = "Sherlock", LastName = "Holmes" },
new Person { FirstName = "James", LastName = "Watson" }
};
return view(persons);
}</person></person>
In the ShowPerson
action, we create a list of Person
objects, each representing an individual with a first name and a last name. This list represents the list of persons to be displayed in the view.
Now, let's create a view that will display the list of persons. This view will receive the list of persons as its model.
- Right-click on the Person folder inside the Views folder.
- Select "Add" -> "View."
- Check the checkbox for creating a strongly typed view.
- From the "Model class" dropdown, select "Person (UrlMapping.Models)."
- From the "Scaffold template" dropdown, select "List."
- Click the "Add" button.
With these steps, a view named "ShowPerson" will be added to the Person folder in the Views folder. This view is strongly typed to receive a list of Person
objects as its model.
You have now successfully created the model and the associated view for displaying a list of persons. When you execute the ShowPerson
action, it will display the list of persons using the ShowPerson
view.
Now modify the ShowPerson
view as
@model IEnumerable<CodeProject.Models.Person>
@{
ViewBag.Title = "ShowPerson";
}
<h2>ShowPerson</h2>
<table>
<tr>
<th>
@Html.DisplayNameFor(model => model.FirstName)
</th>
<th>
@Html.DisplayNameFor(model => model.LastName)
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
@Html.DisplayFor(modelItem => item.LastName)
</td>
</tr>
}
</table>
Now, run your application by pressing Ctrl+F5, and it should work as expected. When you navigate to the ShowPerson
action by clicking the List_of_Person hyperlink on the homepage, it will display the list of persons using the ShowPerson
view.
If you encounter any issues or have further questions, feel free to ask for assistance. Good job on creating your MVC application!
Points of Interest
This article marks my initial contribution to the CodeProject community. As a newcomer to MVC architecture, I faced challenges when building my first application due to the scarcity of beginner-friendly resources, especially since MVC was relatively new in the market at the time. Motivated by this, I decided to share my learning experience and insights. My hope is that this article will serve as a valuable resource for fellow beginners who are venturing into the world of MVC development. If you have any feedback or questions, please feel free to reach out; I'm here to assist you on your learning journey.