Skip to contentSkip to author details

Getting your head around ASP.NET MVC(Model-View-Controller) CORE

Written by Jeff Tyler
 programming  .NET  .NET Core

When I made the switch from Web Forms to MVC a few years back. I thought my head was going to explode. It's loose coupling allows it to do a lot of magic for you. As great as magic is, it can take a lot to get your head around it.

For this tutorial I am going to assume that your using ASP.NET CORE if your not then some of this won't apply but most MVC architectures work in a similar manner.

Definitions
MVC - Model-View-Controller
Model - The data to display
View - The visual representation of the model like HTML or JSON
Controller - A class with methods(called actions) that decides which view and model should be used
Routing - the URL path to reach a controller and action

First open Visual Studio 2017 and create an asp.net core mvc application and name it whatever you want.

Before we get started something that should be known. Asp.Net core has a focus on dependency injection. A simple explanation of dependency injection hopefully this helps.

Normally when you instantiate an object with dependencies you have to do it something like this

var context = new Context();
var instantiatedClass = new InstantiatedClass(context);

If you have to create an instance of InstantiatedClass then this code has to also be duplicated. If the context class had parameters then it would also have to be instantiated and you wind up with dependencies all through your code that is hard to get out, and if you change anything you have to change it everywhere.
Dependency allows you to register all of the classes in one place and when you need the one of the classes you request it from the dependency injection and it gives you an instantiated class ready to go.
I will show later how to use it in an MVC and hopefully it will make since.
Now let's take a peak at some code and see if we can start making since of what they have given us.
Open StartUp.cs and find

  public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
        }

This is where you register things with the dependency injector. Here is where you would register things like EntityFramework or AutoMapper and even your own classes if you want them to be registered in the dependency injector. As you can see there is already one thing added which is used to register all of the components needed in MVC. This will get you started without needing to modify anything. There is also an AddMvcCore method that only loads the minimum expecting you to register the pieces you need. Basically AddMvc adds most of the things that you might need as well some things that you may not need. AddMvcCore adds nothing that you don't need and the bare minimum of what you do need. Expecting you to pick and choose what is required.

Next lets look at the configure method

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseBrowserLink();
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            app.UseStaticFiles();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }

This method is used to set up the pipeline. MVC uses a concept known as middleware. When a request comes in it starts at the beginning of the pipeline and moves through until the end and comes back with a response. You can do things like authorization checking for JWT Tokens or many other useful things. For now though we only need what they have.

The if condition sets up error handling between production and development.
The app.UseStaticFiles allows you to load things like CSS from the wwwroot folder and can be configured for other folders as well.

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });

This is the important piece of code.
This piece of code is the place where you get to tell the application how to do it's magic with routing.
The template is the end of the url after the domeain.
The = sign sets a default in this case home for the controller and index for the action.
The ? makes it an optional route parameter.
The only two pieces that are required is the controller and action.
So as an example
Domain.com = Controller: Home Action: Index
Domain.com/home/ = Controller: Home Action: Index
Domain.com/home/index = Controller: Home Action: Index
Domain.Com/home/detail = Controller: home Action: Detail
Domain.com/other/ = Controller: other Action: index
Domain.com/other/lives = Controller: other Action: lives
Domain.com/home/detail/1 = Controller: home Action: Detail Id:1

So now we know where things are going. Lets see what it's doing.
Look in the controllers folder
There is a HomeController. The name minus the controller is the controller portion of the route. So anything at domain.com/home is going to look into here for a method that matches the action.
So lets look at the Index method since it is the default.

        public IActionResult Index()
        {
            return View();
        }

the view method tells MVC to return a razor view. Since we didn't pass in a folder path it looks in the default location which is Views/Controller/Action. So in this case it would be Views/Home/Index.cshtml

So to wrap up the steps are

  1. Take a url and match it to a route
  2. Find the part that is declared as the controller and the action.
  3. Instantiate the controller
  4. Call the method that matches the action
  5. Return the view for the action.