MVC 5 Attribute Routing Made Only Slightly Easier to Understand

MVC 5 Attribute Routing

I’m studying the Microsoft MVC 5 Framework.  As part of my study practice, I force myself to write an article on the subject of whatever module I happen to be on.  This helps me cement the idea in my own head while sharing my perspective on the lesson.
Hope this helps someone…..anyone. 😉
In the Model View Controller (MVC) framework, Routes determine which controller and method to execute for a specific URL.
A slightly easier way to state this is…  routes tie specific set of code to website URL.

New in MVC 5, Microsoft introduced a cleaner way to do custom routes
This is an example of the old way to do routes, you might see it somewhere on a project.
RouteConfig.cs
routes.MapRoute(
    “MoviesByReleaseDate”,
    “movies/released/{year}/{month}”,
    new { controller = “Movies”, action=”ByReleaseDate”},
    new { year = @”2017|2018″, month = @”\d{2}” });
Controller code is not connected to the RouteConfig so if action name change is made in either one but not both, we have a big problem.
Instead of creating a messy RouteConfig file with lots of custom routes in it,  we can now add custom routes by adding an attribute to the corresponding action.
To enable attribute routing we have to add a line to the RouteConfig file.
// EnableAttribute Routing 
routes.MapMvcAttributeRoutes();

The entire file with new and old code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace Vidly
{
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute(“{resource}.axd/{*pathInfo}”);

            // Enable Attribute Routing 
            routes.MapMvcAttributeRoutes();

            routes.MapRoute(
                “MoviesByReleaseDate”,
                “movies/released/{year}/{month}”,
                new { controller = “Movies”, action=”ByReleaseDate”},
                new { year = @”2017|2018″, month = @”\d{2}” });

           routes.MapRoute(
                name: “Default”,
                url: “{controller}/{action}/{id}”,
                defaults: new { controller = “Home”, action = “Index”, id = UrlParameter.Optional }
            );
        }
    }
}
Attribute Routes are added to the controller. In this case the MoviesController.cs file.
Example Attribute Route:
//Attribute Routes
[Route(“moives/released/{year}/{month:regex(\\d{2}):range(1, 12)}”)]
public ActionResult ByReleaseYear(int year, int month)
{
    return Content(year + “/” + month);

}

In the example above, the month has a regex applied to it to match a pattern.
Will accept  2 digits  \\d{2} and between a range of 1 to 12
There are other constraints we can apply that are supported by the framework

  • Min
  • Max
  • Minlength
  • Maxlength
  • Int
  • Float
  • Guid

Google the term, “ASP.NET MVC Attribute Route Constraints” and you’ll find lots of online resources to help you.

Razor Views in C# MVC – C# Code and HTML Coexisting Together

Razor Views in C# MVC

How C# Code and HTML Coexist Together

Tonight’s study topic is Razor Views in C# MVC 5.

Here are two good resources for this topic.

Paid access to Mosh Hamedani’s Complete ASP.net MVC 5 Course. This is covered in video 16 of his course.

Also helpful, was this YouTube video that is part of a larger MVC tutorial that I really like and refer to often

VIDEO: Razor View Syntax

What are Razor Views and What Do They Do?

Specific to C# MVC, Razor Views are code snippets with special syntax made up of C# code and HTML/CSS. The C# logic can interact with and output HTML and CSS elements/attributes dynamically.

With Razor Views, we use the @ symbol to switch between C# code and HTML. 

A simple example of printing numbers from 1 to 10 using Razor.

@for {int i = 1; i <=10; i++)
{
 <b>@i</b>
}

The Output would be: 1 2 3 4 5 6 7 8 9 10
Inside the brackets, Razor sees the <b>@i</b> and knows to render the C# variable i when its proceeded with an @ character then Razor sees the angle brackets and switches back in to HTML parsing mode.

If we didn’t want to use HTML we could change the <b> tag to <text> and output would just be text without the HTML.

The most important thing to understand and remember about Razor Views is the context switching in the parser is based on detection of specific characters.

@ character starts the C# parser but HTML & text won’t parse until Razor see a tag wrapped in angle brackets. We are just switching back and forth between to parsing modes. Make sense?

The loop is C# code but the output is HTML.
In ASP Classic and .Net, the Response Object would handle the HTML output to the browser from inside the loop.

Here are two more examples to help us cement the idea in our brains.

1. A simple date:
@{
   int day = 24;
   int month = 08;
   int year = 2020;
}
Date is @day-@month-@year
Output = Date is 24-08-2020


2. Loop thru images in folder
@for (int i = 1; i <= 5; i++)
{
  <img src="~/Images/@(i).png" />
}

Notice how in the sample above, we put the variable inside the parenthesis. Why, when we didn’t do this for the date example above?

Because if we don’t C# will try and read i. and an object with a property so we have to wrap it in parenthesis. This tell the Razor syntax that we are just trying to concatenate the values.

Razor View Code Blocks

In Razor Views we define code blocks using @{}.

@{
 int SumOfEvenNumbers = 0;
 int SumOfOddNumbers = 0;

 for(int i=1; i<=10; i++)
 {
  if(i %2==0)
  {
    SumOfEvenNumbers = SumOfEvenNumber + 1;
  }
  else
  {
    SumOfOddNumbers = SumOfOddNumbers + 1;
  }
 }
}

<h3>Sum of Even Numbers = @SumOfEvenNumbers</h3>
<h3>Sum of Odd Numbers = @SumOfOddNumbers</h3>

Razor View Comments

Razor View multi-line code comments are very similar to JavaScript and CSS that use the asterisk and forward slash, /*  */, to wrap comments.

Razor View multi-line comments use ampersand and asterisk in same way. @* to start a multi-line comment and *@ to end it. (See code example below)

What’s in the Razor View Example Below?

H2 tag class name is dynamically selected based on  logic, if Model.Customers.Count is greater than 5 then change the CSS class of the H2 element to “popular”.

Also, inside the <ul> tags, Razor View code loops through the list of customers and outputs the name.  

Sample C# Razor Code Example:

@model  Vidly.ViewModels.RandomMovieViewModel
@{
    ViewBag.Title = "Random";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
 
@*
    This is a comment
    on multiple lines
*@
 
@{
    var className = Model.Customers.Count > 5? "popular": null;
}
 
<h2 class="@className">@Model.Movie.Name</h2>
 
@if (Model.Customers.Count == 0)
{
    <text>No one has rented the movie before.</text>
}
 
else 
{
    <ul>
        @foreach (var cusomter in Model.Customers)
        {
            <li>@cusomter.Name</li>
        }
     </ul>
}