Getting Started with ASP.NET MVC 5 - CodeProject

:

ASP.NET is a technology stack that has been around for a while, its latest incarnation being ASP.NET MVC.

I’d like to explore what it takes to get a simple “Hello, World!” up and running with ASP.NET MVC. To get going with Visual Studio, head on over to Visual Studio Community. You will need Visual Studio to follow along with this tutorial.

Now fire up FILE > ASP.NET Web Application and choose an empty ASP.NET project template in C#. Be sure to check the “Add unit tests” checkbox!

You should now have a solution that looks like this:

ASP.NET bare bones solution

Inside the Package Manager Console, type:

Install-Package Microsoft.AspNet.Mvc

Excited, yet? This is your close to the metal ASP.NET MVC application. The good news is, it is an empty canvas. The bad news, well, nothing will work. So, let’s see what it takes to make it work.

The Basic Pattern

ASP.NET MVC is fashioned after the Model-View-Controller design pattern. It gives you a clean-cut separation of concerns and testable code. What I love the most about this pattern is that it embraces the web. Controllers act like URL routers, and fit well in a RESTful paradigm. When you see /Account/Login, you know requests get routed to a method Login inside a controller Account. Now, let’s put this pattern to work.

Model

Create a folder Models inside the main solution. Add a Message class. This model can be something like:

public class Message
{
    public string Greet { get; set; }
}

We also need a repository to house all our data. We can create something like:

public interface IRepository
{
    Message GetMessage();
}

public class InMemoryRepository : IRepository
{
    public Message GetMessage()
    {
        return new Message { Greet = "Hello, World!" };
    }
}

IRepository and InMemoryRepository can go in separate files. We are only concerned with data at this point. The beauty here is that I’ve loosely coupled my data source from the rest of the application. By implementing an IRepository, I can swap out different implementations of this contract. I don’t care what my implementation does, it may connect to SQL Sever or an in memory storage, as long as the contract gets fulfilled.

You can think of the models inside this design pattern as basic contracts. I don’t care how you go about getting data, I only care about a strongly-typed object named Message. This is a nice layer of abstraction that keeps me from worrying about implementation details in the rest of my application.

Controller

Create a Controllers folder inside the main solution, and add a controller named MessageController. Now write:

public class MessageController : Controller
{
    private readonly IRepository repo;

    public MessageController()
    {
        repo = new InMemoryRepository();
    }

    public MessageController(IRepository repo)
    {
        this.repo = repo;
    }

    public ActionResult Index()
    {
        var vm = repo.GetMessage();
        return View(vm);
    }
}

Controllers must inherit from the Controller base class and have “Controller” as past of the name. So, for example, MessageController. My default constructor initializes the repo from which I get data. The Index method is an action method that becomes part of the URL. Inside the action method, I use repo to get the view model and pass it right into the view.

I have implemented a poor man’s dependency injection in the second constructor which I’ll use when I write unit tests.

Unit Testing

The idea behind unit tests is to give us a level of confidence that our solution will work. Unit tests helps us understand the problem we are trying to solve in code. Following the MVC design pattern frees us from implementation details. The interfaces I’ve already defined fit well within the MVC paradigm. I am only concerned with the contracts I’ve defined to test my code.

Inside the Tests project. Add a unit test and type:

[TestClass]
public class MessageControllerTests
{
    [TestMethod]
    public void MessageContollerGetIndex()
    {
        var target = new MessageController(new MockRepository());
        var result = target.Index() as ViewResult;
        Assert.IsInstanceOfType(result, typeof(ViewResult));
        Assert.IsNotNull(result);
        var vm = result.Model as Message;
        Assert.IsInstanceOfType(vm, typeof(Message));
        Assert.IsNotNull(vm);
        Assert.IsTrue(vm.Greet == "My mocked greeting");
    }

    private class MockRepository : IRepository
    {
        public Message GetMessage()
        {
            return new Message { Greet = "My mocked greeting" };
        }
    }
}

You will need to add the Microsoft.AspNet.Mvc package to the test project. This unit test injects my mocked repository into the MVC controller and checks the results. Notice how results are not based on any implementation details. It gets based on contracts and the flow of data I've defined in the solution. With this unit test, I’m guaranteed well written code.

The awesome thing is unit tests challenge you to think about the problem as abstractions. This frees you from 1970s spaghetti code, and empowers you to write reusable components. This is what Object Oriented Programming is all about.

Now, head over to Test Explorer. Hit Ctr-B to build and Crt-R-A to run all tests, watch for the green light.

Passing unit test

Beautiful. Now we can focus on the last-but-not-least part of the solution which is the front-end view.

View

Before we wrap things up, I’d like you to configure Visual Studio in a way that makes it easy to develop web applications.

First, right click the main solution and click Properties. Set the web project as the single startup project.

Visual Studio solution configuration

Now right click the web project and click Properties > Web. Let’s set IIS Express as the default and prevent Visual Studio from running the browser.

Visual Studio project configuration

With this setup, we get control of the browser and tell Visual Studio which project to run. Having control of the browser is key so we can debug JavaScript inside the browser and not in Visual Studio.

For one last bit of configuration, create an App_Start folder and add a RouteConfig.cs class. Type:

public static class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.MapRoute("Default", "{controller}/{action}");
    }
}

With this, we are telling the framework to ignore specific handlers and map the Controller / Action in the application. This enables simple RESTFul APIs that map to a specific controller and action method.

Create a Global.asax in the solution and write:

public class Global : HttpApplication
{
    protected void Application_Start(object sender, EventArgs e)
    {
        RouteConfig.RegisterRoutes(RouteTable.Routes);
    }
}

That should do it, now we can right click the Views\Message folder and add a view. Make sure you follow the same naming conventions. The MVC controller will look for a Message folder inside Views, when the framework renders the view. The prompt should look like this:

Adding a view

Type:

@model AspNetMvcHelloWorld.Models.Message
@{ Layout = null; }
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Message</title>
    </head>
    <body>
        <h1>@Model.Greet</h1>
    </body>
</html>

If you notice squiggles getting thrown, it is because it’s missing a views Web.config. Being a framework built on top of ASP.NET, it needs to know what handlers will render front-end requests.

Create a Web.config inside the Views folder and put:

<?xml version="1.0"?>
<configuration>
  <configsections>
    <sectiongroup name="system.web.webPages.razor" 

     type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, 
     System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
      <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, 
       System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, 
       PublicKeyToken=31BF3856AD364E35" requirepermission="false"></section>
      <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, 
       System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, 
       PublicKeyToken=31BF3856AD364E35" requirepermission="false"></section>
    </sectiongroup>
  </configsections>
  <system.web.webpages.razor>
    <host factorytype="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, 
     Version=5.2.2.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"></host>
    <pages pagebasetype="System.Web.Mvc.WebViewPage">
      <namespaces>
        <add namespace="System.Web.Mvc"></add>
        <add namespace="System.Web.Mvc.Html"></add>
        <add namespace="System.Web.Routing"></add>
      </namespaces>
    </pages>
  </system.web.webpages.razor>
</configuration>

At the end, your solution should look something like this:

ASP.NET MVC final solution

That’s a wrap, hit F5 and go to /Message/Index. On my machine, I get http://localhost:65023/Message/Index.

Conclusion

I hope you can see how little effort it takes to follow the MVC design pattern. What we now have is an open sandbox ready to have all kinds of good ideas written on top of it.

The framework plays nice because it doesn’t infringe upon your imagination. The ASP.NET MVC framework is simple enough to be out of your way. And embraces many of the good parts we see on the web like separation of concerns and implementation hiding.

If interested, you can check out the entire solution on GitHub.

The post Getting Started with ASP.NET MVC 5 appeared first on BeautifulCoder.NET.