Controllers in ASP.NET Core

Controllers in ASP.NET Core

Controllers are the brain of an ASP.NET Core MVC application. They process incoming requests, perform operations on Model data and selects Views to be rendered to the user. Controllers are stored inside the Controllers folder in the root of the web application. They are basically C# classes whose Public methods are known as Action Methods. These Action Methods handles the HTTP request and prepares the response to be sent to the client.

View is a user interface. View displays data from the model to the user and also enables them to modify the data. A View is a user interface that displays data from the model to the user browser. They resides inside the Views folder in the root of the application.

Views folder contains a separate folder for each controller with the same name as controller and inside these folders we have views for the current controller.

For example, views of HomeController, resides in ‘Views > Home’ folder. In the same way, views which will be rendered from StudentController, will resides in ‘Views > Student’ folder.

Creating Controllers

Start by creating a new ASP.NET Core Web Application in your Visual Studio 2017. Select the Empty Template, framework as .NET Core and version as ASP.NET Core 2.0.

Add the following services and configuration inside the Startup.cs as highlighted by the code below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;

namespace UnderstandingControllers
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseDeveloperExceptionPage();
            app.UseStatusCodePages();
            app.UseStaticFiles();
            app.UseMvc(routes =>
            {
                // Default Route
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

Create a Controllers Folder in the root of your application by right clicking the project name and selecting Add/New Folder. Rename the folder as ‘Controllers’.

create controllers folder

Now right click on the Controllers folder and select Add ➤ Controller. You will see a new dialog window opens up, in this window select the first option – MVC Controller – Empty and click the Add button.

adding a new controller

Give the Controller name as ‘HomeController’ and click the Add button.

The Controller will be created with the following code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;

namespace UnderstandingControllers.Controllers
{
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }
    }
}

Your newly created controller class derives from a Controller base class and has 1 action method by the name of ‘Index’. The Index Action only renders a View to the Client.

You need to create an Index View inside the Views/Home folder. The shortcut method for this is by right clicking the Index text in VS 2017, and then on the options you see select Add View. The below image explains this:

adding a view

After that you will get Add MVC View dialog box. In this dialog box make sure you do:

1. View name: Index
2. Template: Empty (without model)
3. Create a partial view: uncheck
4. Use a Layout Page: uncheck

Finally click the Add button to create this View. See the below image for reference:

add mvc view dialog

The Index View will be created inside the ‘Views/Home’ folder. The Views and Home folder will be created automatically instead of you creating them manually one-by-one.

The created View will have the HTML code shown below:

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
</body>
</html>

[/charp]

Inside the body tag add the following line:



<body>
    Welcome from <b>Index View</b> of <b>Home Controller</b>
</body>

The view will need built in tag helpers to create links from routes. Therefore create a view imports file called _ViewImports.cshtml inside the Views folder and add to it the code shown below:

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Run your application and you will see the View rendered on the browse like shown by the following image:

Index view rendered

Adding Bootstrap 4

Bootstrap is an HTML, CSS and JavaScript framework for making modern web design. For the next sections I will need to add it to my application.

To add Bootstrap to the project I will first need to add Bower Configuration File (bower.json). So right click the project in the solution explorer and select Add ➤ New Item.

The Add New Item dialog box will show up. On the left section of this dialog, select Installed ➤ ASP.NET Core ➤ Web. Then on the middle section select Bower Configuration File and click the Add button (see the below image).

bower

The bower.json file will be added and will open for editing in Visual Studio.

Right click the bower.json file in solution explorer and select Manage Bower Packages. See the below image for this:

manage bower packages

The ‘Manage Bower Packages’ window will open up. Here you click the Browse Tab and on the search box type – ‘bootstrap’.

The bootstrap option will show up on the section below the search box. Select it, then on the right side choose its latest version and click the Install button to add Bootstrap to your project.

The below image shows this:

installing bootstrap

In a few seconds time Bootstrap will be installed and ready to be applied in your project.

If you open the bower.json file you will find the bootstrap gets added inside the dependencies section:

{
  "name": "asp.net",
  "private": true,
  "dependencies": {
    "bootstrap": "v4.1.3"
  }
}

The location of Bootstrap is inside the wwwroot ➤ lib ➤ bootstrap folder.

bootstrap location

Transfer Data from View to Controller

Data from View is transferred to the Controller in the form of Query string, form values and parameters parsed from the URL. These are collectively known as context data.

So in your controller you can get this Context Data using 3 methods which are:

1. Controller’s request property.
2. Receive the data as a parameter to an action method.
3. Model Binding.

1. Controllers Request Property – Request.Form

The Request property of the Controller class returns an HttpRequest object that describes the request received from the client.

The HttpRequest contains a Form property which returns a dictionary of form data. You can use the ‘Form’ property to get the data transferred from the View.

Let’s create a small example to understand it.

First you need to create a form inside the Index View. So change the Index View of the Home Controller code as given below:

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
    <link rel="stylesheet" asp-href-include="lib/bootstrap/dist/css/bootstrap.css" />
</head>
<body>
    <div class="container">
        <form method="post" asp-action="ReceivedDataByRequest">
            <div class="form-group">
                <label>Name:</label>
                <input class="form-control" name="name" />
            </div>
            <div class="form-group">
                <label>Sex:</label>
                <select class="form-control" name="sex">
                    <option value="M">Male</option>
                    <option value="F">Female</option>
                </select>
            </div>
            <button class="btn btn-primary" type="submit">Submit</button>
        </form>
    </div>
</body>
</html>

Seeing the code from the top, I have applied the bootstrap.css link on the page head section. I have used the asp-href-include=”css-path” tag helper which will create the href attribute for the link tag.

With bootstrap I can now do some good designing. The css classes like container, form-group, form-control, btn btn-primary are bootstrap classes that are used for the designing of the form.

I have created a form tag that contains 2 important controls – ‘name’ of type input & ‘sex’ of type select. User will fill or select a value on these controls and click the submit button. The values of these controls will then be transferred to the Controller. I have provided the name for these 2 controls as ‘name’ and ‘sex’. Note that the label controls are only for displaying purpose.

See the Form tag which has the asp-action=”ReceivedDataByRequest” tag helper. This tag helper creates the action property for the form. So this means in my case my controller action method by the name of ‘ReceivedDataByRequest’ will be called on the submit button click.

Now I have to create ‘ReceivedDataByRequest’ action method in my Home Controller. This action method will receive the form’s data sent by the View. So add the below code to create this action method:

public IActionResult ReceivedDataByRequest()
{
    string name = Request.Form["name"];
    string sex = Request.Form["sex"];
    return View("ReceivedDataByRequest", $"{name} sex is {sex}");
}

Now look how I am capturing the form’s value in the action method using the Request.Form. It returns the dictionary of form’s data.

So Request.Form[[“name”]] will give me the value of the name input control and Request.Form[[“sex”]] will give the value selected by the user for the select control in the form.

Note that I am calling another View by name ‘ReceivedDataByRequest’ at the end of the Action method. This is done by another signature of the View method which takes 2 parameters and is shown below:

View("ReceivedDataByRequest", $"{name} sex is {sex}")

The 1st parameter is for the View name to be rendered and 2nd for the data in object form that will be transferred to the view.

Now create the ‘ReceivedDataByRequest’ inside the Views ➤Home folder with the following code:

@model string
@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>ReceivedDataByRequest</title>
</head>
<body>
    <h1>@Model</h1>
</body>
</html>

This View accepts the string data so i have defined the model as – @model string. Finally I have shown that data inside the h1 tag like @Model. So whatever the action method passes to this View will be displayed inside the H1 tag.

Now run your application, fill the form and press the submit button. Your submitted values will be displayed on the browser, as shown by the following image:

fetching data from view in controller using request.Form

2. Receive the data as a parameter to an action method

Another method to fetch the context data from View in the Controller is by providing action method parameters.

The form has 2 controls and I can declare parameters on the action method whose names correspond to the form controls. This makes MVC to know that it will have to transfer the forms values to these 2 parameters.

So simply add a new action method by the name ‘ReceivedDataByParameter’ to the Home Controller. The Code for it is given below:

public IActionResult ReceivedDataByParameter(string name, string sex)
{
    return View("ReceivedDataByParameter", $"{name} sex is {sex}");
}

See the 2 parameters I have provided to this Action method and these have the names same like the 2 control names (‘name’ & ‘sex’).

Make a small change on the Index View by changing the asp-action=”ReceivedDataByRequest” tag helper to asp-action=”ReceivedDataByParameter”.

The changed code is highlighted below:

<form method="post" asp-action="ReceivedDataByParameter">
    <div class="form-group">
        <label>Name:</label>
        <input class="form-control" name="name" />
    </div>
    <div class="form-group">
        <label>Sex:</label>
        <select class="form-control" name="sex">
            <option value="M">Male</option>
            <option value="F">Female</option>
        </select>
    </div>
    <button class="btn btn-primary" type="submit">Submit</button>
</form>

Add a new View inside the Views ➤Home folder and name it ‘ReceivedDataByParameter’. It also receives Model Value of string type and displays the model value in the h1 tag. Check its code as shown below:

@model string
@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>ReceivedDataByParameter</title>
</head>
<body>
    <h1>@Model</h1>
</body>
</html>


Run the application and fill the form. On clicking the submit button you will get to see your form controls values displayed on the browser. Check the below image:

fetching data from view in controller using action method parameters

Note: MVC will also transfer the QueryString values to action method parameters.

3. Model Binding

In Model Binding you will have to create a Model, which is basically a class, inside the Models folder.

Then you have to map this model class with the form.

Finally to get the values in the Controller, include this model type parameter in the Action method.
MVC will know that you done Model Binding and so it will automatically fill the values from the form controls to the Model class.

So first create a ‘Models’ folder in your application root directory and add a new class by name ‘Person.cs’. Include the following code to this class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace UnderstandingControllers.Models
{
    public class Person
    {
        public string name { get; set; }
        public string sex { get; set; }
    }
}

The class has 2 public properties that MVC will automatically fills with the values from the Form’s Controls.

Next add the ‘ReceivedDataByModelBinding’ Action in the Home Controller as shown below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using UnderstandingControllers.Models;

namespace UnderstandingControllers.Controllers
{
    public class HomeController : Controller
    {

        // removed for clarity
        
        public IActionResult ReceivedDataByModelBinding(Person person)
        {
            return View("ReceivedDataByModelBinding", person);
        }
    }
}

This action takes the parameter of type ‘Person’ and therefore MVC knows that I have applied Model Binding to this Action. On the last line of the code I am simply returning the Person’s object to the ‘ReceivedDataByModelBinding’ View. So it means this view will accept Model object of type person.

Before creating the ‘ReceivedDataByModelBinding’ View, import the Model namespace inside the _ViewImports.cshtml file so that in my Views I can directly access the Person class without having to write its full namespace. The Code for this is highlighted below:

@using UnderstandingControllers.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Now create the ‘ReceivedDataByModelBinding’ View inside the Views/Home folder with the code given below, the View is slightly different that the other Views. It accepts model of type Person and I showing the values of the name and sex properties of the Person’s class.

@model Person
@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>ReceivedDataByModelBinding</title>
</head>
<body>
    <h1>@Model.name sex is @Model.sex</h1>
</body>
</html>

Now the final part is creating the Form inside the Index View so that MVC knows the form is mapping with the Person’s class properties (name & sex).

@model Person
@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
    <link rel="stylesheet" asp-href-include="lib/bootstrap/dist/css/bootstrap.css" />
</head>
<body>
    <div class="container">
        <form method="post" asp-action="ReceivedDataByModelBinding">
            <div class="form-group">
                <label>Name:</label>
                <input class="form-control" asp-for="name" />
            </div>
            <div class="form-group">
                <label>Sex:</label>
                <select class="form-control" asp-for="sex">
                    <option value="M">Male</option>
                    <option value="F">Female</option>
                </select>
            </div>
            <button class="btn btn-primary" type="submit">Submit</button>
        </form>
    </div>
</body>
</html>

The point to note here are:

1. The View accepts the model of type person – @model Person
.

2. I have changed the form’s action to ‘ReceivedDataByModelBinding’.

3. The Controls (input & select) are now binding with the name and sex property of the Person’s class. The asp-for=”class_property” is used to bind the control with a property of the class.

Run the application,fill the form and click the submit button. You will see the Model Binding feature comes into play and the forms data is shown by the ‘ReceivedDataByModelBinding’ View as described in the image below:

fetching data from view in controller using model binding

You can download the full codes of this tutorial from the below link:

Download

Conclusion

In this tutorial I explained Controllers and their usage in Core Framework. I hope you find it useful. Next tutorial is – Actions in ASP.NET Core, do check it to.

Share this article -

yogihosting

ABOUT THE AUTHOR

This article has been written by the Technical Staff of YogiHosting. Check out other articles on "ASP.NET Core, jQuery, EF Core, SEO, jQuery, HTML" and more.