Introduction to Routing

Overview

Routing consists of creating an address for a webpage and open such a webpage when a visitor clicks the link. The actual webpage is either generated from scratch or is incomplete because it depends on the link the user would click.

Practical LearningPractical Learning: Introducing Routing

  1. Start Microsoft Visual Studio
  2. On the main menu, click File -> New Project...
  3. In the New Project dialog box, make sure ASP.NET Web Application (.NET Framework) is selected in the middle list.
    Change the Name of the project to TrafficTicketSystem1
  4. Click OK
  5. In the New ASP.NET Web Application, click the MVC icon and click OK
  6. In the So
  7. In the Solution Explorer, right-click Content -> Add -> Style Sheet
  8. Type TrafficTicketSystem
  9. Click OK
  10. Create some styles as follows:
    body {
        background-color: #FFFFFF;
    }
    
    .bold               { font-weight:      600;               }
    .blue               { color:            #0d3bcf;           }
    .maroon             { color:            #800000;           }
    .top-border         { padding-top:      1.05em;
                          border-top:       1px solid #0d3bcf; }
    .topic-title        { color:            maroon;
                          padding-bottom:   0.25em;
                          border-bottom:    1px solid gray;    }
    .menu-holder        { margin:           auto;
                          width:            400px;             }
    .tm-contents        { margin:           auto;
                          width:            500px;
                          height:           2.75em;
                          background-color: #084a90;
                          border:           1px solid black;   }
    .tm-list            { list-style:       none;              }
    .tm-list li         { float:            left;              }
    .tm-list li a       { padding:          8px;
                          display:          block;
                          text-align:       center;
                          color:            azure;
                          text-decoration:  none;              }
    .tm-list li a:hover { background-color: #1f88cf;
                          border-left:      1px solid white;
                          border-right:     1px solid white;   }
    .navbar-fixed-top   { background-color: #084a90;           }
    .common-font        { font-family:      Georgia, Garamond, 'Times New Roman', serif; }
  11. In the Solution Explorer, expand App_Start and double-click BundleConfig.cs
  12. Change the document as follows:
    using System.Web;
    using System.Web.Optimization;
    
    namespace TrafficTicketSystem1
    {
        public class BundleConfig
        {
            // For more information on bundling, visit https://go.microsoft.com/fwlink/?LinkId=301862
            public static void RegisterBundles(BundleCollection bundles)
            {
                bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                            "~/Scripts/jquery-{version}.js"));
    
                bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                            "~/Scripts/jquery.validate*"));
    
                // Use the development version of Modernizr to develop with and learn from. Then, when you're
                // ready for production, use the build tool at https://modernizr.com to pick only the tests you need.
                bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
                            "~/Scripts/modernizr-*"));
    
                bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
                          "~/Scripts/bootstrap.js",
                          "~/Scripts/respond.js"));
    
                bundles.Add(new StyleBundle("~/Content/css").Include(
                          "~/Content/bootstrap.css",
                          "~/Content/site.css",
                          "~/Content/TrafficTicketSystem.css"));
            }
        }
    }
  13. In the Solution Explorer, right-click Models -> Add -> Class...
  14. Type Camera
  15. Click Add
  16. Change the document as follows:
    namespace TrafficTicketSystem1.Models
    {
        public class Camera
        {
            public int CameraID { get; set; }
            public string CameraNumber { get; set; }
            public string Make { get; set; }
            public string Model { get; set; }
            public string Location { get; set; }
        }
    }
  17. In the Solution Explorer, right-click Models -> Add -> Class...
  18. Type Driver
  19. Click Add
  20. Change the document as follows:
    namespace TrafficTicketSystem1.Models
    {
        public class Driver
        {
            public int DriverID { get; set; }
            public string DrvLicNumber { get; set; }
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public string Address { get; set; }
            public string City { get; set; }
            public string County { get; set; }
            public string State { get; set; }
            public string ZIPCode { get; set; }
        }
    }
  21. In the Solution Explorer, right-click Models -> Add -> Class...
  22. Type Vehicle
  23. Click Add
  24. Change the document as follows:
    namespace TrafficTicketSystem1.Models
    {
        public class Vehicle
        {
            public int VehicleID { get; set; }
            public int DriverID { get; set; }
            public string Make { get; set; }
            public string Model { get; set; }
            public int Year { get; set; }
            public string Color { get; set; }
            public string TagNumber { get; set; }
        }
    }
  25. In the Solution Explorer, right-click Models -> Add -> Class...
  26. Type Violation
  27. Click Add
  28. Change the document as follows:
    namespace TrafficTicketSystem1.Models
    {
        public class Violation
        {
            public int ViolationID { get; set; }
            public int CameraID { get; set; }
            public int VehicleID { get; set; }
            public string ViolationType { get; set; }
            public DateTime ViolationDateTime { get; set; }
            public bool PhotoAvailable { get; set; }
            public bool VideoAvailable { get; set; }
            public DateTime PaymentDueDate { get; set; }
            public double PaymentAmount { get; set; }
            public string ViolationName { get; set; }
            public string ViolationDescription { get; set; }
            public string Vehicle { get; set; }
            public string DriverName { get; set; }
            public string DriverAddress { get; set; }
            public string ViolationLocation { get; set; }
            public string PhotoVideo { get; set; }
        }
    }
  29. In the Solution Explorer, right-click Models -> Add -> Class...
  30. Type TrafficTicketsSystem
  31. Click Add
  32. Change the document as follows:
    using System;
    using System.Collections.Generic;
    
    namespace TrafficTicketSystem1.Models
    {
        public class TrafficTicketsSystem
        {
            public List<Driver> drivers = new List<Driver>();
            public List<Camera> cameras = new List<Camera>();
            public List<Vehicle> vehicles = new List<Vehicle>();
            public List<Violation> violations = new List<Violation>();
    
            public TrafficTicketsSystem()
            {
                cameras.Add(new Camera() { CameraID = 1, CameraNumber = "DGH-38460", Make = "Ashton Digital", Model = "MPH-6000", Location = "Eastern Ave and Ashburry Drv" });
                cameras.Add(new Camera() { CameraID = 2, CameraNumber = "ELQ-79284", Make = "Seaside International", Model = "BL5", Location = "Monroe Str and Westview Rd" });
                cameras.Add(new Camera() { CameraID = 3, CameraNumber = "MSR-59575", Make = "Ashton Digital", Model = "MPH-6000", Location = "Concordia Blvd and Sunset Way" });
                cameras.Add(new Camera() { CameraID = 4, CameraNumber = "DHT-29417", Make = "Woodson and Sons", Model = "NG200", Location = "Temple Ave and Barclay Rd" });
                cameras.Add(new Camera() { CameraID = 5, CameraNumber = "AHR-41518", Make = "Seaside International", Model = "442i", Location = "Chesterwood Rd and Old Dutler Str" });
                cameras.Add(new Camera() { CameraID = 6, CameraNumber = "HTR-93847", Make = "Ashton Digital", Model = "366d", Location = "Monrovia Str at Moon Springs" });
    
                drivers.Add(new Driver() { DriverID = 1, DrvLicNumber = "26 840 681",    FirstName = "Simon",    LastName = "Havers",    Address = "1884 Stewart Ln",       City = "Kittanning",   County = "Armstrong",  State = "PA", ZIPCode = "15638" });
                drivers.Add(new Driver() { DriverID = 2, DrvLicNumber = "273-79-4157",   FirstName = "Terence",  LastName = "McConnell", Address = "8304 Polland Str",      City = "Meadowview",   County = "Washington", State = "VA", ZIPCode = "24361" });
                drivers.Add(new Driver() { DriverID = 3, DrvLicNumber = "A402-630-468",  FirstName = "Patrick",  LastName = "Atherton",  Address = "10744 Quincy Blvd",     City = "Cumberland",   County = "Allegany",   State = "MD", ZIPCode = "21502" });
                drivers.Add(new Driver() { DriverID = 4, DrvLicNumber = "C-684-394-527", FirstName = "Sarah",    LastName = "Cuchchran", Address = "10804 Euton Rd",        City = "Shawnee Land",            State = "VA", ZIPCode = "24450" });
                drivers.Add(new Driver() { DriverID = 5, DrvLicNumber = "928-37-4950",   FirstName = "Michael",  LastName = "Atherton",  Address = "663 Vernon Drv, NW",    City = "Washington",              State = "DC", ZIPCode = "20012" });
                drivers.Add(new Driver() { DriverID = 6, DrvLicNumber = "2938468",       FirstName = "Victoria", LastName = "Huband",    Address = "3958 Lubber Court",     City = "Middletown",   County = "New Castle", State = "DE", ZIPCode = "19709" });
                drivers.Add(new Driver() { DriverID = 7, DrvLicNumber = "851608526",     FirstName = "Patrick",  LastName = "Whalley",   Address = "10227 Woodrow Rd",      City = "Shelbyville",  County = "Bedford",    State = "TN", ZIPCode = "38561" });
                drivers.Add(new Driver() { DriverID = 8, DrvLicNumber = "W639-285-940",  FirstName = "David",    LastName = "Woodbank",  Address = "9703 Abington Ave",     City = "Hurlock",      County = "Dorchester", State = "MD", ZIPCode = "21643" });
                drivers.Add(new Driver() { DriverID = 9, DrvLicNumber = "S-283-942-646", FirstName = "Emilie",   LastName = "Sainsbury", Address = "4048 Utah Rd",          City = "Denville",     County = "Morris",     State = "NJ", ZIPCode = "07961" });
                drivers.Add(new Driver() { DriverID = 10, DrvLicNumber = "860586175",     FirstName = "Kelley",   LastName = "Murray",    Address = "8622 Rutger Farms Str", City = "Rutger Farms", County = "Macon",      State = "TN", ZIPCode = "37122" });
    
    
                vehicles.Add(new Vehicle() { VehicleID = 1, TagNumber = "8DE9275", DriverID = 1, Make = "Ford",     Model = "Focus",     Year = 2000, Color = "Gray"   });
                vehicles.Add(new Vehicle() { VehicleID = 2, TagNumber = "KLT4805", DriverID = 6, Make = "Toyota",   Model = "Corolla",   Year = 2016, Color = "Red"    });
                vehicles.Add(new Vehicle() { VehicleID = 3, TagNumber = "KAS9314", DriverID = 8, Make = "Cadillac", Model = "Escalade",  Year = 2008, Color = "Black"  });
                vehicles.Add(new Vehicle() { VehicleID = 4, TagNumber = "HAK3936", DriverID = 9, Make = "Chrysler", Model = "Crossfire", Year = 2006, Color = "Red"    });
                vehicles.Add(new Vehicle() { VehicleID = 5, TagNumber = "PER2849", DriverID = 1, Make = "Buick",    Model = "LeSabre",   Year = 2012, Color = "Silver" });
                vehicles.Add(new Vehicle() { VehicleID = 6, TagNumber = "MWH4685", DriverID = 7, Make = "Honda",    Model = "Accord",    Year = 1998, Color = "Blue"   });
                vehicles.Add(new Vehicle() { VehicleID = 7, TagNumber = "971384",  DriverID = 5, Make = "BMW",      Model = "325i",      Year = 2015, Color = "White"  });
                vehicles.Add(new Vehicle() { VehicleID = 8, TagNumber = "394815",  DriverID = 2, Make = "Jeep",    Model = "Wrangler",  Year = 1996, Color = "Black"  });
    
                violations.Add(new Violation() { ViolationID =  1, CameraID = 3, VehicleID = 2, ViolationType = "Stop Sign",            ViolationDateTime = new DateTime(2018, 01, 18, 09, 12, 35), PhotoAvailable = false, VideoAvailable = true,  PaymentDueDate = new DateTime(2018, 02, 28), PaymentAmount =  75, ViolationName = GetViolationName("Stop Sign"),            ViolationDescription = DescribeViolation("Stop Sign"),            Vehicle = IdentifyVehicle("KLT4805"), DriverName = GetDriverName("KLT4805"), DriverAddress = GetDriverAddress("KLT4805"), ViolationLocation = IdentifyCamera("MSR-59575"), PhotoVideo = GetPhotoVideoOptions(false, true)  });
                violations.Add(new Violation() { ViolationID =  2, CameraID = 4, VehicleID = 7, ViolationType = "Speed",                ViolationDateTime = new DateTime(2018, 02, 06, 11, 58, 06), PhotoAvailable = false, VideoAvailable = true,  PaymentDueDate = new DateTime(2018, 04, 05), PaymentAmount =  85, ViolationName = GetViolationName("Speed"),                ViolationDescription = DescribeViolation("Speed"),                Vehicle = IdentifyVehicle("971384"),  DriverName = GetDriverName("971384"),  DriverAddress = GetDriverAddress("971384"),  ViolationLocation = IdentifyCamera("DHT-29417"), PhotoVideo = GetPhotoVideoOptions(false, true)  });
                violations.Add(new Violation() { ViolationID =  3, CameraID = 1, VehicleID = 5, ViolationType = "Red Light Steady",     ViolationDateTime = new DateTime(2018, 01, 31, 05, 15, 18), PhotoAvailable = true,  VideoAvailable = false, PaymentDueDate = new DateTime(2018, 03, 10), PaymentAmount = 125, ViolationName = GetViolationName("Red Light Steady"),     ViolationDescription = DescribeViolation("Red Light Steady"),     Vehicle = IdentifyVehicle("PER2849"), DriverName = GetDriverName("PER2849"), DriverAddress = GetDriverAddress("PER2849"), ViolationLocation = IdentifyCamera("DGH-38460"), PhotoVideo = GetPhotoVideoOptions(true,  false) });
                violations.Add(new Violation() { ViolationID =  4, CameraID = 4, VehicleID = 6, ViolationType = "Speed",                ViolationDateTime = new DateTime(2018, 03, 05, 16, 07, 15), PhotoAvailable = true,  VideoAvailable = true,  PaymentDueDate = new DateTime(2018, 04, 22), PaymentAmount =  85, ViolationName = GetViolationName("Speed"),                ViolationDescription = DescribeViolation("Speed"),                Vehicle = IdentifyVehicle("MWH4685"), DriverName = GetDriverName("MWH4685"), DriverAddress = GetDriverAddress("MWH4685"), ViolationLocation = IdentifyCamera("DHT-29417"), PhotoVideo = GetPhotoVideoOptions(true,  true)  });
                violations.Add(new Violation() { ViolationID =  5, CameraID = 3, VehicleID = 1, ViolationType = "Stop Sign",            ViolationDateTime = new DateTime(2018, 01, 18, 14, 22, 48), PhotoAvailable = false, VideoAvailable = true,  PaymentDueDate = new DateTime(2018, 03, 10), PaymentAmount =  60, ViolationName = GetViolationName("Stop Sign"),            ViolationDescription = DescribeViolation("Stop Sign"),            Vehicle = IdentifyVehicle("8DE9275"), DriverName = GetDriverName("8DE9275"), DriverAddress = GetDriverAddress("8DE9275"), ViolationLocation = IdentifyCamera("MSR-59575"), PhotoVideo = GetPhotoVideoOptions(false, true)  });
                violations.Add(new Violation() { ViolationID =  6, CameraID = 2, VehicleID = 2, ViolationType = "Speed",                ViolationDateTime = new DateTime(2018, 04, 12, 08, 16, 22), PhotoAvailable = false, VideoAvailable = true,  PaymentDueDate = new DateTime(2018, 06, 08), PaymentAmount = 100, ViolationName = GetViolationName("Speed"),                ViolationDescription = DescribeViolation("Speed"),                Vehicle = IdentifyVehicle("KLT4805"), DriverName = GetDriverName("KLT4805"), DriverAddress = GetDriverAddress("KLT4805"), ViolationLocation = IdentifyCamera("ELQ-79284"), PhotoVideo = GetPhotoVideoOptions(false, true)  });
                violations.Add(new Violation() { ViolationID =  7, CameraID = 6, VehicleID = 5, ViolationType = "Red Light Flashing",   ViolationDateTime = new DateTime(2018, 01, 28, 22, 14, 53), PhotoAvailable = false, VideoAvailable = false, PaymentDueDate = new DateTime(2018, 03, 02), PaymentAmount =  45, ViolationName = GetViolationName("Red Light Flashing"),   ViolationDescription = DescribeViolation("Red Light Flashing"),   Vehicle = IdentifyVehicle("PER2849"), DriverName = GetDriverName("PER2849"), DriverAddress = GetDriverAddress("PER2849"), ViolationLocation = IdentifyCamera("HTR-93847"), PhotoVideo = GetPhotoVideoOptions(false, false) });
                violations.Add(new Violation() { ViolationID =  8, CameraID = 5, VehicleID = 6, ViolationType = "Speed",                ViolationDateTime = new DateTime(2018, 03, 31, 22, 07, 31), PhotoAvailable = true,  VideoAvailable = false, PaymentDueDate = new DateTime(2018, 05, 15), PaymentAmount =  75, ViolationName = GetViolationName("Speed"),                ViolationDescription = DescribeViolation("Speed"),                Vehicle = IdentifyVehicle("MWH4685"), DriverName = GetDriverName("MWH4685"), DriverAddress = GetDriverAddress("MWH4685"), ViolationLocation = IdentifyCamera("AHR-41518"), PhotoVideo = GetPhotoVideoOptions(true,  false) });
                violations.Add(new Violation() { ViolationID =  9, CameraID = 1, VehicleID = 3, ViolationType = "Red Light Right Turn", ViolationDateTime = new DateTime(2018, 01, 31, 12, 30, 11), PhotoAvailable = true,  VideoAvailable = false, PaymentDueDate = new DateTime(2018, 02, 28), PaymentAmount =  60, ViolationName = GetViolationName("Red Light Right Turn"), ViolationDescription = DescribeViolation("Red Light Right Turn"), Vehicle = IdentifyVehicle("KAS9314"), DriverName = GetDriverName("KAS9314"), DriverAddress = GetDriverAddress("KAS9314"), ViolationLocation = IdentifyCamera("DGH-38460"), PhotoVideo = GetPhotoVideoOptions(true,  false) });
                violations.Add(new Violation() { ViolationID = 10, CameraID = 4, VehicleID = 7, ViolationType = "Speed",                ViolationDateTime = new DateTime(2018, 02, 06, 19, 04, 47), PhotoAvailable = true,  VideoAvailable = true,  PaymentDueDate = new DateTime(2018, 04, 05), PaymentAmount =  85, ViolationName = GetViolationName("Speed"),                ViolationDescription = DescribeViolation("Speed"),                Vehicle = IdentifyVehicle("971384"),  DriverName = GetDriverName("971384"),  DriverAddress = GetDriverAddress("971384"),  ViolationLocation = IdentifyCamera("DHT-29417"), PhotoVideo = GetPhotoVideoOptions(true,  true)  });
                violations.Add(new Violation() { ViolationID = 11, CameraID = 2, VehicleID = 1, ViolationType = "Speed",                ViolationDateTime = new DateTime(2018, 04, 15, 15, 25, 53), PhotoAvailable = true,  VideoAvailable = false, PaymentDueDate = new DateTime(2018, 06, 02), PaymentAmount =  40, ViolationName = GetViolationName("Speed"),                ViolationDescription = DescribeViolation("Speed"),                Vehicle = IdentifyVehicle("8DE9275"), DriverName = GetDriverName("8DE9275"), DriverAddress = GetDriverAddress("8DE9275"), ViolationLocation = IdentifyCamera("ELQ-79284"), PhotoVideo = GetPhotoVideoOptions(true,  false) });
            }
    
            /* This method takes a violation type as argument and produces a simple violation name.
               The main purpose is to reduce the long names of some violations. */
            private string GetViolationName(string type)
            {
                if ((type == "Red Light Steady") ||
                    (type == "Red Light Flashing") ||
                    (type == "Red Light Right Turn"))
                {
                    return "Red Light";
                }
                else
                {
                    return type;
                }
            }
    
            // This method takes a violation type and creates some text that will display an explanation/description of the traffic violation to the driver.
            private string DescribeViolation(string type)
            {
                if (type == "Red Light Steady")
                    return "The vehicle drove through a steady red light. The law in our state requires that when a vehicle approaches a steady red light, it must completely stop and wait for the light to change to green";
                else if (type == "Red Light Flashing")
                    return "The vehicle drove through a red light that was flashing (or blinking). The laws in this state require that if a vehicle comes to a flashing red light, whether it is at an intersection or not, the vechicle must first stop complete, the drive must observe around for pedestrians, animals, and other cars, and then cautiously";
                else if (type == "Red Light Right Turn")
                    return "The vehicle turns to the right without stopping. The laws in our state require that, when a vehicle reaches a traffic light and wants to make a right turn, if the light is red, regardless of any presence or not of another vehicle or pedestrian, the vehicle must first stop completely, and then make the right turn";
                else if (type == "Stop Sign")
                    return "The vehicle did not stop at the Stop sign. The law in our state indicates every non-emergency vehicle to completely stop at every Stop sign, regardless of the presence or absence of incoming or adjacent vehicles";
                else if (type == "Speed")
                    return "The vehicle drove at a speed significantly above the speed limit. The laws in this state require that every non-emergency and non-utility vehicle drives at or below the posted speed limit (or at or below the default speed regulation where the speed is not clearly posted)";
                else
                    return "The vehicle committed some type of infraction";
            }
    
            /* This method takes a tag number as argument.
               It returns a combination of the make model, year, and color of the car. */
            private string IdentifyVehicle(string tagNumber)
            {
                foreach (var car in vehicles)
                {
                    if (car.TagNumber == tagNumber)
                    {
                        return car.Make + " " + car.Model + " (" + car.Year + ", " + car.Color + ")";
                    }
                }
    
                return string.Empty;
            }
    
            /* This method takes a tag number as argument.
               It returns the name of the driver/owner. */
            private string GetDriverName(string tagNumber)
            {
                int driverNbr = -1;
    
                foreach (var car in vehicles)
                {
                    if (car.TagNumber == tagNumber)
                    {
                        driverNbr = car.DriverID;
                        break;
                    }
                }
                foreach(var owner in drivers)
                {
                    if (owner.DriverID == driverNbr)
                    {
                        return owner.FirstName + " " + owner.LastName;
                    }
                }
    
                return string.Empty;
            }
    
            /* This method takes a tag number as argument.
               It returns the complete address of the driver/owner. */
            private string GetDriverAddress(string tagNumber)
            {
                int driverNbr = -1;
    
                foreach (var car in vehicles)
                {
                    if (car.TagNumber == tagNumber)
                    {
                        driverNbr = car.DriverID;
                        break;
                    }
                }
                foreach (var owner in drivers)
                {
                    if (owner.DriverID == driverNbr)
                    {
                        return owner.Address + " " + owner.City + " " + owner.State + " " + owner.ZIPCode;
                    }
                }
    
                return string.Empty;
            }
    
            /* This method takes a camera number as argument.
               This is the camera located where the violation took place.
               The function returns the location and the camera number. */
            private string IdentifyCamera(string cameraNbr)
            {
                foreach(var cmra in cameras)
                {
                    if (cmra.CameraNumber == cameraNbr)
                    {
                        return cmra.Location + " (" + cmra.CameraNumber + ")";
                    }
                }
    
                return string.Empty;
            }
    
            /* This method takes the available status of a photo and video takens during the traffic violation.
               The function returns a sentence that will instructs the driver about how to view the photo or video or the violation. */
            private string GetPhotoVideoOptions(bool photo, bool video)
            {
                var sentence = "";
                var pvAvailable = false;
    
                if (photo == true)
                {
                    if (video == true)
                    {
                        pvAvailable = true;
                        sentence = "To view the photo and/or video";
                    }
                    else
                    {
                        pvAvailable = true;
                        sentence = "To see a photo";
                    }
                }
                else
                { // if (p == false)
                    if (video == true)
                    {
                        pvAvailable = true;
                        sentence = "To review a video";
                    }
                    else
                    {
                        pvAvailable = false;
                    }
                }
    
                if (pvAvailable == false)
                    return "There is no photo or video available of this infraction but the violation was committed.";
                else
                    return sentence + " of this violation, please access http://www.trafficviolationsmedia.com. In the form, enter the citation number and click Submit.";
            }
        }
    }
  33. In the Solution Explorer, right-click Controllers -> Add -> Controller...
  34. In the Add Scaffold dialog box, click MVC 5 Controller - Empty
  35. Click Add
  36. Type Violations to get ViolationsController
  37. Click Add
  38. Change the document as follows:
    using System.Web.Mvc;
    
    namespace TrafficTicketSystem1.Controllers
    {
        public class ViolationsController : Controller
        {
            // GET: Violations
            public ActionResult Index()
            {
                Models.TrafficTicketsSystem tts = new Models.TrafficTicketsSystem();
    
                /* Get the list of violations for our local database.
                 * Store that list of violations in a ViewBag so we can use it in a view. */
                ViewBag.Violations = tts.violations;
    
                return View();
            }
        }
    }
  39. In the document, right-click anywhere inside the Index() method and click Add View...
  40. In the Add View dialog box, make sure the View Name text box displays Index. Click Add
  41. Change the document as follows:
    @{
        ViewBag.Title = "Traffic Violations";
    }
    
    <h2 class="text-center blue common-font bold">Traffic Violations</h2>
    
    <table class="table table-striped common-font">
        <tr class="bold">
            <td class="text-center">Violation ID</td>
            <td>Vehicle and Driver</td>
            <td>Violation Location</td>
            <td>Violation Type</td>
            <td class="text-center">Violation Date</td>
            <td class="text-center">Violation Time</td>
            <td class="text-center">Photo Available?</td>
            <td class="text-center">Video Available?</td>
            <td class="text-center">Payment Due Date</td>
            <td class="text-center">Payment Amount</td>
        </tr>
    @foreach (var infraction in ViewBag.violations)
    {
        <tr>
            <td class="text-center">@infraction.ViolationID</td>
            <td>@infraction.ViolationLocation</td>
            <td>@infraction.Vehicle - @infraction.DriverName</td>
            <td>@infraction.ViolationType</td>
            <td class="text-center">@infraction.ViolationDateTime.ToShortDateString()</td>
            <td class="text-center">@infraction.ViolationDateTime.ToShortTimeString()</td>
            <td class="text-center">@infraction.PhotoAvailable</td>
            <td class="text-center">@infraction.VideoAvailable</td>
            <td class="text-center">@infraction.PaymentDueDate.ToShortDateString()</td>
            <td class="text-center">@infraction.PaymentAmount</td>
        </tr>
    }
    </table>
  42. In the Solution Explorer, under Views, expand Shared and double-click _Layout.cshtml
  43. Type the following code:
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Traffic Ticket System :: @ViewBag.Title</title>
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")
    </head>
    <body>
        <div class="navbar navbar-inverse navbar-fixed-top">
            <div class="container">
                <div class="navbar-header">
                    <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>
                    @Html.ActionLink("Traffic Ticket System", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
                </div>
                <div class="navbar-collapse collapse">
                    <ul class="nav navbar-nav">
                        <li>@Html.ActionLink("Traffic Violations", "Index", "Violations")</li>
                        <li>@Html.ActionLink("About", "About", "Home")</li>
                        <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
                    </ul>
                </div>
            </div>
        </div>
        <div class="container body-content">
            @RenderBody()
            <hr />
            <footer>
                <p class="text-center common-font">&copy; @DateTime.Now.Year - Traffic Ticket System</p>
            </footer>
        </div>
    
        @Scripts.Render("~/bundles/jquery")
        @Scripts.Render("~/bundles/bootstrap")
        @RenderSection("scripts", required: false)
    </body>
    </html>
  44. To preview the result, press Ctrl + F5
  45. Click the Traffic Violations link:

    Introducing Routing

  46. Close the browser and return to your programming environment

A Route Collection

To support routing, the .NET Framework provides a class named RouteCollection. This class is derived from the Collection<T> class of the System.Collections.ObjectModel namespace:

public class RouteCollection : Collection<RouteBase>

The RouteCollection class is defined in a namespace named System.Web.Rounting. As its name indicates, RouteCollection is a collection class used to create and manage a list of items. The class is equipped with all types of properties and methods to add and manage its values.

Besides its members, the RouteCollection class is expanded with many extended methods. For example, to let you specify a routing scheme, the RouteCollection class is equipped with an overloaded method named MapRoute. One of its versions uses the following syntax:

public static Route MapRoute(this RouteCollection routes,
						     string name,
						     string url,
						     object defaults)

The first argument is the name of the route. This name can be anything you want. Here is an example:

using System.Web.Mvc;
using System.Web.Routing;

namespace Exercise1
{
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.MapRoute("Detailed Report", . . .);
        }
    }
}

A Route Pattern

A Web Route is specified using a formula that follows some rules. This is the role of the url argument of the RouteCollection.MapRoute() method. The argument is a string that contains a scheme, called a URL pattern, that resembles the path or address of a webpage. The formula it follows is:

{controller}/{action}/{id}

As you can see, this string uses a few placeholders. The most-left placeholder specifies that a path starts with a controller. Here is an example:

using System.Web.Mvc;

namespace ASPNETMVCRouting1.Controllers
{
    public class ViolationsController : Controller
    {
    }
}

The url argument indicates that the controller is followed by the name of an action method. This means that you must create such a controller. By tradtion, that method is named Details. Here is an example:

using System.Web.Mvc;

namespace ASPNETMVCRouting1.Controllers
{
    public class ViolationsController : Controller
    {
        public ActionResult Details()
        {
            return View();
        }
    }
}

The address of a route ends with a value that can be used to select a webpage or a value to display. This can be a value that uniquely idenfies a page or a record. In most cases (or to make things easier), this value is named id and is of type integer. To get ready to use it, pass it as argument to the action method you are creating. You must anticipate that, at times, the value of this identifier will not be provided, for any reason. Therefore, the method must be able to handle null values. For this reason, the argument must be passed as a possible null. If you are passing it as a primitive type such as an integer, add a question mark to it. Here is an example:

using System.Web.Mvc;

namespace ASPNETMVCRouting1.Controllers
{
    public class ViolationsController : Controller
    {
        // GET: Violations/Details/1
        public ActionResult Details(int? id)
        {
            return View();
        }
    }
}

In the value passed as the url argument of the RouteCollection.MapRoute() method, each factor is included in {} and the placeholders are separated by forward slashes. Here is an example:

using System.Web.Mvc;
using System.Web.Routing;

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

            routes.MapRoute("Detailed Report", "{controller}/{action}/{id}", . . .);
        }
    }
}

The last argument, defaults, is an anonymous object. Therefore, define it using the new operator and curcly brackets. In the brackets, use each of the factors from the url argument and assign the appropriate value. The value you provide is not case-sensitive. This means that in this case, academics is the same as Academics and is the same as ACADEMICS. When you have specified this name, when the webserver is asked to display the webpage, the compiler will look for a controller that has that name in the current Web project. If there is not a controller with that name, the browser will display an error as "The resource cannot be found". Therefore, make sure you provide an existing controller name.

After assigning the name of a controller, specify the name of the desired action to access. If the controller exists, the compiler will look for the indicated action method in the controller class. If the action method doesn't exist in the controller, the browser will display an error as "The resource cannot be found". Therefore, make sure you assign an existing action method to action.

If you are not planning to use an identifier in the address, assign UrlParameter.Optional to Id. If you are planning to use an identifier in the address, assign it to Id. When the webserver is asked to display the webpage, it it finds an identifier with the indicated value, it would display it.

To make your code easy to read, you can apply each argument to the name of the corresponding argument used in the syntax of the method. Here is an example:

using System.Web.Mvc;
using System.Web.Routing;

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

            routes.MapRoute(defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
                            url: "{controller}/{action}/{id}",
                            name: "Detailed Report");
        }
    }
}

Another method of the RouteCollection class indicates a URL scheme that should be ignored. This method is named IgnoreRoute. Its syntax is:

public void IgnoreRoute(string url);

This method takes one argument as a string that contains the URL pattern.

In the action method that handles the route, write code to select a record. Normally, to select a record, you would call a method of the class that handles the collection of records. That collection should (must) provides the means to use the value passed as argument to select a record that be uniquely identified by that value. Once you have selected the record, you can display it in a view.

Practical LearningPractical Learning: Using a Route to Select a Record

  1. Access the ViolationsController.cs file and add a method as follows:
    using System.Net;
    using System.Web.Mvc;
    
    namespace ASPNETMVCRouting1.Controllers
    {
        public class ViolationsController : Controller
        {
            // GET: Violations
            public ActionResult Index()
            {
                Models.TrafficTicketsSystem tts = new Models.TrafficTicketsSystem();
    
                /* Get the list of violations for our local database.
                 * Store that list of violations in a ViewBag so we can use it in a view. */
                ViewBag.violations = tts.violations;
    
                return View();
            }
    
            // GET: Violations/Details/1
            public ActionResult Details(int? id)
            {
                Models.Violation ticket = null;
    
                if (id == null)
                {
                    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
                }
    
                Models.TrafficTicketsSystem tts = new Models.TrafficTicketsSystem();
    
                foreach (Models.Violation infraction in tts.violations)
                {
                    if (infraction.ViolationID == id)
                    {
                        ticket = infraction;
                        break;
                    }
                }
    
                if (ticket == null)
                {
                    return HttpNotFound();
                }
    
                ViewBag.Violation = ticket;
    
                return View();
            }
        }
    }
  2. Right-click anywhere inside the Details() method and click Add View...
  3. In the Add View dialog box, make sure the View Name text box is displaying Details. Click Add
  4. Changesthe document as follows:
    @{
        ViewBag.Title = "Traffic Violation";
    }
    
    <h2 class="text-center common-font maroon bold">Traffic Violation</h2>
    
    <table class="table table-striped details-holder">
        <tr>
            <td class="bold">Violation #:</td>
            <td><span class="form-control">@ViewBag.Violation.ViolationID</span></td>
        </tr>
        <tr>
            <td class="bold">Violation Location:</td>
            <td><span class="form-control">@ViewBag.Violation.ViolationLocation</span></td>
        </tr>
        <tr>
            <td class="bold">Driver/Owner:</td>
            <td><span class="form-control">@ViewBag.Violation.DriverName, @ViewBag.Violation.DriverAddress</span></td>
        </tr>
        <tr>
            <td class="bold">Violation Type:</td>
            <td><span class="form-control">@ViewBag.Violation.ViolationName</span></td>
        </tr>
        <tr>
            <td class="bold">Violation Date</td>
            <td><span class="form-control">@ViewBag.Violation.ViolationDateTime.ToShortDateString()</span></td>
        </tr>
        <tr>
            <td class="bold">Violation Time</td>
            <td><span class="form-control">@ViewBag.Violation.ViolationDateTime.ToShortTimeString()</span></td>
        </tr>
        <tr>
            <td class="bold">Photo Available</td>
            <td><span class="form-control">@ViewBag.Violation.PhotoAvailable.ToString()</span></td>
        </tr>
        <tr>
            <td class="bold">Video Available</td>
            <td><span class="form-control">@ViewBag.Violation.VideoAvailable.ToString()</span></td>
        </tr>
        <tr>
            <td class="bold">Payment Due Date</td>
            <td><span class="form-control">@ViewBag.Violation.PaymentDueDate.ToShortDateString()</span></td>
        </tr>
        <tr>
            <td class="bold">Payment Amount</td>
            <td><span class="form-control">@ViewBag.Violation.PaymentAmount.ToString()</span></td>
        </tr>
    </table>
  5. Click the Index.cshtml tab to activate it
  6. To execute the project, on the main menu, click Debug -> Start Without Debugging
  7. In the address bar, click on the right side of the address, type /Details/3

    Route Patterns

  8. Press Enter

    Route Patterns

  9. In the address bar, change 3 to 9

    Route Patterns

  10. Press Enter

    Route Patterns

  11. Close the browser and return to your programming environment

A Link for a Route

To lead the users to a view that can show a record, you can create a link from a webpage that displays a list of records. To start, when the user accesses the records, each record displays on its own row. Remember that each record should (must) have a value that uniquely identifies it. you can create a link so that, when the user positions the mouse on it, the unique value would be selected. You can then create a link on that value. To let you do this, the HtmlHelper class is extended with various versions of the ActionLink() method. One of the versions uses the following syntax:

public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper,
                                       string linkText,
                                       string actionName,
                                       object routeValues);

As mentioned in previous lessons, the first argument, linkText, is the text of the link. The second argument, actionName, is the name of the action method from a controller class. The new argument, routeValues, is of type object and represents the route. The argument is passed as an anonymous object: new {}. In the curly brackets, assign the unique record value to the argument passed to the action method.

Practical LearningPractical Learning: Creating a Link for a Route

  1. Access the Index.cshtml file of the ViolationsController class and change the document as follows:
    @{
        ViewBag.Title = "Traffic Violations";
    }
    
    <h2 class="text-center blue common-font bold">Traffic Violations</h2>
    
    <table class="table table-striped common-font">
        <tr class="bold">
            <td class="text-center">Violation ID</td>
            <td>Vehicle and Driver</td>
            <td>Violation Location</td>
            <td>Violation Type</td>
            <td class="text-center">Violation Date</td>
            <td class="text-center">Violation Time</td>
            <td class="text-center">Photo Available?</td>
            <td class="text-center">Video Available?</td>
            <td class="text-center">Payment Due Date</td>
            <td class="text-center">Payment Amount</td>
            <td>&nbsp;</td>
        </tr>
    @foreach (var infraction in ViewBag.violations)
    {
        <tr>
            <td class="text-center">@infraction.ViolationID</td>
            <td>@infraction.ViolationLocation</td>
            <td>@infraction.Vehicle - @infraction.DriverName</td>
            <td>@infraction.ViolationType</td>
            <td class="text-center">@infraction.ViolationDateTime.ToShortDateString()</td>
            <td class="text-center">@infraction.ViolationDateTime.ToShortTimeString()</td>
            <td class="text-center">@infraction.PhotoAvailable</td>
            <td class="text-center">@infraction.VideoAvailable</td>
            <td class="text-center">@infraction.PaymentDueDate.ToShortDateString()</td>
            <td class="text-center">@infraction.PaymentAmount</td>
            <td class="text-center">@Html.ActionLink("Citation", "Details", new { id = infraction.ViolationID })</td>
        </tr>
    }
    </table>
  2. To execute the application, on the main menu, click Debug and click Start Without Debugging:

    Introducing Interfaces

  3. In the webpage, click the Citation link that corresponds to the 5th record

    Route Patterns

    Route Patterns

  4. Click the Traffic Violations link
  5. In the webpage, click the Citation link that corresponds to the 8th record

    Route Patterns

    Route Patterns

  6. Close the browser and return to your programming environment
  7. Access the Details.cshtml tab and change the code in the document as follows:
    @{
        ViewBag.Title = "Traffic Violation";
    }
    
    <h2 class="text-center common-font maroon bold">Traffic Violation</h2>
    
    <div ng-controller="ViolationsController">
        <h3 class="text-center common-font bold">City of Jamies Town</h3>
        <h5 class="text-center common-font bold">6824 Cochran Ave, Ste 318<br />Jamies Town, MD 20540</h5>
    
        <div class="row common-font">
            <div class="col-md-8">
                <h4 class="common-font bold">Citation #: <span>@ViewBag.Violation.ViolationID</span></h4>
                <h4 class="common-font bold">Violation Type: <span>@ViewBag.Violation.ViolationName</span> Violation</h4>
                <hr />
                <h4 class="common-font bold"><span>@ViewBag.Violation.DriverName</span></h4>
                <h5 class="common-font bold"><span>@ViewBag.Violation.DriverAddress</span></h5>
                <h5 class="common-font bold">Vehicle: <span>@ViewBag.Violation.Vehicle</span></h5>
                <hr />
                <h5 class="common-font bold">To <span>@ViewBag.Violation.DriverName</span></h5>
                <p>Our records indicate that on <span>@ViewBag.Violation.ViolationDateTime.ToLongDateString()</span> at <span>@ViewBag.Violation.ViolationDateTime.ToLongTimeString()</span>, at <span>@ViewBag.Violation.ViolationLocation</span>, the above mentioned vehicle committed a <span>@ViewBag.Violation.ViolationName</span> violation. <span>@ViewBag.Violation.ViolationDescription</span>.</p>
                <p>If you recognize the traffic violation, please pay $<span>@ViewBag.Violation.PaymentAmount </span> by <span>@ViewBag.Violation.PaymentDueDate.ToLongDateString()</span>. Failure to pay the amount by that date will result in an increase of the fine and could result in the suspension of your driving priviledges. If you dispute the violation, to eventually appear in court, please fill out the form on the back of this document and send it to us.</p>
            </div>
            <div class="col-md-4">
                <p><span>@ViewBag.Violation.PhotoVideo</span></p>
            </div>
        </div>
    </div>
  8. Click the Index.cshtml tab to activate it
  9. To execute the project, on the main menu, click Debug -> Start Without Debugging
  10. In the address bar, click on the right side of the address, type /Details/1 and press Enter

    Route Patterns

  11. In the address bar, change 1 to 4 and press Enter

    Route Patterns

  12. Click the Traffic Violations link
  13. In the webpage, click the Citation link for the 2nd record

    Route Patterns

  14. Click the Traffic Violations link
  15. In the webpage, click the Citation link for the 6th record

    Route Patterns

  16. Close the browser and return to your programming environment

At Application Start-Up

To let you indicate how the routing must be done in your ASP.NET MVC project, when you create a project in Microsoft Visual Studio, the studio creates a folder named App_Start in the project. In that folder, it creates a C# file named RouteConfig.cs. In that file, it creates a class named RouteConfig. In that class, it creates a static method named RegisterRoutes. The compiler will refer to that class for routing purposes.

ApplicationPractical Learning: Routing in MVC

  1. In the Solution Explorer, expand App_Start if necessary and double-click RouteConfig.cs to open it
  2. Change the document as follows:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using System.Web.Routing;
    
    namespace TrafficTicketSystem1
    {
        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 = "Violations", action = "Index", id = UrlParameter.Optional }
                );
            }
        }
    }
  3. Click the TrafficTicketSystem1 tab to activate it:

    Routing in MVC

  4. To execute the project, on the main menu, click Debug -> Start Without Debugging:

    Routing in MVC

  5. Close the browser and return to your programming environment

The Entry Page of a Web Site

When you decide to create a website, the most important object is a file named the entry webpage. This is the webpage that displays when a visitor types a domain name (such as yahoo.com, microsoft.com, or csharpkey.com, etc) in the address bar of a browser and presses Enter. Behind-the-scenes, that is, in the webserver, this file is usually named index, Index, default, or Default, and has the extension .htm, .html, or something like that. This is neither a rule nor a law, only a routine. When creating your website, you can decide what webpage must display when.

Practical LearningPractical Learning: Introducing Routing

  1. On the main menu of Microsoft Visual Studio, click File -> New -> Project...
  2. In the New Project dialog box, click ASP.NET Web Application (.NET Framework).
    Change the project Name to DepartmentStore09
  3. Press Enter
  4. In the New ASP.NET Web Application dialog box, click the MVC icon and click OK. Notice the DepartmentStore09 tab

    Fundamentals of Routing

  5. To create a new controller, in the Solution Explorer, right-click Controllers -> Add -> New Scaffolded Item...
  6. In the Add Scaffold dialog box, click MVC 5 Controller - Empty and click Add
  7. Type Inventory to get InventoryController
  8. Click Add
  9. In the document, right-click Index and click Add View...
  10. Make sure the text box of the dialog box displays Index and click Add
  11. Click the DepartmentStore09 tab to activate it
  12. To execute the project, on the main menu, click Debug -> Start Without Debugging:

    Fundamentals of Routing

  13. Close the browser and return to your programming environment

Options on Creating Routes

Ignoring the Indentifier

When a webserver is asked to display a webpage, it switches to the routing configuration and checks the Id factor. If the Id is specified but there is no such identifier, it would be ignored. If you are not planning to use the Id factor, you can assign an empty string to Id. Here is an example:

using System.Web.Mvc;
using System.Web.Routing;

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

            routes.MapRoute("Detailed Report",
			    "{controller}/{action}/{id}",
			    new { controller = "Home", action = "Index", id = "" }
            );
        }
    }
}

Alternatively, if you don't want to use an identifier in the address, remove the Id factor in the url argument and omit it in the defaults argument. Here is an example:

using System.Web.Mvc;
using System.Web.Routing;

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

            routes.MapRoute("Detailed Report",
			    "{controller}/{action}/",
			    new { controller = "Home", action = "Index" }
            );
        }
    }
}

Creating a Collection of Routes

As mentioned previously, the class used to create routes, RouteCollection, is a collection class. This means that you can create and manage as different routes as you want. Each route is created by calling the RouteCollection.Add() method that we saw already. Here are examples:

using System.Web.Mvc;
using System.Web.Routing;

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

            routes.MapRoute(name: "Academia Topics",
                            url: "{controller}/{action}",
                            defaults: new { controller = "Academics", action = "AdmissionApplication" });

            routes.MapRoute(name: "Home",
                            url: "{controller}/{action}/{id}",
                            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });

            routes.MapRoute(name: "Human Resources",
                            url: "{controller}/{action}/",
                            defaults: new { controller = "Personnel", action = "TimeSheet" });
        }
    }
}

After creating the routes, if a visitor accesses your website using the domain name (such as blahblahblah.com), the webserver will refer to the RouteConfig.cs file and enter the RouteConfig.RegisterRoutes() method. As is always the case, the compiler would read the document from top to bottom. As a result, the first route would apply and may show its indicated webpage even if that's not the regular entry-poinit. Otherwise, the webserver would follow or access the views (the webpages) by the order of the routes creations.

View Redirection Using a Route

When an action has been performed, you can redirect the user or visitor to a view of your choice by specifying a route to take. To support this, the Controller class is equipped with an overloaded method named RedirectToRoute. One of the syntaxes used by this method is:

protected internal RedirectToRouteResult RedirectToRoute(object routeValues);

This method takes a route definition as argument. Here is an example:

public ActionResult Testimony()
{
    return RedirectToRoute(new { controller = "UnitedStates",
				    			 action = "Index",
			    	             id = UrlParameter.Optional });
}

Practical LearningPractical Learning: Ending the Lesson


Previous Copyright © 2014-2019, FunctionX Home