The .NET Framework's Linked List

Introduction

A linked list is a collection with the following rules:

Node

Nodes of a Linked List

In reality, there are various types of linked lists. A singly linked list is a one-way directional list where each item points (only) to the item next to it (in a somewhat right direction). The description we just gave is conform to a singly linked list. Another type is the doubly linked list:

Nodes of a Linked List

The last type of linked list is called a circular linked list. This list is primarily created as either a singly linked list or a doubly linked list:

Circular Singly Linked List

Circular Doubly Linked List

Practical LearningPractical Learning: Introducing Linked Lists

  1. Start Microsoft Visual Studio
  2. To create a new application, on the main menu, click File -> New -> Project...
  3. In the middle list, make sure ASP.NET Web Application (.NET Framework) is selected. Change the Name to TrafficTicketsSystem1
  4. Click OK
  5. In the New ASP.NET Web Application dialog box, click the MVC icon.
    Click OK
  6. In the Solution Explorer, right-click TrafficTicketsSystem1 -> Add -> New Folder
  7. Type Images and press Enter
  8. Save the following pictures to the Images folders:

    Traffic Tickets System

    Traffic Tickets System

    Traffic Tickets System

    Traffic Tickets System

  9. In the Solution Explorer, right-click Content -> Add -> Style Sheet
  10. Type TrafficTicketsSystem
  11. Click OK
  12. Change the document as follows:
    body {
        background-color: #FCFBED;
    }
    
    footer                  { background-color: #2e0202;              }
    .bold                   { font-weight:      600;                  }
    .yellow                 { color:            yellow;               }
    .maroon                 { color:            maroon;               }
    .small-text             { width:            120px;                }
    .large-text             { width:            250px;                }
    .flat-text              { border:           1px solid #FCFBED;
                              background-color: #FCFBED;              }
    .push-down              { padding-top:      6.75em;               }
    .containment            { margin:           auto;
                              width:            400px;                }
    .large-content          { margin:           auto;
                              width:            600px;                }
    .box-title              { margin-left:      20px;
                              border-bottom:    1px dashed white;     }
    .bottom-title           { margin-left:      40px;
                              margin-top:       10px;
                              color:            #d9d758;
                              border-bottom:    1px dashed lightblue; }
    .bottom-title + ul      { list-style-type:  none;                 }
    .bottom-title + ul > li { margin-top:       5px;
                              margin-bottom:    5px;                  }
    .management             { background-color: rgb(145, 65, 15);     }
    .management > ul        { list-style-type:  none;                 }
    .management > ul > li   { margin-top:       5px;
                              margin-bottom:    5px;
                              margin-left:     -20px;                 }
    .manage-lead            { color:            antiquewhite;         }
    .manage-lead:link       { color:            orange;               }
    .manage-lead:focus      { color:            white;                }
    .manage-lead:hover      { color:            yellow;               }
    .bottom-lead            { color:            antiquewhite;         }
    .bottom-lead:link       { color:            orange;               }
    .bottom-lead:focus      { color:            white;                }
    .bottom-lead:hover      { color:            yellow;               }
    .bordered               { border:           1px solid #000;       }
    .navbar-fixed-top       { top:              6em;                  }
    .while-box              { margin:           3px;
                              background-color: white;
                              border-left:      1px solid #f1e9e9;
                              border-top:       1px solid #f1e9e9;
                              border-right:     2px solid silver;
                              border-bottom:    2px solid silver;     }
    .navbar-top-fixed       { position:         fixed;
                              right:            0;
                              left:             0;
                              z-index:          1030;                 }
    .navbar-top-fixed       { top:              0;
                              border-width:     0 0 1px;              }
    .navbar-inverse         { background-color: #000;                 }
    .navbar-brand           { font-size:        14px;                 }
    
    .col-md-20, .col-md-30, .col-md-60
                            { position:         relative;
                              min-height:       1px;
                              padding-right:    15px;
                              padding-left:     15px;                 }
    
    @media (min-width: 768px) {
        .navbar-top-fixed .navbar-collapse {
            padding-right: 0;
            padding-left: 0;
        }
    }
    .navbar-top-fixed .navbar-collapse {
        max-height: 340px;
    }
    @media (max-device-width: 480px) and (orientation: landscape) {
        .navbar-top-fixed .navbar-collapse {
            max-height: 200px;
        }
    }
    @media (min-width: 768px) {
        .navbar-top-fixed {
            border-radius: 0;
        }
    }
    
    @media (min-width: 992px) {
        .col-md-20, .col-md-30, .col-md-60 {
            float: left;
        }
    
        .col-md-20 { width: 20%; }
        .col-md-30 { width: 32%; }
        .col-md-60 { width: 60%; }
    }
    
    .common-font { font-family: Georgia, Garamond, 'Times New Roman', serif; }
  13. In the Solution Explorer, expand App_Start and double-click BundleConfig.cs
  14. Change the document as follows:
    using System.Web.Optimization;
    
    namespace TrafficTicketsSystem1
    {
        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"));
    
                bundles.Add(new StyleBundle("~/Content/css").Include(
                          "~/Content/bootstrap.css",
                          "~/Content/site.css",
                          "~/Content/TrafficTicketsSystem.css"));
            }
        }
    }
  15. To create a new class, in the Solution Explorer, right-click Models -> Add -> Class...
  16. Set the Name to Camera
  17. Click Add
  18. Change the file as follows:
    using System;
    using System.ComponentModel.DataAnnotations;
    
    namespace TrafficTicketsSystem1.Models
    {
        [Serializable]
        public class Camera
        {
            [Display(Name = "Camera #")]
            public string CameraNumber { get; set; }
            public string Make         { get; set; }
            public string Model        { get; set; }
            public string Location     { get; set; }
    
            public override bool Equals(object obj)
            {
                Camera cmr = (Camera)obj;
    
                if (cmr.CameraNumber == CameraNumber)
                    return true;
                else
                    return false;
            }
            
            public override int GetHashCode()
            {
                return base.GetHashCode();
            }
        }
    }
  19. In the Solution Explorer, right-click Moddels -> Add -> Class...
  20. Type Driver as the name of the class
  21. Click Add
  22. Complete the class as follows:
    using System;
    using System.ComponentModel.DataAnnotations;
    
    namespace TrafficTicketsSystem1.Models
    {
        [Serializable]
        public class Driver
        {
            [Display(Name = "Drv. Lic. #")]
            public string DrvLicNumber { get; set; }
            [Display(Name = "First Name")]
            public string FirstName    { get; set; }
            [Display(Name = "Last Name")]
            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; }
            [Display(Name = "ZIP Code")]
            public string ZIPCode      { get; set; }
    
            public override bool Equals(object obj)
            {
                Driver dvr = (Driver)obj;
    
                return dvr.DrvLicNumber == DrvLicNumber ? true : false;
            }
    
            public override int GetHashCode()
            {
                return base.GetHashCode();
            }
        }
    }
  23. In the Solution Explorer, right-click Models -> Add -> Class...
  24. Type Vehicle
  25. Click Add
  26. Change the class as follows:
    using System;
    using System.ComponentModel.DataAnnotations;
    
    namespace TrafficTicketsSystem1.Models
    {
        [Serializable]
        public class Vehicle
        {
            [Display(Name = "Tag #")]
            public string TagNumber    { get; set; }
            [Display(Name = "Drv. Lic. #")]
            public string DrvLicNumber { get; set; }
            public string Make         { get; set; }
            public string Model        { get; set; }
            [Display(Name = "Vehicle Year")]
            public string VehicleYear  { get; set; }
            public string Color        { get; set; }
    
            public override bool Equals(object obj)
            {
                Vehicle car = (Vehicle)obj;
    
                if (car.TagNumber == TagNumber)
                    return true;
                else
                    return false;
            }
    
            public override int GetHashCode()
            {
                return base.GetHashCode();
            }
        }
    }
  27. In the Solution Explorer, right-click Models -> Add -> Class...
  28. Type ViolationType as the name of the class
  29. Click Add
  30. Change the class as follows:
    using System;
    using System.ComponentModel.DataAnnotations;
    
    namespace TrafficTicketsSystem1.Models
    {
        [Serializable]
        public class ViolationType
        {
            [Display(Name = "Violation Name")]
            public string ViolationName { get; set; }
            public string Description   { get; set; }
    
            public override bool Equals(object obj)
            {
                ViolationType vt = (ViolationType)obj;
    
                return vt.ViolationName == ViolationName ? true : false;
            }
    
            public override int GetHashCode()
            {
                return base.GetHashCode();
            }
        }
    }
  31. In the Solution Explorer, right-click Models -> Add -> Class...
  32. Type TrafficViolation as the name of the class
  33. Click Add
  34. Change the class as follows:
    using System;
    using System.ComponentModel.DataAnnotations;
    
    namespace TrafficTicketsSystem1.Models
    {
        [Serializable]
        public class TrafficViolation
        {
            [Display(Name = "Traffic Violation #")]
            public int TrafficViolationNumber { get; set; }
            [Display(Name = "Camera #")]
            public string CameraNumber        { get; set; }
            [Display(Name = "Tag #")]
            public string TagNumber           { get; set; }
            [Display(Name = "Violation Type")]
            public string ViolationName       { get; set; }
            [Display(Name = "Violation Date")]
            public string ViolationDate       { get; set; }
            [Display(Name = "Violation Time")]
            public string ViolationTime       { get; set; }
            [Display(Name = "Photo Available")]
            public string PhotoAvailable      { get; set; }
            [Display(Name = "Video Available")]
            public string VideoAvailable      { get; set; }
            [Display(Name = "Payment Due Date")]
            public string PaymentDueDate      { get; set; }
            [Display(Name = "Payment Date")]
            public string PaymentDate         { get; set; }
            [Display(Name = "Payment Amount")]
            public double PaymentAmount       { get; set; }
            [Display(Name = "Payment Status")]
            public string PaymentStatus       { get; set; }
    
            public override bool Equals(object obj)
            {
                TrafficViolation tv = (TrafficViolation)obj;
    
                return tv.TrafficViolationNumber == TrafficViolationNumber ? true : false;
            }
    
            public override int GetHashCode()
            {
                return base.GetHashCode();
            }
        }
    }
  35. In the Solution Explorer, right-click Controllers -> Add -> Controller...
  36. In the middle list of the Add Scaffold dialog box, click MVC 5 Controller - Empty (or make sure it is selected).
    Click Add
  37. Type ViolationsTypes to get ViolationsTypesController
  38. Click Add

Creating a Linked List

Although you can create a linked list collection class from scratch, to assist you, the .NET Framework provides a class named LinkedList and that is a member of the System.Collections.Generic namespace. LinkedList is a generic collection class with three constructors. The default constructor allows you to create an empty linked list. Here is an example of using it:

using System.Web.Mvc;
using System.Collections.Generic;

namespace Exercise1.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Collector()
        {
            LinkedList<double> numbers = new LinkedList<double>();

            return View();
        }
    }
}

Of course you can also declare the variable in a webpage.

Another constructor allows you to create a linked using an existing list. Its syntax is:

public LinkedList(IEnumerable<T> collection);

The argument can be a variable from any class that implements the IEnumerable<T> interface. Here is an example of using this second constructor:

@{
    ViewBag.Title = "Linked List";
}

<h2>Linked List</h2>

@{
    List<double> values = new List<double>();
    values.Add(84.597);
    values.Add(6.47);
    values.Add(2747.06);
    values.Add(282.924);

    LinkedList<double> numbers = new LinkedList<double>(values);
}

Practical LearningPractical Learning: Creating a Linked List

Primary Characteristics of a Linked List

Introduction to a Node as an Object

To support the nodes of a linked list, the .NET Framework provides a class named LinkedListNode:

public sealed class LinkedListNode<T>

This class has only properties, no methods.

The Value of a Node

Probably the most important aspect of a node is its value. To support it, the LinkedListNode class has a property named Value:

public T Value { get; set; }

Because this is a read-write property, you can use its write-accessory to specify or change its value. On the other hand, you can access the value of a node using this property.

The Number of Nodes of a List

The LinkedList class starts as follows:

public class LinkedList<T> : ICollection<T>, 
            		         IEnumerable<T>,
            		         ICollection, IEnumerable,
            		         ISerializable,
            		         IDeserializationCallback

As you can see, the LinkedList class implements the ICollection interface. This gives it a Count property that produces the number of nodes. Here is an example of accessing it:

<!DOCTYPE html>
<html>
<head>
<title>Numbers</title>
</head>
<body>
<h2>Numbers</h2>

@{
    List<double> values = new List<double>();
    values.Add(84.597);
    values.Add(6.47);
    values.Add(2747.06);
    values.Add(282.924);

    LinkedList<double> numbers = new LinkedList<double>(values);
}

<p>There are @numbers.Count.ToString() numbers in the list.</p>
</body>
</html>

This would produce:

Linked List

Primary Operations on a Linked List

Adding a Node

The primary operation to perform on a linked list is to add a new node to it. To support it, the LinkedList class is equipped with various methods. One of them is named AddLast that is overloaded in two versions. One of them uses the following syntax:

public LinkedListNode<T> AddLast(T value);

This method expects the new value as argument. Here are examples of calling it:

@{
    LinkedList<double> numbers = new LinkedList<double>();

    numbers.AddLast(84.597);
    numbers.AddLast(6.47);
    numbers.AddLast(2747.06);
    numbers.AddLast(282.924);
}

<p>There are @numbers.Count.ToString() numbers in the list.</p>

Another version of this method is:

public void AddLast(LinkedListNode<T> node);

This version expects a LinkedListNode object as argument. Here are examples of calling it:

@{
    LinkedList<double> numbers = new LinkedList<double>();

    LinkedListNode<double> number = new LinkedListNode<double>(148.24);
    numbers.AddLast(number);

    number = new LinkedListNode<double>(84.597);
    numbers.AddLast(number);

    number = new LinkedListNode<double>(6.47);
    numbers.AddLast(number);

    number = new LinkedListNode<double>(2747.06);
    numbers.AddLast(number);

    number = new LinkedListNode<double>(282.924);
    numbers.AddLast(number);
}

ApplicationPractical Learning: Adding a Node

  1. In the ViolationsTypesController class, create a method named Create as follows:
    using System.Web;
    using System.Linq;
    using System.Web.Mvc;
    using System.Collections.Generic;
    using TrafficTicketsSystem1.Models;
    
    namespace TrafficTicketsSystem1.Controllers
    {
        public class ViolationsTypesController : Controller
        {
            // GET: ViolationsTypes
            public ActionResult Index()
            {
                LinkedList<ViolationType> categories = new LinkedList<ViolationType>();
    
                return View();
            }
    
            // GET: ViolationsTypes/Create
            public ActionResult Create()
            {
                return View();
            }
        }
    }
  2. In the ViolationsTypesController class, right-click Create() and click Add View...
  3. In the Add View dialog box, make sure the View Name text box is displaying Create.
    Click Add
  4. Create the form as follows:
    @model TrafficTicketsSystem1.Models.ViolationType
    
    @{
        ViewBag.Title = "Create Violation Type";
    }
    
    <h2 class="common-font text-center bold maroon">Create Violation Type</h2>
    
    <hr />
    
    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()
    
        <div class="large-content">
            <div class="form-horizontal common-font">
                @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                <div class="form-group">
                    @Html.LabelFor(model => model.ViolationName, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.EditorFor(model => model.ViolationName, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.ViolationName, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    @Html.LabelFor(model => model.Description, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.TextArea("Description", null,
                                       htmlAttributes: new { @class = "form-control", rows = "10", cols = "20" })
                        @Html.ValidationMessageFor(model => model.Description, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    <div class="col-md-5"></div>
                    <div class="col-md-7 text-center">
                        <input type="submit" value="Save this Violation Type" class="btn btn-warning" />
                    </div>
                </div>
            </div>
        </div>
    }
    
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Violations Types", "Index") ::
        @Html.ActionLink("Description of a Violation Type", "Details") ::
        @Html.ActionLink("Edit/Update a Violation Type", "PrepareEdit") ::
        @Html.ActionLink("Delete a Violation Type", "Delete")
    </p>
  5. Click the ViolationsTypesController.cs tab and create a second Create() method as follows:
    using System.IO;
    using System.Web.Mvc;
    using System.Collections.Generic;
    using TrafficTicketsSystem1.Models;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace TrafficTicketsSystem1.Controllers
    {
        public class ViolationsTypesController : Controller
        {
            // GET: ViolationsTypes
            public ActionResult Index()
            {
                LinkedList<ViolationType> categories = new LinkedList<ViolationType>();
    
                return View();
            }
    
            // GET: ViolationsTypes/Create
            public ActionResult Create()
            {
                return View();
            }
    
            // POST: ViolationsTypes/Create
            [HttpPost]
            public ActionResult Create(FormCollection collection)
            {
                try
                {
                    FileStream fsViolationsTypes = null;
                    LinkedList<ViolationType> categories = new LinkedList<ViolationType>();
                    BinaryFormatter bfViolationsTypes = new BinaryFormatter();
                    string strViolationsTypesFile = Server.MapPath("~/App_Data/ViolationsTypes.tts");
    
                    if (!string.IsNullOrEmpty("DrvLicNumber"))
                    {
                        if (System.IO.File.Exists(strViolationsTypesFile))
                        {
                            using (fsViolationsTypes = new FileStream(strViolationsTypesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                categories = (LinkedList<ViolationType>)bfViolationsTypes.Deserialize(fsViolationsTypes);
                            }
                        }
    
                        ViolationType vt = new ViolationType()
                        {
                            ViolationName = collection["ViolationName"],
                            Description = collection["Description"],
                        };
    
                        categories.AddLast(vt);
    
                        using (fsViolationsTypes = new FileStream(strViolationsTypesFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                        {
                            bfViolationsTypes.Serialize(fsViolationsTypes, categories);
                        }
                    }
    
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
        }
    }

Getting Each Node

The LinkedList class doesn't implement the IList interface, which means it doesn't have an Item property. As we have seen with the AddLast() method and as we will see in the next sections, each method used to add a node is provided in two versions. One of the versions returns a LinkedListNode object. This means that, when performing an addition operation, you can get the returned value and do what you want with it.

The LinkedList class implements the IEnumerable interface. This makes it possible to use foreach to get to access each node. This can be done as follows:

<!DOCTYPE html>
<html>
<head>
<title>Numbers</title>
</head>
<body>
<h2>Numbers</h2>

@{
    List<double> values = new List<double>();
    values.Add(84.597);
    values.Add(6.47);
    values.Add(2747.06);
    values.Add(282.924);

    LinkedList<double> numbers = new LinkedList<double>(values);
    LinkedListNode<double> number = new LinkedListNode<double>(148.24);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(35.75);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(2222.06);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(4.19);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(66.18);
    numbers.AddFirst(number);
}

<ul>
    @foreach(double nbr in numbers)
    {
        <li>Number: @nbr</li>
    }
</ul>
</body>
</html>

This would produce:

Looping a Linked List

Practical LearningPractical Learning: Getting Each Node of a Linked List

  1. In the ViolationsTypesController class, change the Index() method as follows:
    using System.IO;
    using System.Web.Mvc;
    using System.Collections.Generic;
    using TrafficTicketsSystem1.Models;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace TrafficTicketsSystem1.Controllers
    {
        public class ViolationsTypesController : Controller
        {
            // GET: ViolationsTypes
            public ActionResult Index()
            {
                FileStream fsViolationsTypes = null;
                BinaryFormatter bfViolationsTypes = new BinaryFormatter();
                string strViolationsTypesFile = Server.MapPath("~/App_Data/ViolationsTypes.tts");
                LinkedList<ViolationType> categories = new LinkedList<ViolationType>();
    
                // If a file for violations types was proviously created, open it
                if (System.IO.File.Exists(strViolationsTypesFile))
                {
                    using (fsViolationsTypes = new FileStream(strViolationsTypesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        /* After opening the file, get the list of records from it
                         * and store in the declared LinkedList<> variable. */
                        categories = (LinkedList<ViolationType>)bfViolationsTypes.Deserialize(fsViolationsTypes);
                    }
                }
    
                return View(categories);
            }
    
            // GET: ViolationsTypes/Create
            public ActionResult Create()
            {
                return View();
            }
    
            // POST: ViolationsTypes/Create
            [HttpPost]
            public ActionResult Create(FormCollection collection)
            {
                try
                {
                    FileStream fsViolationsTypes = null;
                    LinkedList<ViolationType> categories = new LinkedList<ViolationType>();
                    BinaryFormatter bfViolationsTypes = new BinaryFormatter();
                    string strViolationsTypesFile = Server.MapPath("~/App_Data/ViolationsTypes.tts");
    
                    if (!string.IsNullOrEmpty("DrvLicNumber"))
                    {
                        if (System.IO.File.Exists(strViolationsTypesFile))
                        {
                            using (fsViolationsTypes = new FileStream(strViolationsTypesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                categories = (LinkedList<ViolationType>)bfViolationsTypes.Deserialize(fsViolationsTypes);
                            }
                        }
    
                        ViolationType vt = new ViolationType()
                        {
                            ViolationName = collection["ViolationName"],
                            Description = collection["Description"],
                        };
    
                        categories.AddLast(vt);
    
                        using (fsViolationsTypes = new FileStream(strViolationsTypesFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                        {
                            bfViolationsTypes.Serialize(fsViolationsTypes, categories);
                        }
                    }
    
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
        }
    }
  2. In the document, right-click Index() and click Add View...
  3. In the Add View dialog box, make sure the View Name text box is displaying Index.
    Click Add
  4. Change the document as follows:
    @model IEnumerable<TrafficTicketsSystem1.Models.ViolationType>
    
    @{
        ViewBag.Title = "Violations Types";
    }
    
    <h2 class="bold maroon common-font text-center">Violations Types</h2>
    
    <table class="table table-striped common-font">
        <tr>
            <th class="text-center maroon">@Html.DisplayNameFor(model => model.ViolationName)</th>
            <th class="maroon">@Html.DisplayNameFor(model => model.Description)</th>
            <th></th>
        </tr>
    
        @foreach (var item in Model)
        {
            <tr>
                <td class="text-center">@Html.DisplayFor(modelItem => item.ViolationName)</td>
                <td>@Html.DisplayFor(modelItem => item.Description)</td>
            </tr>
        }
    </table>
    
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Create New Violation Type", "Create") ::
        @Html.ActionLink("Description of a Violation Type", "Details") ::
        @Html.ActionLink("Edit/Update a Violation Type", "PrepareEdit") ::
        @Html.ActionLink("Delete a Violation Type", "Delete")
    </p>
  5. To create a controller, in the Solution Explorer, right-click Controllers -> Add -> New Scaffolded Item...
  6. Make sure MVC 5 Controller - Empty is selected.
    Click Add
  7. Type Vehicles to get VehiclesController
  8. Click Add
  9. In the VehiclesController class, create a method named Index as follows:
    using System.IO;
    using System.Web.Mvc;
    using System.Collections.Generic;
    using TrafficTicketsSystem1.Models;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace TrafficTicketsSystem1.Controllers
    {
        public class VehiclesController : Controller
        {
            // GET: Vehicles
            public ActionResult Index()
            {
                FileStream fsVehicles = null;
                BinaryFormatter bfVehicles = new BinaryFormatter();
                LinkedList<Vehicle> vehicles = new LinkedList<Vehicle>();
    
                string strVehiclesFile = Server.MapPath("~/App_Data/Vehicles.tts");
    
                if (System.IO.File.Exists(strVehiclesFile))
                {
                    using (fsVehicles = new FileStream(strVehiclesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        vehicles = (LinkedList<Vehicle>)bfVehicles.Deserialize(fsVehicles);
                    }
                }
    
                return View(vehicles);
            }
        }
    }
  10. In the VehiclesController class, right-click Index() -> Add View...
  11. Make sure the View Name text box displays Index.
    Click Add
  12. Change the document as follows:
    @model IEnumerable<TrafficTicketsSystem1.Models.Vehicle>
    
    @{
        ViewBag.Title = "Cars - Vehicles";
    }
    
    <h2 class="bold maroon common-font text-center">Cars - Vehicles</h2>
    
    <table class="table table-hover common-font">
        <tr>
            <th class="text-center">@Html.DisplayNameFor(model => model.TagNumber)</th>
            <th>@Html.DisplayNameFor(model => model.DrvLicNumber)</th>
            <th>@Html.DisplayNameFor(model => model.Make)</th>
            <th>@Html.DisplayNameFor(model => model.Model)</th>
            <th>@Html.DisplayNameFor(model => model.VehicleYear)</th>
            <th>@Html.DisplayNameFor(model => model.Color)</th>
        </tr>
    
        @foreach (var item in Model)
        {
            <tr>
                <td class="text-center">@Html.DisplayFor(modelItem => item.TagNumber)</td>
                <td>@Html.DisplayFor(modelItem => item.DrvLicNumber)</td>
                <td>@Html.DisplayFor(modelItem => item.Make)</td>
                <td>@Html.DisplayFor(modelItem => item.Model)</td>
                <td>@Html.DisplayFor(modelItem => item.VehicleYear)</td>
                <td>@Html.DisplayFor(modelItem => item.Color)</td>
            </tr>
        }
    </table>
    <hr />
    <p class="text-center">
        @Html.ActionLink("Register New Vehicle", "Create") ::
        @Html.ActionLink("Edit/Update Vehicle Registration", "PrepareEdit") ::
        @Html.ActionLink("Vehicle Details", "Details") ::
        @Html.ActionLink("Delete Vehicle Record", "PrepareDelete")
    </p>
  13. In the Solution Explorer, right-click Controllers -> Add -> New Scaffolded Item...
  14. In the Add Scaffold dialog box, make sure MVC 5 Controller - Empty is selected. Click Add
  15. Type Cameras to get CamerasController
  16. Click Add
  17. In the class, create a method named Index as follows:
    using System.IO;
    using System.Web.Mvc;
    using System.Collections.Generic;
    using TrafficTicketsSystem1.Models;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace TrafficTicketsSystem1.Controllers
    {
        public class CamerasController : Controller
        {
            // GET: Cameras
            public ActionResult Index()
            {
                FileStream fsCameras = null;
                BinaryFormatter bfCameras = new BinaryFormatter();
                LinkedList<Camera> cameras = new LinkedList<Camera>();
                string strCamerasFile = Server.MapPath("~/App_Data/Cameras.tts");
    
                // If a file for Cameras records was proviously created, open it
                if (System.IO.File.Exists(strCamerasFile))
                {
                    using (fsCameras = new FileStream(strCamerasFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        /* After opening the file, get the list of records from it
                         * and store in the declared LinkedList<> variable. */
                        cameras = (LinkedList<Camera>)bfCameras.Deserialize(fsCameras);
                    }
                }
    
                return View(cameras);
            }
        }
    }
  18. In the class, right-click Index() -> Add View...
  19. In the Add View dialog box, make sure the View Name text box is displaying Index.
    Click Add
  20. Change the document as follows:
    @model IEnumerable<TrafficTicketsSystem1.Models.Camera>
    
    @{
        ViewBag.Title = "Cameras - Traffic Monitors";
    }
    
    <h2 class="bold maroon common-font text-center">Cameras - Traffic Monitors</h2>
    
    <table class="table table-hover common-font">
        <tr>
            <th class="text-center">@Html.DisplayNameFor(model => model.CameraNumber)</th>
            <th>@Html.DisplayNameFor(model => model.Make)</th>
            <th>@Html.DisplayNameFor(model => model.Model)</th>
            <th>@Html.DisplayNameFor(model => model.Location)</th>
        </tr>
    
        @foreach (var item in Model)
        {
            <tr>
                <td class="text-center">@Html.DisplayFor(modelItem => item.CameraNumber)</td>
                <td>@Html.DisplayFor(modelItem => item.Make)</td>
                <td>@Html.DisplayFor(modelItem => item.Model)</td>
                <td>@Html.DisplayFor(modelItem => item.Location)</td>
            </tr>
        }
    </table>
    <hr />
    <p class="text-center">
        @Html.ActionLink("Create New Camera", "Create") ::
        @Html.ActionLink("Edit/Update Camera", "PrepareEdit") ::
        @Html.ActionLink("Camera Details", "Details") ::
        @Html.ActionLink("Delete Camera", "PrepareDelete")</p>
  21. In the Solution Explorer, right-click Controllers -> Add -> New Scaffolded Item...
  22. In the Add Scaffold dialog box, make sure MVC 5 Controller - Empty is selected.
    Click Add
  23. Type Drivers to get DriversController
  24. Click Add
  25. In the class, create an Index() method as follows:
    using System.IO;
    using System.Web.Mvc;
    using System.Collections.Generic;
    using TrafficTicketsSystem1.Models;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace TrafficTicketsSystem1.Controllers
    {
        public class DriversController : Controller
        {
            // GET: Drivers
            public ActionResult Index()
            {
                FileStream fsDrivers = null;
                BinaryFormatter bfDrivers = new BinaryFormatter();
                LinkedList<Driver> drivers = new LinkedList<Driver>();
                string strDriversFile = Server.MapPath("~/App_Data/Drivers.tts");
    
                if (System.IO.File.Exists(strDriversFile))
                {
                    using (fsDrivers = new FileStream(strDriversFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        drivers = (LinkedList<Driver>)bfDrivers.Deserialize(fsDrivers);
                    }
                }
    
                return View(drivers);
            }
        }
    }
  26. In the class, right-click Index() -> Add View...
  27. In the Add View dialog box, make sure the View Name text box is displaying Index.
    Click Add
  28. Change the webpage as follows:
    @model IEnumerable<TrafficTicketsSystem1.Models.Driver>
    
    @{
        ViewBag.Title = "Drivers";
    }
    
    <h2 class="bold maroon common-font text-center">Drivers/Vehicles Owners</h2>
    
    <table class="table table-hover common-font">
        <tr>
            <th class="text-center">@Html.DisplayNameFor(model => model.DrvLicNumber)</th>
            <th>@Html.DisplayNameFor(model => model.FirstName)</th>
            <th>@Html.DisplayNameFor(model => model.LastName)</th>
            <th>@Html.DisplayNameFor(model => model.Address)</th>
            <th>@Html.DisplayNameFor(model => model.City)</th>
            <th>@Html.DisplayNameFor(model => model.County)</th>
            <th>@Html.DisplayNameFor(model => model.State)</th>
            <th>@Html.DisplayNameFor(model => model.ZIPCode)</th>
        </tr>
    
        @foreach (var item in Model)
        {
            <tr>
                <td class="text-center">@Html.DisplayFor(modelItem => item.DrvLicNumber)</td>
                <td>@Html.DisplayFor(modelItem => item.FirstName)</td>
                <td>@Html.DisplayFor(modelItem => item.LastName)</td>
                <td>@Html.DisplayFor(modelItem => item.Address)</td>
                <td>@Html.DisplayFor(modelItem => item.City)</td>
                <td>@Html.DisplayFor(modelItem => item.County)</td>
                <td>@Html.DisplayFor(modelItem => item.State)</td>
                <td>@Html.DisplayFor(modelItem => item.ZIPCode)</td>
            </tr>
        }
    </table>
    
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Issue New Driver's License", "Create") ::
        @Html.ActionLink("Review a Driver's License", "Details") ::
        @Html.ActionLink("Edit/Update a Driver's License", "PrepareEdit") ::
        @Html.ActionLink("Suspend/Delete/Remove a Driver's License", "PrepareDelete")</p>
  29. To start a new controller, in the Solution Explorer, right-click Controllers -> Add -> Controller...
  30. In the Add Scaffold dialog box, make sure MVC 5 Controller - Empty is selected.
    Click Add
  31. Type TrafficViolations to get TrafficViolationController as the name of the controller
  32. Click Add
  33. In the class, change the Index() method as follows:
    using System.IO;
    using System.Web.Mvc;
    using System.Collections.Generic;
    using TrafficTicketsSystem1.Models;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace TrafficTicketsSystem1.Controllers
    {
        public class TrafficViolationsController : Controller
        {
            // GET: TrafficViolations
            public ActionResult Index()
            {
                FileStream fsTrafficViolations = null;
                BinaryFormatter bfTrafficViolations = new BinaryFormatter();
                LinkedList<TrafficViolation> violations = new LinkedList<TrafficViolation>();
    
                string strTrafficViolationsFile = Server.MapPath("~/App_Data/TrafficViolations.tts");
    
                if (System.IO.File.Exists(strTrafficViolationsFile))
                {
                    using (fsTrafficViolations = new FileStream(strTrafficViolationsFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        violations = (LinkedList<TrafficViolation>)bfTrafficViolations.Deserialize(fsTrafficViolations);
                    }
                }
    
                return View(violations);
            }
        }
    }
  34. In the class, right-click Index() -> Add View...
  35. Make sure the View Name text box is displaying Index.
    Click Add
  36. Chang ethe document as follows:
    @model IEnumerable<TrafficTicketsSystem1.Models.TrafficViolation>
    
    @{
        ViewBag.Title = "Traffic Violations";
    }
    
    <h2 class="bold maroon common-font text-center">Traffic Violations</h2>
    
    <table class="table table-hover common-font">
        <tr>
            <th class="text-center">@Html.DisplayNameFor(model => model.TrafficViolationNumber)</th>
            <th>@Html.DisplayNameFor(model => model.CameraNumber)</th>
            <th>@Html.DisplayNameFor(model => model.TagNumber)</th>
            <th>@Html.DisplayNameFor(model => model.ViolationName)</th>
            <th>@Html.DisplayNameFor(model => model.ViolationDate)</th>
            <th>@Html.DisplayNameFor(model => model.ViolationTime)</th>
            <th>@Html.DisplayNameFor(model => model.PhotoAvailable)</th>
            <th>@Html.DisplayNameFor(model => model.VideoAvailable)</th>
            <th>@Html.DisplayNameFor(model => model.PaymentDueDate)</th>
            <th>@Html.DisplayNameFor(model => model.PaymentDate)</th>
            <th>@Html.DisplayNameFor(model => model.PaymentAmount)</th>
            <th>@Html.DisplayNameFor(model => model.PaymentStatus)</th>
        </tr>
    
        @foreach (var item in Model)
        {
            <tr>
                <td class="text-center">@Html.DisplayFor(modelItem => item.TrafficViolationNumber)</td>
                <td>@Html.DisplayFor(modelItem => item.CameraNumber)</td>
                <td>@Html.DisplayFor(modelItem => item.TagNumber)</td>
                <td>@Html.DisplayFor(modelItem => item.ViolationName)</td>
                <td>@Html.DisplayFor(modelItem => item.ViolationDate)</td>
                <td>@Html.DisplayFor(modelItem => item.ViolationTime)</td>
                <td>@Html.DisplayFor(modelItem => item.PhotoAvailable)</td>
                <td>@Html.DisplayFor(modelItem => item.VideoAvailable)</td>
                <td>@Html.DisplayFor(modelItem => item.PaymentDueDate)</td>
                <td>@Html.DisplayFor(modelItem => item.PaymentDate)</td>
                <td>@Html.DisplayFor(modelItem => item.PaymentAmount)</td>
                <td>@Html.DisplayFor(modelItem => item.PaymentStatus)</td>
            </tr>
        }
    </table>
    
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Process a New Traffic Violation", "Create") ::
        @Html.ActionLink("Review a Traffic Violation", "Details") ::
        @Html.ActionLink("Edit/Update a Traffic Violation", "PrepareEdit") ::
        @Html.ActionLink("Suspend/Delete/Cancel a Traffic Violation", "PrepareDelete") ::
        @Html.ActionLink("Prepare/Review a Citation", "Citation")</p>
  37. In the Solution Explorer, under Controllers, double-click ViolationsTypesController.cs to access it

Looking for a Node

Checking Whether the List Contains a Certain Node

Because the LinkedList implements the ICollection interface, it inherits the Contains method. As a reminder, its syntax is:

public bool Contains(T value);

This method checks whether the linked list contains the (a) node that has the value passed as argument. If that node is found, the method returns true. Otherwise it returns false. Here is an example of calling it:

@<!DOCTYPE html>
<html>
<head>
<title>Numbers</title>
</head>
<body>
<h2>Numbers</h2>

@{
    List<double> values = new List<double>();
    values.Add(84.597);
    values.Add(6.47);
    values.Add(2747.06);
    values.Add(282.924);

    LinkedList<double> numbers = new LinkedList<double>(values);
    LinkedListNode<double> number = new LinkedListNode<double>(148.24);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(35.75);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(2222.06);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(4.19);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(66.18);
    numbers.AddFirst(number);
}

@if (numbers.Contains(2222.06) == true)
{
    <p>The list contains 2222.06.</p>
}
else
{
    <p>There is no such a number in the list.</p>
}
</body>
</html>

This would produce:

Label

This method works only if the type of the node is able to perform the comparison for equality. If you are using values of primitive types (int, char, double, DateTime, etc) or string, the method would work fine. If you are using your own class, make sure you override the Equals() method.

Finding a Node by its Value

While the Contains() method is used to look for a value in a linked list, it only lets you know whether the value was found. If you want to get the actual node that has that value, you can call the Find() method. Its syntax is:

public LinkedListNode<T> Find(T value);

When this method is called, it starts looking for the value in the linked list. If it finds it, it returns its node. If there is more than one node with that value, the method returns only the first node that has that value. Here is an example of calling this method:

<!DOCTYPE html>
<html>
<head>
<title>Numbers</title>
</head>
<body>
<h2>Numbers</h2>

@{
    List<double> values = new List<double>();
    values.Add(84.597);
    values.Add(6.47);
    values.Add(2747.06);
    values.Add(282.924);

    LinkedList<double> numbers = new LinkedList<double>(values);
    LinkedListNode<double> number = new LinkedListNode<double>(148.24);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(35.75);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(2222.06);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(4.19);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(66.18);
    numbers.AddFirst(number);
}

@if( numbers.Find(2747.06) != null)
{
    <p>2747.06 was found in the list.</p>
}
else
{
    <p>2747.06 is nowhere in the list.</p>
}
</body>
</html>

This would produce:

Linked List

This method is ready to work on primitive types. If you are using your own class for the type of node, you should (must) override the Equals() method (which we did when we created the Camera class earlier).

Practical LearningPractical Learning: Finding a Node

  1. In the ViolationsTypesController class, create a method named Details as follows:
    using System.IO;
    using System.Web.Mvc;
    using System.Collections.Generic;
    using TrafficTicketsSystem1.Models;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace TrafficTicketsSystem1.Controllers
    {
        public class ViolationsTypesController : Controller
        {
            . . . No Change
    
            // GET: ViolationsTypes/Details/
            public ActionResult Details()
            {
                return View();
            }
        }
    }
  2. In the class, right-click Details() -> Add View...
  3. In the Add View dialog box, make sure the View Name text box is displaying Details.
    Click Add
  4. Change the code of the webpage as follows:
    @{
        ViewBag.Title = "Violation Type Details";
    }
    
    @{
        string strDescription = "";
        string strViolationName = string.Empty;
    
        if (IsPost)
        {
            strViolationName = Request["ViolationName"];
    
            FileStream fsViolationsTypes = null;
            string strViolationsTypesFile = Server.MapPath("~/App_Data/ViolationsTypes.tts");
            TrafficTicketsSystem1.Models.ViolationType category = new TrafficTicketsSystem1.Models.ViolationType();
            LinkedList<TrafficTicketsSystem1.Models.ViolationType> categories = new LinkedList<TrafficTicketsSystem1.Models.ViolationType>();
            System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bfViolationsTypes = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
    
            if (System.IO.File.Exists(strViolationsTypesFile))
            {
                using (fsViolationsTypes = new FileStream(strViolationsTypesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    categories = (LinkedList<TrafficTicketsSystem1.Models.ViolationType>)bfViolationsTypes.Deserialize(fsViolationsTypes);
                }
                category.ViolationName = strViolationName;
    
                LinkedListNode<TrafficTicketsSystem1.Models.ViolationType> type = categories.Find(category);
                strDescription = type.Value.Description;
            }
        }
    }
    
    <h2 class="common-font bold maroon text-center">Violation Type Details</h2>
    
    <hr />
    
    @using (Html.BeginForm())
    {
        <div class="large-content common-font">
            <table>
                <tr>
                    <td class="small-text bold maroon">Violation Name</td>
                    <td>@Html.TextBox("ViolationName", @strViolationName, htmlAttributes: new { @class = "form-control small-text" })</td>
                    <td width="20">&nbsp;</td>
                    <td><input type="submit" value="Find" class="btn btn-warning small-text" /></td>
                </tr>
            </table>
            <br />
            <table>
                <tr>
                    <td class="small-text maroon bold">Description</td>
                    <td><textarea rows="10" cols="40" class="form-control">@strDescription</textarea></td>
                </tr>
            </table>
        </div>
    }
    
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Violations Types", "Index") ::
        @Html.ActionLink("Edit/Update Violation Type", "PrepareEdit") ::
        @Html.ActionLink("Create New Violation Type", "Create") ::
        @Html.ActionLink("Delete a Violation Type", "Delete")</p>
  5. Click the ViolationsTypesController.cs tab to access it again
  6. Create four methods as follows:
    using System.IO;
    using System.Web.Mvc;
    using System.Collections.Generic;
    using TrafficTicketsSystem1.Models;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace TrafficTicketsSystem1.Controllers
    {
        public class ViolationsTypesController : Controller
        {
            . . . No Change
    
            // GET: ViolationsTypes/Details/
            public ActionResult Details()
            {
                return View();
            }
    
            // GET: ViolationsTypes/PrepareEdit/
            public ActionResult PrepareEdit()
            {
                return View();
            }
    
            // GET: ViolationsTypes/ConfirmEdit/
            public ActionResult ConfirmEdit(FormCollection collection)
            {
                if (!string.IsNullOrEmpty(collection["ViolationName"]))
                {
                    FileStream fsViolationsTypes = null;
                    ViolationType violationType = new ViolationType();
                    BinaryFormatter bfViolationsTypes = new BinaryFormatter();
                    LinkedList<ViolationType> violationsTypes = new LinkedList<ViolationType>();
                    string strViolationsTypesFile = Server.MapPath("~/App_Data/ViolationsTypes.tts");
    
                    if (System.IO.File.Exists(strViolationsTypesFile))
                    {
                        using (fsViolationsTypes = new FileStream(strViolationsTypesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            violationsTypes = (LinkedList<ViolationType>)bfViolationsTypes.Deserialize(fsViolationsTypes);
                        }
    
                        violationType.ViolationName = collection["ViolationName"];
    
                        LinkedListNode<ViolationType> vt = violationsTypes.Find(violationType);
    
                        ViewBag.ViolationName = collection["ViolationName"];
                        ViewBag.Description = vt.Value.Description;
                    }
                }
    
                return View();
            }
    
            // GET: ViolationsTypes/Edit/
            public ActionResult Edit()
            {
                return View();
            }
    
            // POST: ViolationsTypes/Edit/
            [HttpPost]
            public ActionResult Edit(FormCollection collection)
            {
                try
                {
                    FileStream fsViolationsTypes = null;
                    ViolationType violationType = new ViolationType();
                    BinaryFormatter bfViolationsTypes = new BinaryFormatter();
                    LinkedList<ViolationType> ViolationsTypes = new LinkedList<ViolationType>();
                    string strViolationsTypesFile = Server.MapPath("~/App_Data/ViolationsTypes.tts");
    
                    if (!string.IsNullOrEmpty("ViolationName"))
                    {
                        if (System.IO.File.Exists(strViolationsTypesFile))
                        {
                            using (fsViolationsTypes = new FileStream(strViolationsTypesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                ViolationsTypes = (LinkedList<ViolationType>)bfViolationsTypes.Deserialize(fsViolationsTypes);
                            }
                        }
    
                        violationType.ViolationName = collection["ViolationName"];
    
                        LinkedListNode<ViolationType> vt = ViolationsTypes.Find(violationType);
    
                        vt.Value.Description = collection["Description"];
    
                        using (fsViolationsTypes = new FileStream(strViolationsTypesFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                        {
                            bfViolationsTypes.Serialize(fsViolationsTypes, ViolationsTypes);
                        }
                    }
    
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
        }
    }
  7. In the class, right-click PrepareEdit() -> Add View...
  8. Make sure the View Name text box is displaying PrepareEdit.
    Click Add
  9. Create the form as follows:
    using System.IO;
    using System.Web.Mvc;
    using System.Collections.Generic;
    using TrafficTicketsSystem1.Models;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace TrafficTicketsSystem1.Controllers
    {
        public class ViolationsTypesController : Controller
        {
            . . . No Change
    
            // GET: ViolationsTypes/Details/
            public ActionResult Details()
            {
                return View();
            }
    
            // GET: ViolationsTypes/PrepareEdit/
            public ActionResult PrepareEdit()
            {
                return View();
            }
    
            // GET: ViolationsTypes/ConfirmEdit/
            public ActionResult ConfirmEdit(FormCollection collection)
            {
                if (!string.IsNullOrEmpty(collection["ViolationName"]))
                {
                    FileStream fsViolationsTypes = null;
                    ViolationType violationType = new ViolationType();
                    BinaryFormatter bfViolationsTypes = new BinaryFormatter();
                    LinkedList<ViolationType> violationsTypes = new LinkedList<ViolationType>();
                    string strViolationsTypesFile = Server.MapPath("~/App_Data/ViolationsTypes.tts");
    
                    if (System.IO.File.Exists(strViolationsTypesFile))
                    {
                        using (fsViolationsTypes = new FileStream(strViolationsTypesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            violationsTypes = (LinkedList<ViolationType>)bfViolationsTypes.Deserialize(fsViolationsTypes);
                        }
    
                        violationType.ViolationName = collection["ViolationName"];
    
                        LinkedListNode<ViolationType> vt = violationsTypes.Find(violationType);
    
                        ViewBag.ViolationName = collection["ViolationName"];
                        ViewBag.Description = vt.Value.Description;
                    }
                }
    
                return View();
            }
    
            // GET: ViolationsTypes/Edit/
            public ActionResult Edit()
            {
                return View();
            }
    
            // POST: ViolationsTypes/Edit/
            [HttpPost]
            public ActionResult Edit(FormCollection collection)
            {
                try
                {
                    FileStream fsViolationsTypes = null;
                    ViolationType violationType = new ViolationType();
                    BinaryFormatter bfViolationsTypes = new BinaryFormatter();
                    LinkedList<ViolationType> ViolationsTypes = new LinkedList<ViolationType>();
                    string strViolationsTypesFile = Server.MapPath("~/App_Data/ViolationsTypes.tts");
    
                    if (!string.IsNullOrEmpty("ViolationName"))
                    {
                        if (System.IO.File.Exists(strViolationsTypesFile))
                        {
                            using (fsViolationsTypes = new FileStream(strViolationsTypesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                ViolationsTypes = (LinkedList<ViolationType>)bfViolationsTypes.Deserialize(fsViolationsTypes);
                            }
                        }
    
                        violationType.ViolationName = collection["ViolationName"];
    
                        LinkedListNode<ViolationType> vt = ViolationsTypes.Find(violationType);
    
                        vt.Value.Description = collection["Description"];
    
                        using (fsViolationsTypes = new FileStream(strViolationsTypesFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                        {
                            bfViolationsTypes.Serialize(fsViolationsTypes, ViolationsTypes);
                        }
                    }
    
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
        }
    }
  10. In the class, right-click PrepareEdit -> Add View...
  11. In the Add View dialog box, make sure the View Name text box is displaying PrepareEdit.
    Click Add
  12. Create a form as follows:
    @model TrafficTicketsSystem1.Models.ViolationType
    
    @{
        ViewBag.Title = "Prepare Violation Type Edit";
    }
    
    <h2 class="maroon common-font text-center bold">Prepare Violation Type Edition</h2>
    
    <hr />
    
    @using (Html.BeginForm("ConfirmEdit", "ViolationsTypes", FormMethod.Post))
    {
        @Html.AntiForgeryToken()
    
        <div class="large-content">
            <div class="form-horizontal common-font">
                @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                <div class="form-group">
                    @Html.LabelFor(model => model.ViolationName, htmlAttributes: new { @class = "control-label col-md-4 maroon" })
                    <div class="col-md-4">
                        @Html.EditorFor(model => model.ViolationName, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.ViolationName, "", new { @class = "text-danger" })
                    </div>
                    <div class="col-md-4">
                        <p><input type="submit" value="Find Violation Type" class="btn btn-warning" /></p>
                    </div>
                </div>
            </div>
        </div>
    }
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Violations Types", "Index") ::
        @Html.ActionLink("Create New Violation Type", "Create") ::
        @Html.ActionLink("Delete/Remove Violation Type", "PrepareDelete") ::
        @Html.ActionLink("Edit/Update Violation Type Definition", "PrepareEdit")</p>
  13. In the Solution Explorer, under Views, right-click ViolationsTypes -> Add -> View...
  14. Type ConfirmEdit as the View Name
  15. Click Add
  16. Create a form as follows:
    @{
        ViewBag.Title = "Confirm Violation Type Edition";
    }
    
    <h2 class="maroon common-font text-center bold">Confirm Violation Type Edition</h2>
    
    <hr />
    
    @using (Html.BeginForm("Edit", "ViolationsTypes", FormMethod.Post))
    {
        <div class="common-font large-content">
            <table>
                <tr>
                    <td class="small-text bold maroon">Violation Name</td>
                    <td>@Html.TextBox("ViolationName", @ViewBag.ViolationName as string, htmlAttributes: new { @class = "form-control" })</td>
                </tr>
                <tr>
                    <td></td>
                    <td></td>
                </tr>
                <tr>
                    <td class="maroon small-text bold">Description</td>
                    <td>@Html.TextArea("Description", @ViewBag.Description as string, htmlAttributes: new { @class = "form-control", rows = "10", cols = "50" })</td>
                </tr>
            </table>
        </div>
    
        <hr />
    
        <p class="text-center"><input type="submit" value="Save Camera Record" class="btn btn-warning" /></p>
        <div class="form-group">
            <label class="col-md-6 control-label"></label>
            <div class="col-md-6">
    
            </div>
        </div>
    }
    
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Violations Types", "Index") ::
        @Html.ActionLink("Create New Violation Type", "Create") ::
        @Html.ActionLink("Review Violation Type Definition", "Details") ::
        @Html.ActionLink("Delete/Remove Violation Type", "PrepareDelete")</p>
  17. In the Solution Explorer, under Controllers, double-click DriversController.cs to access it
  18. In the DriversController class, create new methods as follows:
    using System.IO;
    using System.Web.Mvc;
    using System.Collections.Generic;
    using TrafficTicketsSystem1.Models;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace TrafficTicketsSystem1.Controllers
    {
        public class DriversController : Controller
        {
            // GET: Drivers
            public ActionResult Index()
            {
                FileStream fsDrivers = null;
                BinaryFormatter bfDrivers = new BinaryFormatter();
                LinkedList<Driver> drivers = new LinkedList<Driver>();
                string strDriversFile = Server.MapPath("~/App_Data/Drivers.tts");
    
                if (System.IO.File.Exists(strDriversFile))
                {
                    using (fsDrivers = new FileStream(strDriversFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        drivers = (LinkedList<Driver>)bfDrivers.Deserialize(fsDrivers);
                    }
                }
    
                return View(drivers);
            }
    
            // GET: Drivers/Details
            public ActionResult Details()
            {
                return View();
            }
    
            // GET: Drivers/PrepareEdit/
            public ActionResult PrepareEdit()
            {
                return View();
            }
    
            // GET: Drivers/ConfirmEdit/
            public ActionResult ConfirmEdit(FormCollection collection)
            {
                if (!string.IsNullOrEmpty(collection["DrvLicNumber"]))
                {
                    FileStream fsDrivers       = null;
                    Driver driver              = new Driver();
                    BinaryFormatter bfDrivers  = new BinaryFormatter();
                    LinkedList<Driver> drivers = new LinkedList<Driver>();
                    string strDriversFile      = Server.MapPath("~/App_Data/Drivers.tts");
    
                    if (System.IO.File.Exists(strDriversFile))
                    {
                        using (fsDrivers = new FileStream(strDriversFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            drivers = (LinkedList<Driver>)bfDrivers.Deserialize(fsDrivers);
                        }
    
                        driver.DrvLicNumber = collection["DrvLicNumber"];
    
                        LinkedListNode<Driver> person = drivers.Find(driver);
    
                        ViewBag.DrvLicNumber = collection["DrvLicNumber"];
                        ViewBag.FirstName    = person.Value.FirstName;
                        ViewBag.LastName     = person.Value.LastName;
                        ViewBag.Address      = person.Value.Address;
                        ViewBag.City         = person.Value.City;
                        ViewBag.County       = person.Value.County;
                        ViewBag.State        = person.Value.State;
                        ViewBag.ZIPCode      = person.Value.ZIPCode;
                    }
                }
    
                return View();
            }
    
            // GET: Drivers/Edit/
            public ActionResult Edit()
            {
                return View();
            }
    
            // POST: Drivers/Edit/
            [HttpPost]
            public ActionResult Edit(FormCollection collection)
            {
                try
                {
                    FileStream fsDrivers       = null;
                    Driver driver              = new Driver();
                    BinaryFormatter bfDrivers  = new BinaryFormatter();
                    LinkedList<Driver> drivers = new LinkedList<Driver>();
                    string strDriversFile      = Server.MapPath("~/App_Data/Drivers.tts");
    
                    if (!string.IsNullOrEmpty("CameraNumber"))
                    {
                        if (System.IO.File.Exists(strDriversFile))
                        {
                            using (fsDrivers = new FileStream(strDriversFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                drivers = (LinkedList<Driver>)bfDrivers.Deserialize(fsDrivers);
                            }
                        }
    
                        driver.DrvLicNumber = collection["DrvLicNumber"];
    
                        LinkedListNode<Driver> person = drivers.Find(driver);
    
                        person.Value.FirstName = collection["FirstName"];
                        person.Value.LastName  = collection["LastName"];
                        person.Value.Address   = collection["Address"];
                        person.Value.City      = collection["City"];
                        person.Value.County    = collection["County"];
                        person.Value.State     = collection["State"];
                        person.Value.ZIPCode   = collection["ZIPCode"];
    
                        using (fsDrivers = new FileStream(strDriversFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                        {
                            bfDrivers.Serialize(fsDrivers, drivers);
                        }
                    }
    
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
        }
    }
  19. In the class, right-click Details() -> Add View...
  20. Make sure the View Name text box is displaying Details.
    Press Enter
  21. Change the document as follows:
    @{
        ViewBag.Title = "Driver's Details";
    }
    
    @{
        string strCity = string.Empty;
        string strState = string.Empty;
        string strCounty = string.Empty;
        string strZIPCode = string.Empty;
        string strAddress = string.Empty;
        string strLastName = string.Empty;
        string strFirstName = string.Empty;
        string strDrvLicNumber = string.Empty;
    
    
        if (IsPost)
        {
            strDrvLicNumber = Request["DrvLicNumber"];
    
            FileStream fsDrivers = null;
            string strDriversFile = Server.MapPath("~/App_Data/Drivers.tts");
            TrafficTicketsSystem13.Models.Driver driver = new TrafficTicketsSystem13.Models.Driver();
            LinkedList<TrafficTicketsSystem13.Models.Driver> drivers = new LinkedList<TrafficTicketsSystem13.Models.Driver>();
            System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bfDrivers = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
    
            if (System.IO.File.Exists(strDriversFile))
            {
                using (fsDrivers = new FileStream(strDriversFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    drivers = (LinkedList<TrafficTicketsSystem13.Models.Driver>)bfDrivers.Deserialize(fsDrivers);
                }
    
                driver.DrvLicNumber = strDrvLicNumber;
    
                LinkedListNode<TrafficTicketsSystem13.Models.Driver> person = drivers.Find(driver);
    
                strCity = person.Value.City;
                strState = person.Value.State;
                strCounty = person.Value.County;
                strZIPCode = person.Value.ZIPCode;
                strAddress = person.Value.Address;
                strLastName = person.Value.LastName;
                strFirstName = person.Value.FirstName;
            }
        }
    }
    
    <h2 class="common-font bold maroon text-center">Driver's Details</h2>
    
    <hr />
    
    @using (Html.BeginForm())
    {
        <div class="containment common-font">
            <div class="form-horizontal common-font">
                @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                <div class="form-group">
                    <label for="dln" class="control-label col-md-4 maroon">Drv. Lic. #</label>
                    <div class="col-md-4">
                        @Html.TextBox("DrvLicNumber", @strDrvLicNumber, htmlAttributes: new { @class = "form-control", id = "dln" })
                    </div>
                    <div class="col-md-4"><input type="submit" value="Find" class="btn btn-warning small-text" /></div>
                </div>
                <div class="form-group">
                    <label for="fName" class="small-text maroon col-md-5">First Name</label>
                    <div class="col-md-7">@Html.TextBox("FirstName", @strFirstName, htmlAttributes: new { @class = "form-control", id = "fName" })</div>
                </div>
                <div class="form-group">
                    <label for="lName" class="small-text maroon col-md-5">Last Name</label>
                    <div class="col-md-7">@Html.TextBox("LastName", @strLastName, htmlAttributes: new { @class = "form-control", id = "lName" })</div>
                </div>
                <div class="form-group">
                    <label for="adrs" class="small-text maroon col-md-5">Address</label>
                    <div class="col-md-7">@Html.TextBox("Address", @strAddress, htmlAttributes: new { @class = "form-control", id = "adrs" })</div>
                </div>
                <div class="form-group">
                    <label for="ct" class="small-text maroon col-md-5">City</label>
                    <div class="col-md-7">@Html.TextBox("City", @strCity, htmlAttributes: new { @class = "form-control", id = "ct" })</div>
                </div>
                <div class="form-group">
                    <label for="local" class="small-text maroon col-md-5">County</label>
                    <div class="col-md-7">@Html.TextBox("County", @strCounty, htmlAttributes: new { @class = "form-control", id = "local" })</div>
                </div>
                <div class="form-group">
                    <label for="government" class="small-text maroon col-md-5">State</label>
                    <div class="col-md-7">@Html.TextBox("State", @strState, htmlAttributes: new { @class = "form-control", id = "government" })</div>
                </div>
                <div class="form-group">
                    <label for="zip" class="small-text maroon col-md-5">ZIP Code</label>
                    <div class="col-md-7">@Html.TextBox("ZIPCode", @strZIPCode, htmlAttributes: new { @class = "form-control", id = "zip" })</div>
                </div>
            </div>
        </div>
    }
    
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Drivers - Vehicles Owners", "Index") ::
        @Html.ActionLink("Issue New Driver's License", "Create") ::
        @Html.ActionLink("Edit/Update a Driver's License", "PrepareEdit") ::
        @Html.ActionLink("Suspend/Delete/Remove a Driver's License", "PrepareDelete")</p>
  22. In the Solution Explorer, under Views, right-click Drivers -> Add -> View...
  23. Type PrepareEdit as the name of the view
  24. Click OK
  25. Create the form as follows:
    @model TrafficTicketsSystem1.Models.Driver
    
    @{
        ViewBag.Title = "Prepare Driver Edit";
    }
    
    @using (Html.BeginForm("ConfirmEdit", "Drivers", FormMethod.Post))
    {
        @Html.AntiForgeryToken()
    
        <div class="large-content">
            <div class="form-horizontal common-font">
                @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                <div class="form-group">
                    @Html.LabelFor(model => model.DrvLicNumber, htmlAttributes: new { @class = "control-label col-md-4 maroon" })
                    <div class="col-md-4">
                        @Html.EditorFor(model => model.DrvLicNumber, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.DrvLicNumber, "", new { @class = "text-danger" })
                    </div>
                    <div class="col-md-4">
                        <p><input type="submit" value="Find Driver" class="btn btn-warning small-text" /></p>
                    </div>
                </div>
            </div>
        </div>
    }
    <hr />
    
    <h2 class="maroon common-font text-center bold">Prepare Driver Edit</h2>
    
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Drivers - Vehicles Owners", "Index") ::
        @Html.ActionLink("Issue a New Driver's License", "Create") ::
        @Html.ActionLink("Review a Driver's License", "Details") ::
        @Html.ActionLink("Suspend/Delete/Remove a Driver's License", "PrepareDelete")</p>
  26. In the Solution Explorer, under Views, right-click Drivers -> Add -> View...
  27. Type ConfirmEdit as the View Name
  28. Click Add
  29. Create a form as follows:
    @{
        ViewBag.Title = "Confirm Driver Edit";
    }
    
    <h2 class="maroon common-font text-center bold">Confirm Driver Edit</h2>
    
    <hr />
    
    @using (Html.BeginForm("Edit", "Drivers", FormMethod.Post))
    {
        <div class="containment">
            <div class="small-content common-font">
                <table>
                    <tr>
                        <td class="small-text bold maroon">Drv. Lic. #</td>
                        <td>@Html.TextBox("DrvLicNumber", @ViewBag.DrvLicNumber as string, htmlAttributes: new { @class = "form-control large-text" })</td>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td></td>
                    </tr>
                    <tr>
                        <td class="maroon bold">First Name</td>
                        <td>@Html.TextBox("FirstName", @ViewBag.FirstName as string, htmlAttributes: new { @class = "form-control large-text" })</td>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td></td>
                    </tr>
                    <tr>
                        <td class="maroon bold">Last Name</td>
                        <td>@Html.TextBox("LastName", @ViewBag.LastName as string, htmlAttributes: new { @class = "form-control large-text" })</td>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td></td>
                    </tr>
                    <tr>
                        <td class="maroon bold">Address</td>
                        <td>@Html.TextBox("Address", @ViewBag.Address as string, htmlAttributes: new { @class = "form-control large-text" })</td>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td></td>
                    </tr>
                    <tr>
                        <td class="small-text bold maroon">City</td>
                        <td>@Html.TextBox("City", @ViewBag.City as string, htmlAttributes: new { @class = "form-control large-text" })</td>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td></td>
                    </tr>
                    <tr>
                        <td class="maroon bold">County</td>
                        <td>@Html.TextBox("County", @ViewBag.County as string, htmlAttributes: new { @class = "form-control large-text" })</td>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td></td>
                    </tr>
                    <tr>
                        <td class="maroon bold">State</td>
                        <td>@Html.TextBox("State", @ViewBag.State as string, htmlAttributes: new { @class = "form-control large-text" })</td>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td></td>
                    </tr>
                    <tr>
                        <td class="maroon bold">ZIP Code</td>
                        <td>@Html.TextBox("ZIPCode", @ViewBag.ZIPCode as string, htmlAttributes: new { @class = "form-control large-text" })</td>
                    </tr>
                </table>
            </div>
        </div>
    
        <hr />
    
        <p class="text-center"><input type="submit" value="Save/Update Driver Record" class="btn btn-warning" /></p>
        <div class="form-group">
            <label class="col-md-6 control-label"></label>
            <div class="col-md-6">
    
            </div>
        </div>
    }
    
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Drivers - Vehicles Owners", "Index") ::
        @Html.ActionLink("Process New Driver's License", "Create") ::
        @Html.ActionLink("Review Driver's License", "Details") ::
        @Html.ActionLink("Delete/Remove Driver Record", "PrepareDelete")</p>
  30. In the Solution Explorer, under Controllers, double-click CamerasController.cs

Finding the Last Instance of a Certain Node

If the list contains more than one node that has the value but you prefer to use the last node, you can call the FindLast() method. Its syntax is:

public LinkedListNode<T> FindLast(T value);

If the linked list contains unique nodes (that is, each node is somehow different from the others (this can be taken care of by the ID-based property), you can still use this method to look for a node.

Practical LearningPractical Learning: Finding the Last Instance of a Certain Node

  1. In the CamerasController class, create a method named Details as follows:
    using System.IO;
    using System.Web.Mvc;
    using System.Collections.Generic;
    using TrafficTicketsSystem1.Models;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace TrafficTicketsSystem1.Controllers
    {
        public class CamerasController : Controller
        {
            // GET: Cameras
            public ActionResult Index()
            {
                FileStream fsCameras = null;
                BinaryFormatter bfCameras = new BinaryFormatter();
                LinkedList<Camera> cameras = new LinkedList<Camera>();
                string strCamerasFile = Server.MapPath("~/App_Data/Cameras.tts");
    
                // If a file for Cameras records was proviously created, open it
                if (System.IO.File.Exists(strCamerasFile))
                {
                    using (fsCameras = new FileStream(strCamerasFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        /* After opening the file, get the list of records from it
                         * and store in the declared LinkedList<> variable. */
                        cameras = (LinkedList<Camera>)bfCameras.Deserialize(fsCameras);
                    }
                }
    
                return View(cameras);
            }
    
            // GET: Cameras/Details/
            public ActionResult Details()
            {
                return View();
            }
        }
    }
  2. In the class, right-click Details() -> Add View...
  3. In the Add View dialog box, make sure the View Name dialog box is displaying Details.
    Click Add
  4. Change the document as follows:
    @{
        ViewBag.Title = "Camera Details";
    }
    
    @{
        string strMake = string.Empty;
        string strModel = string.Empty;
        string strLocation = string.Empty;
        string strCameraNumber = string.Empty;
    
        if (IsPost)
        {
            strCameraNumber = Request["CameraNumber"];
    
            FileStream fsCameras = null;
            string strCamerasFile = Server.MapPath("~/App_Data/Cameras.tts");
            TrafficTicketsSystem1.Models.Camera camera = new TrafficTicketsSystem1.Models.Camera();
            LinkedList<TrafficTicketsSystem1.Models.Camera> cameras = new LinkedList<TrafficTicketsSystem1.Models.Camera>();
            System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bfCameras = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
    
            if (System.IO.File.Exists(strCamerasFile))
            {
                using (fsCameras = new FileStream(strCamerasFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    cameras = (LinkedList<TrafficTicketsSystem1.Models.Camera>)bfCameras.Deserialize(fsCameras);
                }
    
                camera.CameraNumber = strCameraNumber;
    
                LinkedListNode<TrafficTicketsSystem1.Models.Camera> viewer = cameras.FindLast(camera);
                strMake = viewer.Value.Make;
                strModel = viewer.Value.Model;
                strLocation = viewer.Value.Location;
            }
        }
    }
    
    <h2 class="common-font bold maroon text-center">Camera Details</h2>
    
    <hr />
    
    @using (Html.BeginForm())
    {
        <div class="containment common-font">
            <table>
                <tr>
                    <td class="small-text bold maroon">Camera #</td>
                    <td>@Html.TextBox("CameraNumber", @strCameraNumber, htmlAttributes: new { @class = "form-control small-text" })</td>
                    <td>&nbsp;</td>
                    <td><input type="submit" value="Find" class="btn btn-warning small-text" /></td>
                </tr>
            </table>
            <br />
            <table>
                <tr>
                    <td class="small-text maroon bold">Make</td>
                    <td>@Html.TextBox("Make", @strMake, htmlAttributes: new { @class = "form-control" })</td>
                </tr>
                <tr>
                    <td>&nbsp;</td>
                    <td></td>
                </tr>
                <tr>
                    <td class="small-text maroon bold">Model</td>
                    <td>@Html.TextBox("Model", @strModel, htmlAttributes: new { @class = "form-control" })</td>
                </tr>
                <tr>
                    <td>&nbsp;</td>
                    <td></td>
                </tr>
                <tr>
                    <td class="small-text maroon bold">Location</td>
                    <td>@Html.TextBox("Location", @strLocation, htmlAttributes: new { @class = "form-control" })</td>
                </tr>
            </table>
        </div>
    }
    
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Cameras", "Index") ::
        @Html.ActionLink("Edit/Update Camera Details", "PrepareEdit") ::
        @Html.ActionLink("Create New Camera", "Create") ::
        @Html.ActionLink("Delete/Remove a Cameras", "PrepareDelete")</p>
  5. Click the CamerasController.cs tab
  6. Create four methods as follows:
    using System.IO;
    using System.Web.Mvc;
    using System.Collections.Generic;
    using TrafficTicketsSystem1.Models;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace TrafficTicketsSystem1.Controllers
    {
        public class CamerasController : Controller
        {
            // GET: Cameras
            public ActionResult Index()
            {
                FileStream fsCameras = null;
                BinaryFormatter bfCameras = new BinaryFormatter();
                LinkedList<Camera> cameras = new LinkedList<Camera>();
                string strCamerasFile = Server.MapPath("~/App_Data/Cameras.tts");
    
                // If a file for Cameras records was proviously created, open it
                if (System.IO.File.Exists(strCamerasFile))
                {
                    using (fsCameras = new FileStream(strCamerasFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        /* After opening the file, get the list of records from it
                         * and store in the declared LinkedList<> variable. */
                        cameras = (LinkedList<Camera>)bfCameras.Deserialize(fsCameras);
                    }
                }
    
                return View(cameras);
            }
    
            // GET: Cameras/Details/
            public ActionResult Details()
            {
                return View();
            }
    
            // GET: Cameras/PrepareEdit/
            public ActionResult PrepareEdit()
            {
                return View();
            }
    
            // GET: Cameras/ConfirmEdit/
            public ActionResult ConfirmEdit(FormCollection collection)
            {
                if (!string.IsNullOrEmpty(collection["CameraNumber"]))
                {
                    FileStream         fsCameras      = null;
                    Camera             camera         = new Camera();
                    BinaryFormatter    bfCameras      = new BinaryFormatter();
                    LinkedList<Camera> cameras        = new LinkedList<Camera>();
                    string             strCamerasFile = Server.MapPath("~/App_Data/Cameras.tts");
    
                    if (System.IO.File.Exists(strCamerasFile))
                    {
                        using (fsCameras = new FileStream(strCamerasFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            cameras = (LinkedList<Camera>)bfCameras.Deserialize(fsCameras);
                        }
    
                        camera.CameraNumber = collection["CameraNumber"];
    
                        LinkedListNode<Camera> viewer = cameras.FindLast(camera);
    
                        ViewBag.CameraNumber = collection["CameraNumber"];
                        ViewBag.Make = viewer.Value.Make;
                        ViewBag.Model = viewer.Value.Model;
                        ViewBag.Location = viewer.Value.Location;
                    }
                }
    
                return View();
            }
    
            // GET: Cameras/Edit/
            public ActionResult Edit()
            {
                return View();
            }
    
            // POST: Cameras/Edit/
            [HttpPost]
            public ActionResult Edit(FormCollection collection)
            {
                try
                {
                    FileStream fsCameras = null;
                    Camera camera = new Camera();
                    BinaryFormatter bfCameras = new BinaryFormatter();
                    LinkedList<Camera> cameras = new LinkedList<Camera>();
                    string strCamerasFile = Server.MapPath("~/App_Data/Cameras.tts");
    
                    if (!string.IsNullOrEmpty("CameraNumber"))
                    {
                        if (System.IO.File.Exists(strCamerasFile))
                        {
                            using (fsCameras = new FileStream(strCamerasFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                cameras = (LinkedList<Camera>)bfCameras.Deserialize(fsCameras);
                            }
                        }
    
                        camera.CameraNumber = collection["CameraNumber"];
    
                        LinkedListNode<Camera> viewer = cameras.FindLast(camera);
    
                        viewer.Value.Make = collection["Make"];
                        viewer.Value.Model = collection["Model"];
                        viewer.Value.Location = collection["Location"];
    
                        using (fsCameras = new FileStream(strCamerasFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                        {
                            bfCameras.Serialize(fsCameras, cameras);
                        }
                    }
    
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
        }
    }
  7. In the document, right-click PrepareEdit() and click Add View...
  8. Make sure the View Name text box is displaying PrepareEdit.
    Click Add
  9. Change the document as follows:
    @model TrafficTicketsSystem1.Models.Camera
    
    @{
        ViewBag.Title = "Prepare Camera Edit";
    }
    
    <h2 class="maroon common-font text-center bold">Prepare Camera Details Edition</h2>
    
    <hr />
    
    @using (Html.BeginForm("ConfirmEdit", "Cameras", FormMethod.Post))
    {
        @Html.AntiForgeryToken()
    
        <div class="large-content">
            <div class="form-horizontal common-font">
                @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                <div class="form-group">
                    @Html.LabelFor(model => model.CameraNumber, htmlAttributes: new { @class = "control-label col-md-4 maroon" })
                    <div class="col-md-4">
                        @Html.EditorFor(model => model.CameraNumber, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.CameraNumber, "", new { @class = "text-danger" })
                    </div>
                    <div class="col-md-4">
                        <p><input type="submit" value="Find Camera" class="btn btn-warning small-text" /></p>
                    </div>
                </div>
            </div>
        </div>
    }
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Cameras", "Index") ::
        @Html.ActionLink("Create New Camera", "Create") ::
        @Html.ActionLink("Review Camera Details", "Details") ::
        @Html.ActionLink("Delete/Remove Camera", "PrepareDelete")</p>
  10. In the Solution Explorer, under Views, right-click Cameras -> Add -> View...
  11. Type ConfirmEdit as the name of the view
  12. Click OK
  13. Change the document as follows:
    @{
        ViewBag.Title = "Confirm Camera Edit";
    }
    
    <h2 class="maroon common-font text-center bold">Editing Camera Details</h2>
    
    <hr />
    
    @using (Html.BeginForm("Edit", "Cameras", FormMethod.Post))
    {
        <div class="containment">
            <div class="small-content common-font">
                <table>
                    <tr>
                        <td class="small-text bold maroon">Camera #</td>
                        <td>@Html.TextBox("CameraNumber", @ViewBag.CameraNumber as string, htmlAttributes: new { @class = "form-control large-text" })</td>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td></td>
                    </tr>
                    <tr>
                        <td class="maroon bold">Make</td>
                        <td>@Html.TextBox("Make", @ViewBag.Make as string, htmlAttributes: new { @class = "form-control large-text" })</td>
                    </tr>
                    <tr>
                        <td></td>
                        <td></td>
                    </tr>
                    <tr>
                        <td class="maroon bold">Model</td>
                        <td>@Html.TextBox("Model", @ViewBag.Model as string, htmlAttributes: new { @class = "form-control large-text" })</td>
                    </tr>
                    <tr>
                        <td></td>
                        <td></td>
                    </tr>
                    <tr>
                        <td class="maroon bold">Location</td>
                        <td>@Html.TextBox("Location", @ViewBag.Location as string, htmlAttributes: new { @class = "form-control large-text" })</td>
                    </tr>
                </table>
            </div>
        </div>
    
        <hr />
    
        <div class="form-group">
            <label class="col-md-6 control-label"></label>
            <div class="col-md-6">
                <p class="text-center"><input type="submit" value="Save Camera Record" class="btn btn-warning" /></p>
            </div>
        </div>
    }
    
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Cameras", "Index") ::
        @Html.ActionLink("Create New Camera", "Create") ::
        @Html.ActionLink("Review Camera Details", "Details") ::
        @Html.ActionLink("Delete/Remove Camera", "PrepareDelete")</p>
  14. In the Solution Explorer, under Controllers, double-click VehiclesController.cs to access it
  15. In the VehiclesController class, add new methods as follows:
    using System.IO;
    using System.Web.Mvc;
    using System.Collections.Generic;
    using TrafficTicketsSystem1.Models;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace TrafficTicketsSystem1.Controllers
    {
        public class VehiclesController : Controller
        {
            // GET: Vehicles
            public ActionResult Index()
            {
                FileStream fsVehicles = null;
                BinaryFormatter bfVehicles = new BinaryFormatter();
                LinkedList<Vehicle> vehicles = new LinkedList<Vehicle>();
    
                string strVehiclesFile = Server.MapPath("~/App_Data/Vehicles.tts");
    
                if (System.IO.File.Exists(strVehiclesFile))
                {
                    using (fsVehicles = new FileStream(strVehiclesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        vehicles = (LinkedList<Vehicle>)bfVehicles.Deserialize(fsVehicles);
                    }
                }
    
                return View(vehicles);
            }
    
            // GET: Vehicles/Details/5
            public ActionResult Details()
            {
                return View();
            }
    
            // GET: Vehicles/PrepareEdit/
             public ActionResult PrepareEdit()
            {
                return View();
            }
    
            // GET: Vehicles/ConfirmEdit/
             public ActionResult ConfirmEdit(FormCollection collection)
            {
                if (!string.IsNullOrEmpty(collection["TagNumber"]))
                {
                    FileStream fsVehicles = null;
                    Vehicle vehicle = new Vehicle();
                    BinaryFormatter bfVehicles = new BinaryFormatter();
                    LinkedList<Vehicle> vehicles = new LinkedList<Vehicle>();
                    string strVehiclesFile = Server.MapPath("~/App_Data/Vehicles.tts");
    
                    if (System.IO.File.Exists(strVehiclesFile))
                    {
                        using (fsVehicles = new FileStream(strVehiclesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            vehicles = (LinkedList<Vehicle>)bfVehicles.Deserialize(fsVehicles);
                        }
    
                        vehicle.TagNumber = collection["TagNumber"];
    
                        LinkedListNode<Vehicle> car = vehicles.FindLast(vehicle);
    
                        ViewBag.TagNumber = collection["TagNumber"];
                        ViewBag.DrvLicNumber = car.Value.DrvLicNumber;
                        ViewBag.Make = car.Value.Make;
                        ViewBag.Model = car.Value.Model;
                        ViewBag.VehicleYear = car.Value.VehicleYear;
                        ViewBag.Color = car.Value.Color;
                    }
                }
    
                return View();
            }
    
            // GET: Vehicles/Edit/
             public ActionResult Edit()
            {
                return View();
            }
    
            // POST: Vehicles/Edit/
            [HttpPost]
             public ActionResult Edit(FormCollection collection)
            {
                try
                {
                    FileStream fsVehicles = null;
                    Vehicle vehicle = new Vehicle();
                    BinaryFormatter bfVehicles = new BinaryFormatter();
                    LinkedList<Vehicle> vehicles = new LinkedList<Vehicle>();
                    string strVehiclesFile = Server.MapPath("~/App_Data/Vehicles.tts");
    
                    if (!string.IsNullOrEmpty("CameraNumber"))
                    {
                        if (System.IO.File.Exists(strVehiclesFile))
                        {
                            using (fsVehicles = new FileStream(strVehiclesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                vehicles = (LinkedList<Vehicle>)bfVehicles.Deserialize(fsVehicles);
                            }
                        }
    
                        vehicle.TagNumber = collection["TagNumber"];
    
                        LinkedListNode<Vehicle> car = vehicles.FindLast(vehicle);
    
                        car.Value.TagNumber = collection["TagNumber"];
                        car.Value.Make = collection["Make"];
                        car.Value.Model = collection["Model"];
                        car.Value.VehicleYear = collection["VehicleYear"];
                        car.Value.Color = collection["Color"];
    
                        using (fsVehicles = new FileStream(strVehiclesFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                        {
                            bfVehicles.Serialize(fsVehicles, vehicles);
                        }
                    }
    
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
        }
    }
  16. In the class, right-click Details() -> Add View...
  17. In the Add View dialog box, make sure the View Name dialog box is displaying Details.
    Click Add
  18. Change the document as follows:
    @{
        ViewBag.Title = "Vehicle Details";
    
        string strTagNumber    = string.Empty;
        string strState        = string.Empty;
        string strMake         = string.Empty;
        string strModel        = string.Empty;
        string strVehicleYear  = string.Empty;
        string strColor        = string.Empty;
        string strDrvLicNumber = string.Empty;
    
        if (IsPost)
        {
            strTagNumber = Request["TagNumber"];
    
            FileStream fsVehicles = null;
            string strVehiclesFile = Server.MapPath("~/App_Data/Vehicles.tts");
            TrafficTicketsSystem1.Models.Vehicle car = new TrafficTicketsSystem1.Models.Vehicle();
            LinkedList<TrafficTicketsSystem1.Models.Vehicle> vehicles = new LinkedList<TrafficTicketsSystem1.Models.Vehicle>();
            System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bfVehicles = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
    
            if (System.IO.File.Exists(strVehiclesFile))
            {
                using (fsVehicles = new FileStream(strVehiclesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    vehicles = (LinkedList<TrafficTicketsSystem1.Models.Vehicle>)bfVehicles.Deserialize(fsVehicles);
                }
    
                car.TagNumber = strTagNumber;
    
                LinkedListNode<TrafficTicketsSystem1.Models.Vehicle> node = vehicles.FindLast(car);
    
                strTagNumber = node.Value.TagNumber;
                strDrvLicNumber = node.Value.DrvLicNumber;
                strMake = node.Value.Make;
                strModel = node.Value.Model;
                strVehicleYear = node.Value.VehicleYear;
                strColor = node.Value.Color;
            }
        }
    }
    
    <h2 class="common-font bold maroon text-center">Vehicle Details</h2>
    
    <hr />
    
    @using (Html.BeginForm())
    {
        <div class="large-content common-font">
            <table>
                <tr>
                    <td class="small-text bold maroon">Tag #</td>
                    <td>@Html.TextBox("TagNumber", @strTagNumber, htmlAttributes: new { @class = "form-control small-text" })</td>
                    <td width="20">&nbsp;</td>
                    <td><input type="submit" value="Find" class="btn btn-warning small-text" /></td>
                </tr>
            </table>
            <br />
            <table>
                <tr>
                    <td class="small-text maroon bold">Drv. Lic. #</td>
                    <td>@Html.TextBox("DrvLicNumber", @strDrvLicNumber, htmlAttributes: new { @class = "form-control" })</td>
                </tr>
                <tr>
                    <td>&nbsp;</td>
                    <td></td>
                </tr>
                <tr>
                    <td class="small-text maroon bold">Make</td>
                    <td>@Html.TextBox("Make", @strMake, htmlAttributes: new { @class = "form-control" })</td>
                </tr>
                <tr>
                    <td>&nbsp;</td>
                    <td></td>
                </tr>
                <tr>
                    <td class="small-text maroon bold">Model</td>
                    <td>@Html.TextBox("Model", @strModel, htmlAttributes: new { @class = "form-control" })</td>
                </tr>
                <tr>
                    <td>&nbsp;</td>
                    <td></td>
                </tr>
                <tr>
                    <td class="small-text maroon bold">City</td>
                    <td>@Html.TextBox("VehicleYear", @strVehicleYear, htmlAttributes: new { @class = "form-control" })</td>
                </tr>
                <tr>
                    <td>&nbsp;</td>
                    <td></td>
                </tr>
                <tr>
                    <td class="small-text maroon bold">County</td>
                    <td>@Html.TextBox("Color", @strColor, htmlAttributes: new { @class = "form-control" })</td>
                </tr>
            </table>
        </div>
    }
    
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Cars - Vehicles", "Index") ::
        @Html.ActionLink("Issue New Vehicle's License", "Create") ::
        @Html.ActionLink("Edit/Update a Vehicle's License", "PrepareEdit") ::
        @Html.ActionLink("Suspend/Delete/Remove a Vehicle's License", "PrepareDelete")</p>
  19. In the Solution Explorer, under Views, right-click Vehicles -> Add -> View...
  20. Type PrepareEdit as the name of the view
  21. Click Add
  22. Create a form as follows:
    @model TrafficTicketsSystem1.Models.Vehicle
    
    @{
        ViewBag.Title = "Prepare Vehicle Edit";
    }
    
    <h2 class="maroon common-font text-center bold">Prepare Vehicle Edition</h2>
    
    <hr />
    
    @using (Html.BeginForm("ConfirmEdit", "Vehicles", FormMethod.Post))
    {
        @Html.AntiForgeryToken()
    
        <div class="large-content">
            <div class="form-horizontal common-font">
                @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                <div class="form-group">
                    @Html.LabelFor(model => model.TagNumber, htmlAttributes: new { @class = "control-label col-md-4 maroon" })
                    <div class="col-md-4">
                        @Html.EditorFor(model => model.TagNumber, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.TagNumber, "", new { @class = "text-danger" })
                    </div>
                    <div class="col-md-4">
                        <p><input type="submit" value="Find Vehicle" class="btn btn-warning small-text" /></p>
                    </div>
                </div>
            </div>
        </div>
    }
    
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Cars - Vehicles", "Index") ::
        @Html.ActionLink("Create Vehicle Registration", "Create") ::
        @Html.ActionLink("Vehicle Details", "Details") ::
        @Html.ActionLink("Delete Vehicle Record", "PrepareDelete")</p>
  23. In the Solution Explorer, under Views, right-click Vehicles -> Add -> View...
  24. Type ConfirmEdit as the name of the view
  25. Click OK
  26. Change the document as follows:
    @{
        ViewBag.Title = "Confirm Vehicle Edit";
    }
    
    <h2 class="common-font bold maroon text-center">Confirm Vehicle Edition</h2>
    
    <hr />
    
    @using (Html.BeginForm("Edit", "Vehicles", FormMethod.Post))
    {
        <div class="large-content">
            <div class="form-horizontal common-font">
                @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                <div class="form-group">
                    <label for="tagNbr" class="control-label col-md-5 maroon">Tag #</label>
                    <div class="col-md-7">
                        @Html.TextBox("TagNumber", @ViewBag.TagNumber as string, htmlAttributes: new { @class = "form-control", id = "tagNbr" })
                    </div>
                </div>
                <div class="form-group">
                    <label for="dln" class="control-label col-md-5 maroon">Drv. Lic. #</label>
                    <div class="col-md-7">@Html.TextBox("DrvLicNumber", @ViewBag.DrvLicNumber as string, htmlAttributes: new { @class = "form-control", id = "dln" })</div>
                </div>
                <div class="form-group">
                    <label for="make" class="control-label col-md-5 maroon">Make</label>
                    <div class="col-md-7">@Html.TextBox("Make", @ViewBag.Make as string, htmlAttributes: new { @class = "form-control", id = "make" })</div>
                </div>
                <div class="form-group">
                    <label for="mdl" class="control-label col-md-5 maroon">Model</label>
                    <div class="col-md-7">@Html.TextBox("Model", @ViewBag.Model as string, htmlAttributes: new { @class = "form-control", id = "mdl" })</div>
                </div>
                <div class="form-group">
                    <label for="vYear" class="control-label col-md-5 maroon">Vehicle Year</label>
                    <div class="col-md-7">@Html.TextBox("VehicleYear", @ViewBag.VehicleYear as string, htmlAttributes: new { @class = "form-control", id = "vYear" })</div>
                </div>
                <div class="form-group">
                    <label for="clr" class="control-label col-md-5 maroon">Color</label>
                    <div class="col-md-7">@Html.TextBox("Color", @ViewBag.Color as string, htmlAttributes: new { @class = "form-control", id = "clr" })</div>
                </div>
            </div>
        </div>
    
        <hr />
    
        <div class="form-group">
            <label class="col-md-6 control-label"></label>
            <div class="col-md-6">
                <p><input type="submit" value="Update Vehicle Registration" class="btn btn-warning" /></p>
            </div>
        </div>
    }
    
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Vehicles", "Index") ::
        @Html.ActionLink("Register New Vehicle", "Create") ::
        @Html.ActionLink("Vehicle Details", "Details") ::
        @Html.ActionLink("Delete Vehicle Record", "PrepareDelete")</p>
  27. In the Solution Explorer, under Controllers, double-click TrafficViolationsController.cs to access it
  28. In the TrafficViolations class, add new methods as follows:
    using System.IO;
    using System.Web.Mvc;
    using System.Collections.Generic;
    using TrafficTicketsSystem1.Models;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace TrafficTicketsSystem1.Controllers
    {
        public class TrafficViolationsController : Controller
        {
            // GET: TrafficViolations
            public ActionResult Index()
            {
                FileStream fsTrafficViolations = null;
                BinaryFormatter bfTrafficViolations = new BinaryFormatter();
                LinkedList<TrafficViolation> violations = new LinkedList<TrafficViolation>();
    
                string strTrafficViolationsFile = Server.MapPath("~/App_Data/TrafficViolations.tts");
    
                if (System.IO.File.Exists(strTrafficViolationsFile))
                {
                    using (fsTrafficViolations = new FileStream(strTrafficViolationsFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        violations = (LinkedList<TrafficViolation>)bfTrafficViolations.Deserialize(fsTrafficViolations);
                    }
                }
    
                return View(violations);
            }
    
            // GET: Drivers/Details/
            public ActionResult Details()
            {
                return View();
            }
    
            // GET: TrafficViolations/PrepareEdit/
            public ActionResult PrepareEdit()
            {
                return View();
            }
    
            // GET: TrafficViolations/ConfirmEdit/
            public ActionResult ConfirmEdit(FormCollection collection)
            {
                FileStream fsTrafficViolations = null;
                BinaryFormatter bfTrafficViolations = new BinaryFormatter();
                LinkedList<TrafficViolation> violations = new LinkedList<TrafficViolation>();
                string strTrafficViolationsFile = Server.MapPath("~/App_Data/TrafficViolations.tts");
    
                if (System.IO.File.Exists(strTrafficViolationsFile))
                {
                    using (fsTrafficViolations = new FileStream(strTrafficViolationsFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        violations = (LinkedList<TrafficViolation>)bfTrafficViolations.Deserialize(fsTrafficViolations);
                    }
    
                    TrafficViolation violation = new TrafficViolation();
                    violation.TrafficViolationNumber = int.Parse(collection["TrafficViolationNumber"]);
    
                    LinkedListNode<TrafficViolation> node = violations.FindLast(violation);
    
                    BinaryFormatter bfCameras = new BinaryFormatter();
                    FileStream fsCameras = null, fsViolationsTypes = null;
                    LinkedList<Camera> cameras = new LinkedList<Camera>();
                    BinaryFormatter bfViolationsTypes = new BinaryFormatter();
                    string strCamerasFile = Server.MapPath("~/App_Data/Cameras.tts");
                    LinkedList<ViolationType> violationsTypes = new LinkedList<ViolationType>();
                    string strViolationsTypesFile = Server.MapPath("~/App_Data/ViolationsTypes.tts");
    
                    List<SelectListItem> itemsCameras = new List<SelectListItem>();
                    List<SelectListItem> paymentsStatus = new List<SelectListItem>();
                    List<SelectListItem> itemsPhotoAvailable = new List<SelectListItem>();
                    List<SelectListItem> itemsVideoAvailable = new List<SelectListItem>();
                    List<SelectListItem> itemsViolationsTypes = new List<SelectListItem>();
    
                    if (System.IO.File.Exists(strCamerasFile))
                    {
                        using (fsCameras = new FileStream(strCamerasFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            cameras = (LinkedList<Camera>)bfCameras.Deserialize(fsCameras);
    
                            foreach (Camera cmr in cameras)
                            {
                                itemsCameras.Add(new SelectListItem() { Text = cmr.CameraNumber, Value = cmr.CameraNumber, Selected = (node.Value.CameraNumber == cmr.CameraNumber) });
                            }
                        }
                    }
    
                    if (System.IO.File.Exists(strViolationsTypesFile))
                    {
                        using (fsViolationsTypes = new FileStream(strViolationsTypesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            violationsTypes = (LinkedList<ViolationType>)bfViolationsTypes.Deserialize(fsViolationsTypes);
    
                            foreach (ViolationType vt in violationsTypes)
                            {
                                itemsViolationsTypes.Add(new SelectListItem() { Text = vt.ViolationName, Value = vt.ViolationName, Selected = (node.Value.ViolationName == vt.ViolationName) });
                            }
                        }
                    }
    
                    itemsPhotoAvailable.Add(new SelectListItem() { Value = "Unknown" });
                    itemsPhotoAvailable.Add(new SelectListItem() { Text = "No", Value = "No", Selected = (node.Value.PhotoAvailable == "No") });
                    itemsPhotoAvailable.Add(new SelectListItem() { Text = "Yes", Value = "Yes", Selected = (node.Value.PhotoAvailable == "Yes") });
                    itemsVideoAvailable.Add(new SelectListItem() { Value = "Unknown" });
                    itemsVideoAvailable.Add(new SelectListItem() { Text = "No", Value = "No", Selected = (node.Value.VideoAvailable == "No") });
                    itemsVideoAvailable.Add(new SelectListItem() { Text = "Yes", Value = "Yes", Selected = (node.Value.VideoAvailable == "Yes") });
    
                    paymentsStatus.Add(new SelectListItem() { Value = "Unknown" });
                    paymentsStatus.Add(new SelectListItem() { Text = "Pending", Value = "Pending", Selected = (node.Value.PaymentStatus == "Pending") });
                    paymentsStatus.Add(new SelectListItem() { Text = "Rejected", Value = "Rejected", Selected = (node.Value.PaymentStatus == "Rejected") });
                    paymentsStatus.Add(new SelectListItem() { Text = "Cancelled", Value = "Cancelled", Selected = (node.Value.PaymentStatus == "Cancelled") });
                    paymentsStatus.Add(new SelectListItem() { Text = "Paid Late", Value = "Paid Late", Selected = (node.Value.PaymentStatus == "Paid Late") });
                    paymentsStatus.Add(new SelectListItem() { Text = "Paid On Time", Value = "Paid On Time", Selected = (node.Value.PaymentStatus == "Paid On Time") });
    
                    ViewBag.CameraNumber = itemsCameras;
                    ViewBag.PaymentStatus = paymentsStatus;
                    ViewBag.TagNumber = node.Value.TagNumber;
                    ViewBag.PaymentDate = node.Value.PaymentDate;
                    ViewBag.ViolationName = itemsViolationsTypes;
                    ViewBag.PhotoAvailable = itemsPhotoAvailable;
                    ViewBag.VideoAvailable = itemsVideoAvailable;
                    ViewBag.PaymentAmount = node.Value.PaymentAmount;
                    ViewBag.ViolationDate = node.Value.ViolationDate;
                    ViewBag.ViolationTime = node.Value.ViolationTime;
                    ViewBag.PaymentDueDate = node.Value.PaymentDueDate;
                    ViewBag.TrafficViolationNumber = node.Value.TrafficViolationNumber;
                }
    
                return View();
            }
    
            // GET: TrafficViolations/Edit/
            public ActionResult Edit()
            {
                return View();
            }
    
            // POST: TrafficViolations/Edit/
            [HttpPost]
            public ActionResult Edit(FormCollection collection)
            {
                try
                {
                    FileStream fsTrafficViolations = null;
                    TrafficViolation violation = new TrafficViolation();
                    BinaryFormatter bfTrafficViolations = new BinaryFormatter();
                    LinkedList<TrafficViolation> violations = new LinkedList<TrafficViolation>();
                    string strTrafficViolationsFile = Server.MapPath("~/App_Data/TrafficViolations.tts");
    
                    if (!string.IsNullOrEmpty("TrafficViolationNumber"))
                    {
                        if (System.IO.File.Exists(strTrafficViolationsFile))
                        {
                            using (fsTrafficViolations = new FileStream(strTrafficViolationsFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                violations = (LinkedList<TrafficViolation>)bfTrafficViolations.Deserialize(fsTrafficViolations);
                            }
                        }
    
                        violation.TrafficViolationNumber = int.Parse(collection["TrafficViolationNumber"]);
    
                        LinkedListNode<TrafficViolation> infraction = violations.FindLast(violation);
    
                        infraction.Value.CameraNumber = collection["CameraNumber"];
                        infraction.Value.TagNumber = collection["TagNumber"];
                        infraction.Value.ViolationName = collection["ViolationName"];
                        infraction.Value.ViolationDate = collection["ViolationDate"];
                        infraction.Value.ViolationTime = collection["ViolationTime"];
                        infraction.Value.PhotoAvailable = collection["PhotoAvailable"];
                        infraction.Value.VideoAvailable = collection["VideoAvailable"];
                        infraction.Value.PaymentDueDate = collection["PaymentDueDate"];
                        infraction.Value.PaymentDate = collection["PaymentDate"];
                        infraction.Value.PaymentAmount = double.Parse(collection["PaymentAmount"]);
                        infraction.Value.PaymentStatus = collection["PaymentStatus"];
    
                        using (fsTrafficViolations = new FileStream(strTrafficViolationsFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                        {
                            bfTrafficViolations.Serialize(fsTrafficViolations, violations);
                        }
                    }
    
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
    
            // GET: Drivers/PrepareCitation/
            public ActionResult PrepareCitation()
            {
                return View();
            }
    
            /* This function takes the available status of a photo and video taken during the traffic violation.
               The function returns a sentence that will instruct the driver about how to view the photo or video or the violation. */
            private string GetPhotoVideoOptions(string photo, string video)
            {
                var sentence = string.Empty;
                var pvAvailable = "No";
    
                if (photo == "Yes")
                {
                    if (video == "Yes")
                    {
                        pvAvailable = "Yes";
                        sentence = "To view the photo and/or video";
                    }
                    else
                    {
                        pvAvailable = "Yes";
                        sentence = "To see a photo";
                    }
                }
                else
                { // if (photo == "No")
                    if (video == "Yes")
                    {
                        pvAvailable = "Yes";
                        sentence = "To review a video";
                    }
                    else
                    {
                        pvAvailable = "No";
                    }
                }
    
                if (pvAvailable == "No")
                    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.";
            }
    
            // GET: Drivers/PresentCitation/
            public ActionResult PresentCitation(FormCollection collection)
            {
                FileStream fsTrafficViolations = null;
                BinaryFormatter bfTrafficViolations = new BinaryFormatter();
                LinkedList<TrafficViolation> violations = new LinkedList<TrafficViolation>();
                string strTrafficViolationsFile = Server.MapPath("~/App_Data/TrafficViolations.tts");
    
                if (System.IO.File.Exists(strTrafficViolationsFile))
                {
                    using (fsTrafficViolations = new FileStream(strTrafficViolationsFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        violations = (LinkedList<TrafficViolation>)bfTrafficViolations.Deserialize(fsTrafficViolations);
                    }
    
                    TrafficViolation violation = new TrafficViolation();
                    violation.TrafficViolationNumber = int.Parse(collection["TrafficViolationNumber"]);
    
                    LinkedListNode<TrafficViolation> nodeTrafficViolation = violations.FindLast(violation);
    
                    ViewBag.TrafficViolationNumber = collection["TrafficViolationNumber"];
    
                    ViewBag.ViolationDate = nodeTrafficViolation.Value.ViolationDate;
                    ViewBag.ViolationTime = nodeTrafficViolation.Value.ViolationTime;
                    ViewBag.PaymentAmount = nodeTrafficViolation.Value.PaymentAmount.ToString("C");
                    ViewBag.PaymentDueDate = nodeTrafficViolation.Value.PaymentDueDate;
    
                    ViewBag.PhotoVideo = GetPhotoVideoOptions(nodeTrafficViolation.Value.PhotoAvailable, nodeTrafficViolation.Value.VideoAvailable);
    
                    FileStream fsViolationsTypes = null;
                    ViolationType category = new ViolationType();
                    BinaryFormatter bfViolationsTypes = new BinaryFormatter();
                    LinkedList<ViolationType> categories = new LinkedList<ViolationType>();
                    string strViolationsTypesFile = Server.MapPath("~/App_Data/ViolationsTypes.tts");
    
                    if (System.IO.File.Exists(strViolationsTypesFile))
                    {
                        using (fsViolationsTypes = new FileStream(strViolationsTypesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            categories = (LinkedList<ViolationType>)bfViolationsTypes.Deserialize(fsViolationsTypes);
                        }
    
                        category.ViolationName = nodeTrafficViolation.Value.ViolationName;
    
                        LinkedListNode<ViolationType> type = categories.Find(category);
                        ViewBag.ViolationName = nodeTrafficViolation.Value.ViolationName;
                        ViewBag.ViolationDescription = type.Value.Description;
                    }
    
                    FileStream fsVehicles = null;
                    Vehicle car = new Vehicle();
                    BinaryFormatter bfVehicles = new BinaryFormatter();
                    LinkedList<Vehicle> vehicles = new LinkedList<Vehicle>();
    
                    string strVehiclesFile = Server.MapPath("~/App_Data/Vehicles.tts");
    
                    using (fsVehicles = new FileStream(strVehiclesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        vehicles = (LinkedList<Vehicle>)bfVehicles.Deserialize(fsVehicles);
                    }
    
                    car.TagNumber = nodeTrafficViolation.Value.TagNumber;
                    LinkedListNode<Vehicle> nodeVehicle = vehicles.FindLast(car);
    
                    ViewBag.Vehicle = nodeVehicle.Value.Make + " " + nodeVehicle.Value.Model + ", " + 
                                      nodeVehicle.Value.Color + ", " + nodeVehicle.Value.VehicleYear + " (Tag # " + 
                                      nodeVehicle.Value.TagNumber + ")";
    
                    FileStream fsDrivers = null;
                    Driver driver = new Driver();
                    BinaryFormatter bfDrivers = new BinaryFormatter();
                    LinkedList<Driver> drivers = new LinkedList<Driver>();
                    string strDriversFile = Server.MapPath("~/App_Data/Drivers.tts");
    
                    using (fsDrivers = new FileStream(strDriversFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        drivers = (LinkedList<Driver>)bfDrivers.Deserialize(fsDrivers);
                    }
    
                    driver.DrvLicNumber = nodeVehicle.Value.DrvLicNumber;
                    LinkedListNode<Driver> person = drivers.Find(driver);
    
                    ViewBag.DriverName = person.Value.FirstName + " " + person.Value.LastName + " (Drv. Lic. # " + driver.DrvLicNumber + ")";
                    ViewBag.DriverAddress = person.Value.Address + " " + person.Value.City + ", " + person.Value.State + " " + person.Value.ZIPCode;
    
                    FileStream fsCameras = null;
                    BinaryFormatter bfCameras = new BinaryFormatter();
                    LinkedList<Camera> cameras = new LinkedList<Camera>();
                    string strCamerasFile = Server.MapPath("~/App_Data/Cameras.tts");
                    LinkedList<ViolationType> violationsTypes = new LinkedList<ViolationType>();
                    
                    using (fsCameras = new FileStream(strCamerasFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        cameras = (LinkedList<Camera>)bfCameras.Deserialize(fsCameras);
                    }
    
                    Camera camera = new Camera();
    
                    camera.CameraNumber = nodeTrafficViolation.Value.CameraNumber;
    
                    LinkedListNode<Camera> viewer = cameras.FindLast(camera);
    
                    ViewBag.Camera = viewer.Value.Make + " " + viewer.Value.Model + " (" + viewer.Value.CameraNumber + ")";
                    ViewBag.ViolationLocation = viewer.Value.Location;
                }
    
                return View();
            }
        }
    }
  29. In the class, right-click Details() -> Add View...
  30. In the Add View dialog box, make sure the View Name dialog box is displaying Details.
    Click Add
  31. Change the document as follows:
    @{
        ViewBag.Title = "Traffic Violation Details";
    }
    
    @{
        double dPaymentAmount = 0.00;
        string strTagNumber = string.Empty;
        string strPaymentDate = string.Empty;
        string strCameraNumber = string.Empty;
        string strPaymentStatus = string.Empty;
        string strViolationName = string.Empty;
        string strViolationDate = string.Empty;
        string strViolationTime = string.Empty;
        string strPhotoAvailable = string.Empty;
        string strVideoAvailable = string.Empty;
        string strPaymentDueDate = string.Empty;
        string strTrafficViolationNumber = string.Empty;
    
    
        if (IsPost)
        {
            strTrafficViolationNumber = Request["TrafficViolationNumber"];
    
            FileStream fsTrafficViolations = null;
            string strTrafficViolationsFile = Server.MapPath("~/App_Data/TrafficViolations.tts");
            LinkedList<TrafficTicketsSystem1.Models.TrafficViolation> violations = new LinkedList<TrafficTicketsSystem1.Models.TrafficViolation>();
            System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bfTrafficViolations = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
    
            if (System.IO.File.Exists(strTrafficViolationsFile))
            {
                using (fsTrafficViolations = new FileStream(strTrafficViolationsFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    violations = (LinkedList<TrafficTicketsSystem1.Models.TrafficViolation>)bfTrafficViolations.Deserialize(fsTrafficViolations);
                }
    
                TrafficTicketsSystem1.Models.TrafficViolation violation = new TrafficTicketsSystem1.Models.TrafficViolation();
                violation.TrafficViolationNumber = int.Parse(strTrafficViolationNumber);
    
                LinkedListNode<TrafficTicketsSystem1.Models.TrafficViolation> node = violations.FindLast(violation);
    
                strTagNumber = node.Value.TagNumber;
                strPaymentDate = node.Value.PaymentDate;
                strCameraNumber = node.Value.CameraNumber;
                strPaymentStatus = node.Value.PaymentStatus;
                dPaymentAmount = node.Value.PaymentAmount;
                strViolationName = node.Value.ViolationName;
                strViolationDate = node.Value.ViolationDate;
                strViolationTime = node.Value.ViolationTime;
                strPhotoAvailable = node.Value.PhotoAvailable;
                strVideoAvailable = node.Value.VideoAvailable;
                strPaymentDueDate = node.Value.PaymentDueDate;
            }
        }
    }
    
    <h2 class="common-font bold maroon text-center">Traffic Violation Details</h2>
    
    <hr />
    
    @using (Html.BeginForm())
    {
        <div class="large-content">
            <div class="form-horizontal common-font">
                @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                <div class="form-group">
                    <label for="tvn" class="control-label col-md-4 maroon">Traffic Violation #</label>
                    <div class="col-md-4">
                        @Html.TextBox("TrafficViolationNumber", @strTrafficViolationNumber, htmlAttributes: new { @class = "form-control", id = "tvn" })
                    </div>
                    <div class="col-md-4"><input type="submit" value="Find Traffic Violation" class="btn btn-warning" /></div>
                </div>
                <div class="form-group">
                    <label for="cmrNbr" class="control-label col-md-5 maroon">Camera #</label>
                    <div class="col-md-7">@Html.TextBox("CameraNumber", @strCameraNumber, htmlAttributes: new { @class = "form-control", id = "cmrNbr" })</div>
                </div>
                <div class="form-group">
                    <label for="tagNbr" class="control-label col-md-5 maroon">Tag #</label>
                    <div class="col-md-7">@Html.TextBox("TagNumber", @strTagNumber, htmlAttributes: new { @class = "form-control", id = "tagNbr" })</div>
                </div>
                <div class="form-group">
                    <label for="vType" class="control-label col-md-5 maroon">Violation Type</label>
                    <div class="col-md-7">@Html.TextBox("ViolationName", @strViolationName, htmlAttributes: new { @class = "form-control", id = "vType" })</div>
                </div>
                <div class="form-group">
                    <label for="vDate" class="control-label col-md-5 maroon">Violation Date</label>
                    <div class="col-md-7">@Html.TextBox("ViolationDate", @strViolationDate, htmlAttributes: new { @class = "form-control", id = "vDate" })</div>
                </div>
                <div class="form-group">
                    <label for="vTime" class="control-label col-md-5 maroon">Violation Time</label>
                    <div class="col-md-7">@Html.TextBox("ViolationTime", @strViolationTime, htmlAttributes: new { @class = "form-control", id = "vTime" })</div>
                </div>
                <div class="form-group">
                    <label for="photo" class="control-label col-md-5 maroon">Photo Available</label>
                    <div class="col-md-7">@Html.TextBox("PhotoAvailable", @strPhotoAvailable, htmlAttributes: new { @class = "form-control", id = "photo" })</div>
                </div>
                <div class="form-group">
                    <label for="video" class="control-label col-md-5 maroon">Video Available</label>
                    <div class="col-md-7">@Html.TextBox("VideoAvailable", @strVideoAvailable, htmlAttributes: new { @class = "form-control", id = "video" })</div>
                </div>
                <div class="form-group">
                    <label for="pdd" class="control-label col-md-5 maroon">Payment Due Date</label>
                    <div class="col-md-7">@Html.TextBox("PaymentDueDate", @strPaymentDueDate, htmlAttributes: new { @class = "form-control", id = "pdd" })</div>
                </div>
                <div class="form-group">
                    <label for="pmtDate" class="control-label col-md-5 maroon">Payment Date</label>
                    <div class="col-md-7">@Html.TextBox("PaymentDate", @strPaymentDate, htmlAttributes: new { @class = "form-control", id = "pmtDate" })</div>
                </div>
                <div class="form-group">
                    <label for="pmtAmount" class="control-label col-md-5 maroon">Payment Amount</label>
                    <div class="col-md-7">@Html.TextBox("PaymentAmount", @dPaymentAmount, htmlAttributes: new { @class = "form-control", id = "pmtAmount" })</div>
                </div>
                <div class="form-group">
                    <label for="pmtStatus" class="control-label col-md-5 maroon">Payment Status</label>
                    <div class="col-md-7">@Html.TextBox("PaymentStatus", @strPaymentStatus, htmlAttributes: new { @class = "form-control", id = "pmtStatus" })</div>
                </div>
            </div>
        </div>
    }
    
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Traffic Violations", "Index") ::
        @Html.ActionLink("Process/Create a Traffic Violation", "Create") ::
        @Html.ActionLink("Edit/Update a Traffic Violation", "PrepareEdit") ::
        @Html.ActionLink("Delete/Remove a Traffic Violation", "PrepareDelete") ::
        @Html.ActionLink("Create/Review a Traffic Citation", "Citation")</p>
  32. In the Solution Explorer, under Views, right-click TrafficViolations -> Add -> View...
  33. Type PrepareEdit as the name of the view
  34. Click Add
  35. Create a form as follows:
    @model TrafficTicketsSystem1.Models.TrafficViolation
    
    @{
        ViewBag.Title = "Prepare Traffic Violation Edit";
    }
    
    <h2 class="common-font bold maroon text-center">Prepare Traffic Violation Edition</h2>
    
    <hr />
    
    @using (Html.BeginForm("ConfirmEdit", "TrafficViolations", FormMethod.Post))
    {
        @Html.AntiForgeryToken()
    
        <div class="large-content">
            <div class="form-horizontal common-font">
                @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                <div class="form-group">
                    @Html.LabelFor(model => model.TrafficViolationNumber, htmlAttributes: new { @class = "control-label col-md-4 maroon" })
                    <div class="col-md-4">
                        @Html.EditorFor(model => model.TrafficViolationNumber, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.TrafficViolationNumber, "", new { @class = "text-danger" })
                    </div>
                    <div class="col-md-4">
                        <p><input type="submit" value="Find Traffic Violation" class="btn btn-warning" /></p>
                    </div>
                </div>
            </div>
        </div>
    }
    
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Traffic Violations", "Index") ::
        @Html.ActionLink("Process a New Traffic Violation", "Create") ::
        @Html.ActionLink("Review a Traffic Violation", "Details") ::
        @Html.ActionLink("Suspend/Delete/Cancel a Traffic Violation", "PrepareDelete") ::
        @Html.ActionLink("Prepare/Review a Citation", "Citation")</p>
  36. In the Solution Explorer, under Views, right-click TrafficViolations -> Add -> View...
  37. Type ConfirmEdit as the name of the view
  38. Click OK
  39. Change the document as follows:
    @{
        ViewBag.Title = "Confirm Traffic Violation Edit";
    }
    
    <h2 class="common-font bold maroon text-center">Confirm Traffic Violation Edition</h2>
    
    <hr />
    
    @using (Html.BeginForm("Edit", "TrafficViolations", FormMethod.Post))
    {
        <div class="large-content">
            <div class="form-horizontal common-font">
                @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                <div class="form-group">
                    <label for="tvn" class="control-label col-md-5 maroon">Traffic Violation #</label>
                    <div class="col-md-7">
                        @Html.TextBox("TrafficViolationNumber", @ViewBag.TrafficViolationNumber as string, htmlAttributes: new { @class = "form-control", id = "tvn" })
                    </div>
                </div>
                <div class="form-group">
                    <label for="cmrNbr" class="control-label col-md-5 maroon">Camera #</label>
                    <div class="col-md-7">@Html.DropDownList("CameraNumber", @ViewBag.CamerasNumbers as SelectList, htmlAttributes: new { @class = "form-control", id = "cmrNbr" })</div>
                </div>
                <div class="form-group">
                    <label for="tagNbr" class="control-label col-md-5 maroon">Tag #</label>
                    <div class="col-md-7">@Html.TextBox("TagNumber", @ViewBag.TagNumber as string, htmlAttributes: new { @class = "form-control", id = "tagNbr" })</div>
                </div>
                <div class="form-group">
                    <label for="vType" class="control-label col-md-5 maroon">Violation Type</label>
                    <div class="col-md-7">@Html.DropDownList("ViolationName", @ViewBag.ViolationsNames as SelectList, htmlAttributes: new { @class = "form-control", id = "vType" })</div>
                </div>
                <div class="form-group">
                    <label for="vDate" class="control-label col-md-5 maroon">Violation Date</label>
                    <div class="col-md-7">@Html.TextBox("ViolationDate", @ViewBag.ViolationDate as string, htmlAttributes: new { @class = "form-control", id = "vDate" })</div>
                </div>
                <div class="form-group">
                    <label for="vTime" class="control-label col-md-5 maroon">Violation Time</label>
                    <div class="col-md-7">@Html.TextBox("ViolationTime", @ViewBag.ViolationTime as string, htmlAttributes: new { @class = "form-control", id = "vTime" })</div>
                </div>
                <div class="form-group">
                    <label for="photo" class="control-label col-md-5 maroon">Photo Available</label>
                    <div class="col-md-7">@Html.DropDownList("PhotoAvailable", @ViewBag.PhotosAvailable as SelectList, htmlAttributes: new { @class = "form-control", id = "photo" })</div>
                </div>
                <div class="form-group">
                    <label for="video" class="control-label col-md-5 maroon">Video Available</label>
                    <div class="col-md-7">@Html.DropDownList("VideoAvailable", @ViewBag.VideosAvailable as SelectList, htmlAttributes: new { @class = "form-control", id = "video" })</div>
                </div>
                <div class="form-group">
                    <label for="pdd" class="control-label col-md-5 maroon">Payment Due Date</label>
                    <div class="col-md-7">@Html.TextBox("PaymentDueDate", @ViewBag.PaymentDueDate as string, htmlAttributes: new { @class = "form-control", id = "pdd" })</div>
                </div>
                <div class="form-group">
                    <label for="pmtDate" class="control-label col-md-5 maroon">Payment Date</label>
                    <div class="col-md-7">@Html.TextBox("PaymentDate", @ViewBag.PaymentDate as string, htmlAttributes: new { @class = "form-control", id = "pmtDate" })</div>
                </div>
                <div class="form-group">
                    <label for="pmtAmount" class="control-label col-md-5 maroon">Payment Amount</label>
                    <div class="col-md-7">@Html.TextBox("PaymentAmount", @ViewBag.PaymentAmount as string, htmlAttributes: new { @class = "form-control", id = "pmtAmount" })</div>
                </div>
                <div class="form-group">
                    <label for="pmtStatus" class="control-label col-md-5 maroon">Payment Status</label>
                    <div class="col-md-7">@Html.DropDownList("PaymentStatus", @ViewBag.PaymentsStatus as SelectList, htmlAttributes: new { @class = "form-control", id = "pmtStatus" })</div>
                </div>
            </div>
        </div>
    
        <hr />
    
        <div class="form-group">
            <label class="col-md-6 control-label"></label>
            <div class="col-md-6">
                <p><input type="submit" value="Update Traffic Violation" class="btn btn-warning" /></p>
            </div>
        </div>
    }
    
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Traffic Violations", "Index") ::
        @Html.ActionLink("Process/Create a Traffic Violation", "Create") ::
        @Html.ActionLink("Edit/Update a Traffic Violation", "PrepareEdit") ::
        @Html.ActionLink("Delete/Remove a Traffic Violation", "PrepareDelete") ::
        @Html.ActionLink("Create/Review a Traffic Citation", "Citation")
    </p>
  40. In the Solution Explorer, under Views, right-click TrafficViolations -> Add -> View...
  41. Type PrepareCitation in the View Name
  42. Press Enter
  43. Create a small form as follows:
    @model TrafficTicketsSystem1.Models.TrafficViolation
    
    @{
        ViewBag.Title = "Prepare Citation/Infraction";
    }
    
    <h2 class="maroon bold text-center common-font">Prepare Citation/Infraction</h2>
    
    <hr />
    
    @using (Html.BeginForm("PresentCitation", "TrafficViolations", FormMethod.Post))
    {
        @Html.AntiForgeryToken()
    
        <div class="large-content">
            <div class="form-horizontal common-font">
                @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                <div class="form-group">
                    @Html.LabelFor(model => model.TrafficViolationNumber, htmlAttributes: new { @class = "control-label col-md-4 maroon" })
                    <div class="col-md-4">
                        @Html.EditorFor(model => model.TrafficViolationNumber, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.TrafficViolationNumber, "", new { @class = "text-danger" })
                    </div>
                    <div class="col-md-4">
                        <p><input type="submit" value="Find Traffic Violation" class="btn btn-warning" /></p>
                    </div>
                </div>
            </div>
        </div>
    }
    
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Traffic Violations", "Index") ::
        @Html.ActionLink("Process a New Traffic Violation", "Create") ::
        @Html.ActionLink("Review a Traffic Violation", "Details") ::
        @Html.ActionLink("Edit/Update a Traffic Violation", "PrepareEdit") ::
        @Html.ActionLink("Delete/Dismiss a Traffic Violation", "PrepareDelete")</p>
  44. In the Solution Explorer, under Views, right-click TrafficViolations -> Add -> View...
  45. Type PresentCitation as the name of the view
  46. Click Add
  47. Change the document as follows:
    @{
        ViewBag.Title = "Citation";
    }
    
    <div>
        <h2 class="common-font bold text-center maroon">City of Jamies Town</h2>
        <h3 class="text-center common-font bold">6824 Cochran Ave, Ste 318<br />Jamies Town, MD 20540</h3>
        
        <div class="row common-font">
            <div class="col-md-8">
                <h4 class="common-font bold">Citation #: @ViewBag.TrafficViolationNumber</h4>
    
                <h4 class="common-font bold">Violation Type: @ViewBag.ViolationName Violation</h4>
                <hr />
                <h4 class="common-font bold">@ViewBag.DriverName</h4>
                <h5 class="common-font bold">@ViewBag.DriverAddress"</h5>
                <h5 class="common-font bold">Vehicle: @ViewBag.Vehicle</h5>
                <hr />
                <h5 class="common-font bold">To @ViewBag.DriverName</h5>
    
                <p>Our records indicate that on @ViewBag.ViolationDate at @ViewBag.ViolationTime, at @ViewBag.ViolationLocation, the above mentioned vehicle committed a @ViewBag.ViolationName violation. @ViewBag.ViolationDescription.</p>
    
                <p>If you recognize the traffic violation, please pay @ViewBag.PaymentAmount by @ViewBag.PaymentDueDate. 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 back to us.</p>
            </div>
            <div class="col-md-4">
                <p>@ViewBag.PhotoVideo</p>
            </div>
        </div>
    </div>
  48. In the Solution Explorer, under Controllers, double-click CamerasController.cs to access it

Navigating Among the Nodes

The First and the Last Nodes

As mentioned already, a linked list has a first and a last nodes (some people or documentations call them the head and the tail). To identify the first node, the LinkedList class is equippped with a read-only property named First. Its syntax is:

public LinkedListNode<T> First { get; }

The last node is represented by a read-only property of the same name and that, too, is a LinkedListNode object:

public LinkedListNode<T> Last { get; }

Here are examples of accessing these properties:

<!DOCTYPE html>
<html>
<head>
<title>Numbers</title>
</head>
<body>
<h2>Numbers</h2>

@{
    List<double> values = new List<double>();
    values.Add(84.597);
    values.Add(6.47);
    values.Add(2747.06);
    values.Add(282.924);

    LinkedList<double> numbers = new LinkedList<double>(values);
    LinkedListNode<double> number = new LinkedListNode<double>(148.24);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(35.75);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(2222.06);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(4.19);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(66.18);
    numbers.AddFirst(number);
}

<p>The value of the first node is @numbers.First.Value</p>
<p>The value of the last node is @numbers.Last.Value</p>
</body>
</html>

This would produce:

Label

The Next and Previous Nodes

To access a node that is next to an existing node, you must first know what node is used as reference. To let you access the next node, the LinkedListNode class is equipped with a read-only property named Next:

public LinkedListNode<T> Next { get; }

To let you access the node previous to an existing one, the LinkedListNode class is equipped with the read-only Previous property:

public LinkedListNode Previous { get; }

Remember that in both cases, you need a node as reference. Here examples of accessing these two properties:

<!DOCTYPE html>
<html>
<head>
<title>Numbers</title>
</head>
<body>
<h2>Numbers</h2>

@{
    List<double> values = new List<double>();
    values.Add(84.597);
    values.Add(6.47);
    values.Add(2747.06);
    values.Add(282.924);

    LinkedList<double> numbers = new LinkedList<double>(values);
    LinkedListNode<double> number = new LinkedListNode<double>(148.24);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(35.75);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(2222.06);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(4.19);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(66.18);
    numbers.AddFirst(number);
}

<ul>
    @foreach (double nbr in numbers)
    {
        <li>Number: @nbr</li>
    }
</ul>

<p>The value of the first node is @numbers.First.Value</p>
<p>The value of the last node is @numbers.Last.Value</p>
<hr />

@{ LinkedListNode<double> reference = numbers.Find(2222.06); }

<p>The node next to 2222.06 is @reference.Next.Value</p>
<p>The node preceeding 2222.06 is @reference.Previous.Value</p>
</body>
</html>

This would produce:

Linked Lists - The Next and Previous Nodes

Creating Nodes

Adding the First Node

When dealing with a linked list, you have many options on how to add a new node. As mentioned already, a linked list has a first node, a last node, and one or more nodes between them. All nodes have and use some references with regards to the node(s) close to them. Based on this, when adding a new node, you have to specify whether you want it as the first node, the last node, the node before a certain node, or the node after a certain one. The LinkedList class easily supports all these operations with very little effort on your part.

We saw that you could call the AddFirst() method to add a new node. In reality, there is no such a thing as simply adding a new node to a linked list. When a linked list has just been created and it is empty, it holds a reference to a null node. There is nothing you can do with that node and you don't need to do anything with it. To start adding nodes, you have the option of setting it as the first or the last item. This would not make any difference because there is no other node in the list.

After adding a node, it becomes a reference that new nodes can use. If you call the AddFirst() method, the new node would be added before any existing node in the collection.

Practical LearningPractical Learning: Adding a First to a Linked List

  1. In the CamerasController class, create two methods named Create as follows:
    using System.IO;
    using System.Web.Mvc;
    using System.Collections.Generic;
    using TrafficTicketsSystem1.Models;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace TrafficTicketsSystem1.Controllers
    {
        public class CamerasController : Controller
        {
            . . . No Change
    
            // GET: Cameras/Create
            public ActionResult Create()
            {
                return View();
            }
    
            // POST: Cameras/Create
            [HttpPost]
            public ActionResult Create(FormCollection collection)
            {
                try
                {
                    FileStream fsCameras = null;
                    BinaryFormatter bfCameras = new BinaryFormatter();
                    LinkedList<Camera> cameras = new LinkedList<Camera>();
                    string strCamerasFile = Server.MapPath("~/App_Data/Cameras.tts");
    
                    if (!string.IsNullOrEmpty("CameraNumber"))
                    {
                        if (System.IO.File.Exists(strCamerasFile))
                        {
                            using (fsCameras = new FileStream(strCamerasFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                cameras = (LinkedList<Camera>)bfCameras.Deserialize(fsCameras);
                            }
                        }
    
                        Camera viewer = new Camera()
                        {
                            CameraNumber = collection["CameraNumber"],
                            Make = collection["Make"],
                            Model = collection["Model"],
                            Location = collection["Location"]
                        };
    
                        cameras.AddFirst(viewer);
    
                        using (fsCameras = new FileStream(strCamerasFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                        {
                            bfCameras.Serialize(fsCameras, cameras);
                        }
                    }
    
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
        }
    }
  2. In the document, right-click one of the Create() method -> Add View...
  3. In the Add View dialog box, make sure the View Name text box is displaying Create.
    Click Add
  4. Change the document as follows:
    @model TrafficTicketsSystem1.Models.Camera
    
    @{
        ViewBag.Title = "Create Camera";
    }
    
    <h2 class="common-font text-center bold maroon">Camera Setup</h2>
    
    <hr />
    
    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()
    
        <div class="large-content">
            <div class="form-horizontal common-font">
                @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                <div class="form-group">
                    @Html.LabelFor(model => model.CameraNumber, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.EditorFor(model => model.CameraNumber, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.CameraNumber, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    @Html.LabelFor(model => model.Make, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.EditorFor(model => model.Make, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.Make, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    @Html.LabelFor(model => model.Model, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.EditorFor(model => model.Model, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.Model, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    @Html.LabelFor(model => model.Location, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.EditorFor(model => model.Location, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.Location, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    <div class="col-md-5"></div>
                    <div class="col-md-7 text-center">
                        <input type="submit" value="Save this Camera Setup" class="btn btn-warning" />
                    </div>
                </div>
            </div>
        </div>
    }
    
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Cameras - Traffic Monitors", "Index") ::
        @Html.ActionLink("Review a Traffic Camera Setup", "Details") ::
        @Html.ActionLink("Edit/Update a Camera Setup", "PrepareEdit") ::
        @Html.ActionLink("Delete/Remove a Camera", "PrepareDelete")</p>

Adding the Last Node

To add a last node to a linked list, you can call a method named AddLast. It is overloaded with two versions whose syntaxes are:

public LinkedListNode<T> AddLast(T value);
public void AddLast(LinkedListNode<T> node);

When you call this method, the value or node you pass will be added as the last item in the list. Here is an example:

<!DOCTYPE html>
<html>
<head>
<title>Numbers</title>
</head>
<body>
<h2>Numbers</h2>

@{
    List<double> values = new List<double>();
    values.Add(84.597);
    values.Add(6.47);
    values.Add(2747.06);
    values.Add(282.924);

    LinkedList<double> numbers = new LinkedList<double>(values);
    LinkedListNode<double> number = new LinkedListNode<double>(148.24);
    numbers.AddFirst(number);

    numbers.AddLast(18264.86);

    number = new LinkedListNode<double>(35.75);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(2222.06);
    numbers.AddFirst(number);

    LinkedListNode<double> last = new LinkedListNode<double>(827366.993);
    numbers.AddLast(last);

    number = new LinkedListNode<double>(4.19);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(66.18);
    numbers.AddFirst(number);
}

<ul>
    @foreach (double nbr in numbers)
    {
        if( (nbr == 18264.86) || (nbr == 827366.993) )
        {
            <li style="color: tomato">Number: @nbr</li>
        }
        else
        {
            <li>Number: @nbr</li>
        }
    }
</ul>
</body>
</html>

This would produce:

Practical LearningPractical Learning: Adding a Last Node

  1. In the Solution Explorer, under Controllers, click VehiclesController.cs to access it
  2. In the VehiclesController class, create two methods named Create as follows:
    using System.IO;
    using System.Web.Mvc;
    using System.Collections.Generic;
    using TrafficTicketsSystem1.Models;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace TrafficTicketsSystem1.Controllers
    {
        public class VehiclesController : Controller
        {
            . . . No Change
    
            // GET: Vehicles/Create
            public ActionResult Create()
            {
                return View();
            }
    
            // POST: Vehicles/Create
            [HttpPost]
            public ActionResult Create(FormCollection collection)
            {
                try
                {
                    bool driverFound = false;
                    FileStream fsVehicles = null, fsDrivers = null;
                    BinaryFormatter bfDrivers = new BinaryFormatter();
                    BinaryFormatter bfVehicles = new BinaryFormatter();
                    LinkedList<Driver> drivers = new LinkedList<Driver>();
                    LinkedList<Vehicle> vehicles = new LinkedList<Vehicle>();
                    string strDriversFile = Server.MapPath("~/App_Data/Drivers.tts");
                    string strVehiclesFile = Server.MapPath("~/App_Data/Vehicles.tts");
    
                    // Open the file of the drivers records
                    if (System.IO.File.Exists(strDriversFile))
                    {
                        using (fsDrivers = new FileStream(strDriversFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            /* After opening the file, get the list of records from it
                             * and store in the empty LinkedList<> collection we started. */
                            drivers = (LinkedList<Driver>)bfDrivers.Deserialize(fsDrivers);
    
                            // Navigate to each record
                            foreach (Driver person in drivers)
                            {
                                /* When you get to a record, find out if its DrvLicNumber value 
                                 * is the DrvLicNumber the user typed on the form. */
                                if (person.DrvLicNumber == collection["DrvLicNumber"])
                                {
                                    /* If you find the record with that DrvLicNumber value, 
                                     * make a note to indicate it. */
                                    driverFound = true;
                                    break;
                                }
                            }
                        }
                    }
    
                    /* If the driverFound is true, it means the driver's license 
                     * number is valid, which means we can save the record. */
                    if (driverFound == true)
                    {
                        // Check whether a file for vehicles exists already.
                        if (System.IO.File.Exists(strVehiclesFile))
                        {
                            // If a file for vehicles exists already, open it ...
                            using (fsVehicles = new FileStream(strVehiclesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                // ... and store the records in our vehicles variable
                                vehicles = (LinkedList<Vehicle>)bfVehicles.Deserialize(fsVehicles);
                            }
                        }
    
                        Vehicle car = new Vehicle()
                        {
                            TagNumber = collection["TagNumber"],
                            DrvLicNumber = collection["DrvLicNumber"],
                            Make = collection["Make"],
                            Model = collection["Model"],
                            VehicleYear = collection["VehicleYear"],
                            Color = collection["Color"]
                        };
    
                        LinkedListNode<Vehicle> node = new LinkedListNode<Vehicle>(car);
                        vehicles.AddLast(node);
    
                        using (fsVehicles = new FileStream(strVehiclesFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                        {
                            bfVehicles.Serialize(fsVehicles, vehicles);
                        }
                    }
    
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
        }
    }
  3. In the class, right-click one of the Create() methods and click Add View...
  4. In the Add View dialog box, make sure the View Name text box is displaying Create.Click Add
  5. Change the document as follows:
    @model TrafficTicketsSystem1.Models.Vehicle
    
    @{
        ViewBag.Title = "Create Vehicle";
    }
    
    <h2 class="common-font maroon text-center bold">Vehicle Registration</h2>
    
    <hr />
    
    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()
    
        <div class="containment">
            <div class="form-horizontal common-font">
                @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                <div class="form-group">
                    @Html.LabelFor(model => model.TagNumber, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.EditorFor(model => model.TagNumber, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.TagNumber, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    <label for="drvLicNbr" class="control-label col-md-5 maroon">Driver's License #</label>
                    <div class="col-md-7">
                        @Html.EditorFor(model => model.DrvLicNumber, new { htmlAttributes = new { @class = "form-control", id = "drvLicNbr" } })
                        @Html.ValidationMessageFor(model => model.DrvLicNumber, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    @Html.LabelFor(model => model.Make, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.EditorFor(model => model.Make, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.Make, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    @Html.LabelFor(model => model.Model, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.EditorFor(model => model.Model, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.Model, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    @Html.LabelFor(model => model.VehicleYear, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.EditorFor(model => model.VehicleYear, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.VehicleYear, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    @Html.LabelFor(model => model.Color, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.EditorFor(model => model.Color, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.Color, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    <label class="col-md-6"></label>
                    <div class="col-md-6">
                        <input type="submit" value="Save this Vehicle's Record" class="btn btn-warning" />
                    </div>
                </div>
            </div>
        </div>
    }
    
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Cars - Vehicle", "Index") ::
        @Html.ActionLink("Edit/Update Vehicle Registration", "PrepareEdit") ::
        @Html.ActionLink("Vehicle Details", "Details") ::
        @Html.ActionLink("Delete Vehicle Record", "PrepareDelete")</p>

Nodes Maintenance in a Linked List

Inserting a Node Before a Referenced One

A linked list supports the concept of inserting a node but not exactly like traditional collections do it. With a linked list, you must add a node before or after an existing node used as reference.

Behind the scenes, before inserting a node, you must identify the position where you want to put it. That is, you must identify what node you will use as reference:

Inserting a New node Before a Node

In this case, you want to insert a new node before the Other Node. Behind the scenes, the reference between the two existing nodes must be brocken. Then the new node points to the Other Node as its next and the Other Node points at the New Node as its previous:

Inserting a New node Before a Node

After the new node has been added, it must point to the previous node (Some Node in our example) as its previous item. The previous node (Some Node in our example) must now point to the new node as its next item:

Inserting a New node Before a Node

As you may imagine, to insert a node, you must provide two pieces of information: a reference to the node that will succeed the new node, and the new node (or its value). If the referenced node is the first item of the list, the new node would become the new first object.

To assist you with this operation, the LinkedList class provides a method named AddBefore. This method is overloaded with two versions whose syntaxes are:

public void AddBefore(LinkedListNode<T> node, LinkedListNode<T> newNode);
public LinkedListNode<T> AddBefore(LinkedListNode<T> node, T value);

In both cases, you pass a first argument as an existing node. In the first case, you must pass the LinkedListNode object that will be inserted before the node. Here are two examples of calling thses methods:

<!DOCTYPE html>
<html>
<head>
<title>Numbers</title>
</head>
<body>
<h2>Numbers</h2>

@{
    List<double> values = new List<double>();
    values.Add(84.597);
    values.Add(6.47);
    values.Add(2747.06);
    values.Add(282.924);

    LinkedList<double> numbers = new LinkedList<double>(values);
    LinkedListNode<double> number = new LinkedListNode<double>(148.24);
    numbers.AddFirst(number);

    numbers.AddLast(18264.86);

    number = new LinkedListNode<double>(35.75);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(2222.06);
    numbers.AddFirst(number);

    LinkedListNode<double> last = new LinkedListNode<double>(827366.993);
    numbers.AddLast(last);

    number = new LinkedListNode<double>(4.19);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(66.18);
    numbers.AddFirst(number);

    LinkedListNode<double> reference = numbers.Find(148.24);
    numbers.AddBefore(reference, 9999.9999);

    LinkedListNode<double> other = numbers.Find(6.47);
    LinkedListNode<double> before = new LinkedListNode<double>(7777.7777);
    numbers.AddBefore(other, before);
}

<ul>
    @foreach (double nbr in numbers)
    {
        if( (nbr == 7777.7777) || (nbr == 9999.9999) )
        {
            <li style="color: tomato">Number: @nbr</li>
        }
        else if ((nbr == 6.47) || (nbr == 148.24))
        {
            <li style="color: blue">Number: @nbr</li>
        }
        else
        {
            <li>Number: @nbr</li>
        }    
    }
</ul>
</body>
</html>

This would produce:

Linked List

In the second version, you directly pass the value to be positioned before node.

Practical LearningPractical Learning: Inserting a Node Before a Referenced One

  1. In the Solution Explorer, under Controllers, click TrafficViolationsController.cs
  2. In the class, create two methods named Create as follows:
    using System.IO;
    using System.Web.Mvc;
    using System.Collections.Generic;
    using TrafficTicketsSystem1.Models;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace TrafficTicketsSystem1.Controllers
    {
        public class TrafficViolationsController : Controller
        {
            . . . No Change
    
            // GET: TrafficViolations/Create
            public ActionResult Create()
            {
                Random rndNumber = new Random();
                BinaryFormatter bfCameras = new BinaryFormatter();
                FileStream fsCameras = null, fsViolationsTypes = null;
                LinkedList<Camera> cameras = new LinkedList<Camera>();
                BinaryFormatter bfViolationsTypes = new BinaryFormatter();
                string strCamerasFile = Server.MapPath("~/App_Data/Cameras.tts");
                LinkedList<ViolationType> violationsTypes = new LinkedList<ViolationType>();
                string strViolationsTypesFile = Server.MapPath("~/App_Data/ViolationsTypes.tts");
    
                List<SelectListItem> itemsCameras = new List<SelectListItem>();
                List<SelectListItem> paymentsStatus = new List<SelectListItem>();
                List<SelectListItem> itemsPhotoAvailable = new List<SelectListItem>();
                List<SelectListItem> itemsVideoAvailable = new List<SelectListItem>();
                List<SelectListItem> itemsViolationsTypes = new List<SelectListItem>();
    
                if (System.IO.File.Exists(strCamerasFile))
                {
                    using (fsCameras = new FileStream(strCamerasFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        cameras = (LinkedList<Camera>)bfCameras.Deserialize(fsCameras);
    
                        foreach (Camera cmr in cameras)
                        {
                            itemsCameras.Add(new SelectListItem() { Text = cmr.CameraNumber + " - " + cmr.Location, Value = cmr.CameraNumber });
                        }
                    }
                }
    
                if (System.IO.File.Exists(strViolationsTypesFile))
                {
                    using (fsViolationsTypes = new FileStream(strViolationsTypesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        violationsTypes = (LinkedList<ViolationType>)bfViolationsTypes.Deserialize(fsViolationsTypes);
    
                        foreach (ViolationType vt in violationsTypes)
                        {
                            itemsViolationsTypes.Add(new SelectListItem() { Text = vt.ViolationName, Value = vt.ViolationName });
                        }
                    }
                }
    
                itemsPhotoAvailable.Add(new SelectListItem() { Value = "Unknown" });
                itemsPhotoAvailable.Add(new SelectListItem() { Text = "No", Value = "No" });
                itemsPhotoAvailable.Add(new SelectListItem() { Text = "Yes", Value = "Yes" });
                itemsVideoAvailable.Add(new SelectListItem() { Value = "Unknown" });
                itemsVideoAvailable.Add(new SelectListItem() { Text = "No", Value = "No" });
                itemsVideoAvailable.Add(new SelectListItem() { Text = "Yes", Value = "Yes" });
    
                paymentsStatus.Add(new SelectListItem() { Value = "Unknown" });
                paymentsStatus.Add(new SelectListItem() { Text = "Pending", Value = "Pending" });
                paymentsStatus.Add(new SelectListItem() { Text = "Rejected", Value = "Rejected" });
                paymentsStatus.Add(new SelectListItem() { Text = "Cancelled", Value = "Cancelled" });
                paymentsStatus.Add(new SelectListItem() { Text = "Paid Late", Value = "Paid Late" });
                paymentsStatus.Add(new SelectListItem() { Text = "Paid On Time", Value = "Paid On Time" });
    
                ViewBag.CameraNumber = itemsCameras;
                ViewBag.PaymentStatus = paymentsStatus;
                ViewBag.PhotoAvailable = itemsPhotoAvailable;
                ViewBag.VideoAvailable = itemsVideoAvailable;
                ViewBag.ViolationName = itemsViolationsTypes;
                ViewBag.TrafficViolationNumber = rndNumber.Next(10000001, 99999999);
    
                return View();
            }
    
            // POST: TrafficViolations/Create
            [HttpPost]
            public ActionResult Create(FormCollection collection)
            {
                try
                {
                    bool vehicleFound = false;
                    BinaryFormatter bfDrivers = new BinaryFormatter();
                    FileStream fsTrafficViolations = null, fsVehicles = null;
                    LinkedList<Vehicle> vehicles = new LinkedList<Vehicle>();
                    BinaryFormatter bfTrafficViolations = new BinaryFormatter();
                    string strVehiclesFile = Server.MapPath("~/App_Data/Vehicles.tts");
                    LinkedList<TrafficViolation> trafficViolations = new LinkedList<TrafficViolation>();
                    string strTrafficViolationsFile = Server.MapPath("~/App_Data/TrafficViolations.tts");
    
                    // Open the file for the vehicles
                    if (System.IO.File.Exists(strVehiclesFile))
                    {
                        using (fsVehicles = new FileStream(strVehiclesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            /* After opening the file, get the list of vehicles from it
                             * and store it in the LinkedList<Vehicle> variable. */
                            vehicles = (LinkedList<Vehicle>)bfDrivers.Deserialize(fsVehicles);
    
                            // Check each record
                            foreach (Vehicle car in vehicles)
                            {
                                /* When you get to a record, find out if its TagNumber value 
                                 * is the same as the tag number the user provided. */
                                if (car.TagNumber == collection["TagNumber"])
                                {
                                    /* If you find a record with that tag number, make a note. */
                                    vehicleFound = true;
                                    break;
                                }
                            }
                        }
                    }
    
                    /* If the vehicleFound is true, it means the car that committed the infraction has been identified. */
                    if (vehicleFound == true)
                    {
                        // Check whether a file for traffic violations was created already.
                        if (System.IO.File.Exists(strTrafficViolationsFile))
                        {
                            // If a file for traffic violations exists already, open it ...
                            using (fsTrafficViolations = new FileStream(strTrafficViolationsFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                // ... and store the records in our trafficViolations variable
                                trafficViolations = (LinkedList<TrafficViolation>)bfTrafficViolations.Deserialize(fsTrafficViolations);
                            }
                        }
    
                        TrafficViolation tv = new TrafficViolation()
                        {
                            TrafficViolationNumber = int.Parse(collection["TrafficViolationNumber"]),
                            CameraNumber = collection["CameraNumber"].Substring(0, 9),
                            TagNumber = collection["TagNumber"],
                            ViolationName = collection["ViolationName"],
                            ViolationDate = collection["ViolationDate"],
                            ViolationTime = collection["ViolationTime"],
                            PhotoAvailable = collection["PhotoAvailable"],
                            VideoAvailable = collection["VideoAvailable"],
                            PaymentDueDate = collection["PaymentDueDate"],
                            PaymentDate = collection["PaymentDate"],
                            PaymentAmount = double.Parse(collection["PaymentAmount"]),
                            PaymentStatus = collection["PaymentStatus"]
                        };
    
                        // If a list of traffic violations exists already, get the last one 
                        LinkedListNode<TrafficViolation> node = trafficViolations.Last;
    
                        if (node == null)
                        {
                            trafficViolations.AddFirst(tv);
                        }
                        else
                        {
                            // If the file contains a node already, add the new one before the last
                            trafficViolations.AddBefore(node, tv);
                        }
    
                        // After updating the list of traffic violations, save the file 
                        using (fsTrafficViolations = new FileStream(strTrafficViolationsFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                        {
                            bfTrafficViolations.Serialize(fsTrafficViolations, trafficViolations);
                        }
                    }
    
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
        }
    }
  3. In the class, right-click one of the Create() methods and click Add View...
  4. Make sure the View Name displays Create.
    Click Add
  5. Create a form as follows:
    @model TrafficTicketsSystem1.Models.TrafficViolation
    
    @{
        ViewBag.Title = "Create Traffic Violation";
    }
    
    <h2 class="common-font text-center bold maroon">Traffic Violation Issuance</h2>
    
    <hr />
    
    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()
    
        <div class="containment">
            <div class="form-horizontal common-font">
                @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                <div class="form-group">
                    @Html.LabelFor(model => model.TrafficViolationNumber, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.TextBox("TrafficViolationNumber", @ViewBag.TrafficViolationNumber as string, htmlAttributes: new { @class = "form-control" })
                        @Html.ValidationMessageFor(model => model.TrafficViolationNumber, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    @Html.LabelFor(model => model.CameraNumber, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.DropDownList("CameraNumber", ViewBag.CamerasNumbers as SelectList, htmlAttributes: new { @class = "form-control" })
                        @Html.ValidationMessageFor(model => model.CameraNumber, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    @Html.LabelFor(model => model.TagNumber, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.EditorFor(model => model.TagNumber, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.TagNumber, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    @Html.LabelFor(model => model.ViolationName, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.DropDownList("ViolationName", ViewBag.ViolationName as SelectList, htmlAttributes: new { @class = "form-control" })
                        @Html.ValidationMessageFor(model => model.ViolationName, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    @Html.LabelFor(model => model.ViolationDate, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.TextBox("ViolationDate", null, htmlAttributes: new { @class = "form-control", type = "Date" })
                        @Html.ValidationMessageFor(model => model.ViolationDate, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    @Html.LabelFor(model => model.ViolationTime, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.EditorFor(model => model.ViolationTime, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.ViolationTime, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    @Html.LabelFor(model => model.PhotoAvailable, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.DropDownList("PhotoAvailable", ViewBag.PhotoAvailable as SelectList, htmlAttributes: new { @class = "form-control" })
                        @Html.ValidationMessageFor(model => model.PhotoAvailable, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    @Html.LabelFor(model => model.VideoAvailable, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.DropDownList("VideoAvailable", ViewBag.PhotoAvailable as SelectList, htmlAttributes: new { @class = "form-control" })
                        @Html.ValidationMessageFor(model => model.VideoAvailable, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    @Html.LabelFor(model => model.PaymentDueDate, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.TextBox("PaymentDueDate", null, htmlAttributes: new { @class = "form-control", type = "Date" })
                        @Html.ValidationMessageFor(model => model.PaymentDueDate, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    @Html.LabelFor(model => model.PaymentDate, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.EditorFor(model => model.PaymentDate, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.PaymentDate, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    @Html.LabelFor(model => model.PaymentAmount, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.EditorFor(model => model.PaymentAmount, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.PaymentAmount, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    @Html.LabelFor(model => model.PaymentStatus, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.DropDownList("PaymentStatus", ViewBag.PaymentStatus as SelectList, htmlAttributes: new { @class = "form-control" })
                        @Html.ValidationMessageFor(model => model.PaymentStatus, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    <label class="col-md-6"></label>
                    <div class="col-md-6">
                        <input type="submit" value="Save this Traffic Violation Record" class="btn btn-warning" />
                    </div>
                </div>
            </div>
        </div>
    }
    <hr />
    <p class="text-center">
        @Html.ActionLink("Traffic Violations", "Index") ::
        @Html.ActionLink("Review a Traffic Violation", "Details") ::
        @Html.ActionLink("Edit/Update a Traffic Violation", "PrepareEdit") ::
        @Html.ActionLink("Delete/Remove a Traffic Violation", "PrepareDelete") ::
        @Html.ActionLink("Prepare/Review a Citation", "Citation")</p>

Inserting a Node After a Referenced One

Instead of inserting a node before an existing one, you can add it after one. The approach is logically the same as inserting a node before another, except that the sequence is reversed. First identify the node that will be used as reference. Start by adding the new node after that one. Behind the scenes, the referenced node will point to the new node as its next and the new node will point to the existing node as its previous:

Inserting a New node After an Existing Node

After the new node has been added, it will point to the node after it as its next. The other node will point to the new node as its previous:

Inserting a New node After an Existing Node

If the new node is added after the last node, the new node will become the new last node.

To let you insert a node after an existing node, the LinkedList class is equipped with a method named AddAfter. It comes in two versions and their syntaxes are:

public void AddAfter(LinkedListNode<T> node, LinkedListNode<T> newNode);
public LinkedListNode<T> AddAfter(LinkedListNode<T> node, T value);

The arguments follow the same description as the AddBefore() method, only in reverse. Here is an example:

<!DOCTYPE html>
<html>
<head>
<title>Numbers</title>
</head>
<body>
<h2>Numbers</h2>

@{
    List<double> values = new List<double>();
    values.Add(84.597);
    values.Add(6.47);
    values.Add(2747.06);
    values.Add(282.924);

    LinkedList<double> numbers = new LinkedList<double>(values);
    LinkedListNode<double> number = new LinkedListNode<double>(148.24);
    numbers.AddFirst(number);

    numbers.AddLast(18264.86);

    number = new LinkedListNode<double>(35.75);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(2222.06);
    numbers.AddFirst(number);

    LinkedListNode<double> last = new LinkedListNode<double>(827366.993);
    numbers.AddLast(last);

    number = new LinkedListNode<double>(4.19);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(66.18);
    numbers.AddFirst(number);

    LinkedListNode<double> reference = numbers.Find(148.24);
    numbers.AddAfter(reference, 9999.9999);

    LinkedListNode<double> other = numbers.Find(6.47);
    LinkedListNode<double> before = new LinkedListNode<double>(7777.7777);
    numbers.AddAfter(other, before);
}

<ul>
    @foreach (double nbr in numbers)
    {
        if ((nbr == 7777.7777) || (nbr == 9999.9999))
        {
            <li style="color: tomato">Number: @nbr</li>
        }
        else if ((nbr == 6.47) || (nbr == 148.24))
        {
            <li style="color: blue">Number: @nbr</li>
        }
        else
        {
            <li>Number: @nbr</li>
        }
    }
</ul>
</body>
</html>

This would produce:

Linked List

Practical LearningPractical Learning: Inserting a Node After a Referenced One

  1. In the Solution Explorer, under Controllers, click DriversController.cs to access it
  2. In the DriversController class, add two Create() methods as follows:
    using System.IO;
    using System.Web.Mvc;
    using System.Collections.Generic;
    using TrafficTicketsSystem1.Models;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace TrafficTicketsSystem1.Controllers
    {
        public class DriversController : Controller
        {
            . . . No Change
    
            // GET: Drivers/Create
            public ActionResult Create()
            {
                return View();
            }
    
            // POST: Drivers/Create
            [HttpPost]
            public ActionResult Create(FormCollection collection)
            {
                try
                {
                    Driver drv = new Driver();
                    FileStream fsDrivers = null;
                    BinaryFormatter bfDrivers = new BinaryFormatter();
                    LinkedList<Driver> drivers = new LinkedList<Driver>();
                    string strDriversFile = Server.MapPath("~/App_Data/Drivers.tts");
    
                    // Make sure the user provides both the driver's license number and a state
                    if ((!string.IsNullOrEmpty("DrvLicNumber")) && (!string.IsNullOrEmpty("State")))
                    {
                        // Assuming the user provided a State value, make that
                        // Find out whether a file for drivers was created already
                        if (System.IO.File.Exists(strDriversFile))
                        {
                            // If that file exists, open it...
                            using (fsDrivers = new FileStream(strDriversFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                // ... and store the records in the LinkedList<Driver> variable
                                drivers = (LinkedList<Driver>)bfDrivers.Deserialize(fsDrivers);
    
                                // Check all the drivers records
                                foreach (Driver d in drivers)
                                {
                                    // When you get to a record, if its State is the same the user enter, make it the reference node
                                    if (d.State.Equals(collection["State"]))
                                    {
                                        drv = d;
                                    }
                                }
                            }
                        }
    
                        LinkedListNode<Driver> referenceNode = drivers.Find(drv);
    
                        // Prepare a driver's record to save
                        Driver person = new Driver()
                        {
                            DrvLicNumber = collection["DrvLicNumber"],
                            FirstName = collection["FirstName"],
                            LastName = collection["LastName"],
                            Address = collection["Address"],
                            City = collection["City"],
                            County = collection["County"],
                            State = collection["State"],
                            ZIPCode = collection["ZIPCode"],
                        };
    
                        // If there is no driver yet, then simply add the new driver as the last record
                        if (referenceNode == null)
                        {
                            drivers.AddLast(person);
                        }
                        else // if( referenceNode != null)
                        {
                            drivers.AddAfter(referenceNode, person);
                        }
    
                        using (fsDrivers = new FileStream(strDriversFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                        {
                            bfDrivers.Serialize(fsDrivers, drivers);
                        }
                    }
    
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
        }
    }
  3. In the class, right-click one of the Create() methods -> Add View...
  4. Make sure the View Name is displaying Create.
    Click Add
  5. Create a form as follows:
    @model TrafficTicketsSystem1.Models.Driver
    
    @{
        ViewBag.Title = "Create Driver";
    }
    
    <h2 class="common-font maroon text-center bold">Driver's License Issuance</h2>
    
    <hr />
    
    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()
    
        <div class="containment">
            <div class="form-horizontal common-font">
                @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                <div class="form-group">
                    @Html.LabelFor(model => model.DrvLicNumber, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.EditorFor(model => model.DrvLicNumber, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.DrvLicNumber, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    @Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.EditorFor(model => model.FirstName, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.FirstName, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    @Html.LabelFor(model => model.LastName, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.EditorFor(model => model.LastName, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.LastName, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    @Html.LabelFor(model => model.Address, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.EditorFor(model => model.Address, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.Address, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    @Html.LabelFor(model => model.City, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.EditorFor(model => model.City, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.City, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    @Html.LabelFor(model => model.County, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.EditorFor(model => model.County, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.County, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    @Html.LabelFor(model => model.State, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.EditorFor(model => model.State, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.State, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    @Html.LabelFor(model => model.ZIPCode, htmlAttributes: new { @class = "control-label col-md-5 maroon" })
                    <div class="col-md-7">
                        @Html.EditorFor(model => model.ZIPCode, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.ZIPCode, "", new { @class = "text-danger" })
                    </div>
                </div>
    
                <div class="form-group">
                    <label class="col-md-6"></label>
                    <div class="col-md-6">
                        <input type="submit" value="Save this Driver's Record" class="btn btn-warning" />
                    </div>
                </div>
            </div>
        </div>
    }
    
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Drivers - Vehicles Owners", "Index") ::
        @Html.ActionLink("Review a Driver's License", "Details") ::
        @Html.ActionLink("Edit/Update a Driver's License", "PrepareEdit") ::
        @Html.ActionLink("Suspend/Delete/Remove a Driver's License", "PrepareDelete")</p>

Deleting Nodes

Deleting the First Node

When it comes time to delete a node, you have many options, such as deleting the first or the last node of the list. To let you delete the first node, the LinkedList class provides the RemoveFirst() method. Its syntax is:

public void RemoveFirst();

As you can see, this method takes no argument. When it is called:

Here is an example:

<!DOCTYPE html>
<html>
<head>
<title>Numbers</title>
</head>
<body>
<h2>Numbers</h2>

@{
    List<double> values = new List<double>();
    values.Add(84.597);
    values.Add(6.47);
    values.Add(2747.06);
    values.Add(282.924);

    LinkedList<double> numbers = new LinkedList<double>(values);
    LinkedListNode<double> number = new LinkedListNode<double>(148.24);
    numbers.AddFirst(number);

    numbers.AddLast(18264.86);

    number = new LinkedListNode<double>(35.75);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(2222.06);
    numbers.AddFirst(number);

    LinkedListNode<double> last = new LinkedListNode<double>(827366.993);
    numbers.AddLast(last);

    number = new LinkedListNode<double>(4.19);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(66.18);
    numbers.AddFirst(number);

    LinkedListNode<double> reference = numbers.Find(148.24);
    numbers.AddBefore(reference, 9999.9999);

    LinkedListNode<double> other = numbers.Find(6.47);
    LinkedListNode<double> before = new LinkedListNode<double>(7777.7777);
    numbers.AddBefore(other, before);

    numbers.RemoveFirst();
}

<ul>
    @foreach (double nbr in numbers)
    {
        if ((nbr == 7777.7777) || (nbr == 9999.9999))
        {
            <li style="color: tomato">Number: @nbr</li>
        }
        else if ((nbr == 6.47) || (nbr == 148.24))
        {
            <li style="color: blue">Number: @nbr</li>
        }
        else
        {
            <li>Number: @nbr</li>
        }
    }
</ul>
</body>
</html>

This would produce:

Linked List - Removing the First Node

Deleting the Last Node

To delete the last node, you can call the RemoveLast() method whose syntax is:

public void RemoveLast();

This method follows the same logic as the RemoveFirst() method, only in reverse. Here are examples of calling these methods:

<!DOCTYPE html>
<html>
<head>
<title>Numbers</title>
</head>
<body>
<h2>Numbers</h2>

@{
    List<double> values = new List<double>();
    values.Add(84.597);
    values.Add(6.47);
    values.Add(2747.06);
    values.Add(282.924);

    LinkedList<double> numbers = new LinkedList<double>(values);
    LinkedListNode<double> number = new LinkedListNode<double>(148.24);
    numbers.AddFirst(number);

    numbers.AddLast(18264.86);

    number = new LinkedListNode<double>(35.75);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(2222.06);
    numbers.AddFirst(number);

    LinkedListNode<double> last = new LinkedListNode<double>(827366.993);
    numbers.AddLast(last);

    number = new LinkedListNode<double>(4.19);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(66.18);
    numbers.AddFirst(number);

    LinkedListNode<double> reference = numbers.Find(148.24);
    numbers.AddBefore(reference, 9999.9999);

    LinkedListNode<double> other = numbers.Find(6.47);
    LinkedListNode<double> before = new LinkedListNode<double>(7777.7777);
    numbers.AddBefore(other, before);

    numbers.RemoveLast();
}

<ul>
    @foreach (double nbr in numbers)
    {
        if ((nbr == 7777.7777) || (nbr == 9999.9999))
        {
            <li style="color: tomato">Number: @nbr</li>
        }
        else if ((nbr == 6.47) || (nbr == 148.24))
        {
            <li style="color: blue">Number: @nbr</li>
        }
        else
        {
            <li>Number: @nbr</li>
        }
    }
</ul>
</body>
</html>

This would produce:

Linked List

Removing (the First Instance of) a Node by Value

There are two ways you can delete an item inside the collection. This can be done using the Remove() method. It comes in two versions. If you know the value or object you want to remove, you can call the following version of that method:

public bool Remove(T value);

When calling this method, pass the value to delete. The compiler would first look for a node that has that value:

Here is an example:

<!DOCTYPE html>
<html>
<head>
<title>Numbers</title>
</head>
<body>
<h2>Numbers</h2>

@{
    List<double> values = new List<double>();
    values.Add(84.597);
    values.Add(6.47);
    values.Add(2747.06);
    values.Add(282.924);

    LinkedList<double> numbers = new LinkedList<double>(values);
    LinkedListNode<double> number = new LinkedListNode<double>(148.24);
    numbers.AddFirst(number);

    numbers.AddLast(18264.86);

    number = new LinkedListNode<double>(35.75);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(2222.06);
    numbers.AddFirst(number);

    LinkedListNode<double> last = new LinkedListNode<double>(827366.993);
    numbers.AddLast(last);

    number = new LinkedListNode<double>(4.19);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(66.18);
    numbers.AddFirst(number);

    LinkedListNode<double> reference = numbers.Find(148.24);
    numbers.AddBefore(reference, 9999.9999);

    LinkedListNode<double> other = numbers.Find(6.47);
    LinkedListNode<double> before = new LinkedListNode<double>(7777.7777);
    numbers.AddBefore(other, before);

    numbers.Remove(84.597);
}

<ul>
    @foreach (double nbr in numbers)
    {
        if ((nbr == 7777.7777) || (nbr == 9999.9999))
        {
            <li style="color: tomato">Number: @nbr</li>
        }
        else if ((nbr == 6.47) || (nbr == 148.24))
        {
            <li style="color: blue">Number: @nbr</li>
        }
        else
        {
            <li>Number: @nbr</li>
        }
    }
</ul>
</body>
</html>

This would produce:

Linked List Removing a Node by Value

Practical LearningPractical Learning: Removing a Node by Value

  1. In the Solution Explorer, under Controllers, double-click ViolationsTypes.cs to access it
  2. In the ViolationsTypes class, create four methods as follows:
    using System.IO;
    using System.Web.Mvc;
    using System.Collections.Generic;
    using TrafficTicketsSystem1.Models;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace TrafficTicketsSystem1.Controllers
    {
        public class ViolationsTypesController : Controller
        {
            // GET: ViolationsTypes
            public ActionResult Index()
            {
                FileStream fsViolationsTypes = null;
                BinaryFormatter bfViolationsTypes = new BinaryFormatter();
                string strViolationsTypesFile = Server.MapPath("~/App_Data/ViolationsTypes.tts");
                LinkedList<ViolationType> categories = new LinkedList<ViolationType>();
    
                // If a file for violations types was proviously created, open it
                if (System.IO.File.Exists(strViolationsTypesFile))
                {
                    using (fsViolationsTypes = new FileStream(strViolationsTypesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        /* After opening the file, get the list of records from it
                         * and store in the declared LinkedList<> variable. */
                        categories = (LinkedList<ViolationType>)bfViolationsTypes.Deserialize(fsViolationsTypes);
                    }
                }
    
                return View(categories);
            }
    
            // GET: ViolationsTypes/Create
            public ActionResult Create()
            {
                return View();
            }
    
            // POST: ViolationsTypes/Create
            [HttpPost]
            public ActionResult Create(FormCollection collection)
            {
                try
                {
                    FileStream fsViolationsTypes = null;
                    LinkedList<ViolationType> categories = new LinkedList<ViolationType>();
                    BinaryFormatter bfViolationsTypes = new BinaryFormatter();
                    string strViolationsTypesFile = Server.MapPath("~/App_Data/ViolationsTypes.tts");
    
                    if (!string.IsNullOrEmpty("DrvLicNumber"))
                    {
                        if (System.IO.File.Exists(strViolationsTypesFile))
                        {
                            using (fsViolationsTypes = new FileStream(strViolationsTypesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                categories = (LinkedList<ViolationType>)bfViolationsTypes.Deserialize(fsViolationsTypes);
                            }
                        }
    
                        ViolationType vt = new ViolationType()
                        {
                            ViolationName = collection["ViolationName"],
                            Description = collection["Description"],
                        };
    
                        categories.AddLast(vt);
    
                        using (fsViolationsTypes = new FileStream(strViolationsTypesFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                        {
                            bfViolationsTypes.Serialize(fsViolationsTypes, categories);
                        }
                    }
    
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
    
            // GET: ViolationsTypes/Details/
            public ActionResult Details()
            {
                return View();
            }
    
            // GET: ViolationsTypes/PrepareEdit/
            public ActionResult PrepareEdit()
            {
                return View();
            }
    
            // GET: ViolationsTypes/ConfirmEdit/
            public ActionResult ConfirmEdit(FormCollection collection)
            {
                if (!string.IsNullOrEmpty(collection["ViolationName"]))
                {
                    FileStream fsViolationsTypes = null;
                    ViolationType violationType = new ViolationType();
                    BinaryFormatter bfViolationsTypes = new BinaryFormatter();
                    LinkedList<ViolationType> violationsTypes = new LinkedList<ViolationType>();
                    string strViolationsTypesFile = Server.MapPath("~/App_Data/ViolationsTypes.tts");
    
                    if (System.IO.File.Exists(strViolationsTypesFile))
                    {
                        using (fsViolationsTypes = new FileStream(strViolationsTypesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            violationsTypes = (LinkedList<ViolationType>)bfViolationsTypes.Deserialize(fsViolationsTypes);
                        }
    
                        violationType.ViolationName = collection["ViolationName"];
    
                        LinkedListNode<ViolationType> vt = violationsTypes.Find(violationType);
    
                        ViewBag.ViolationName = collection["ViolationName"];
                        ViewBag.Description = vt.Value.Description;
                    }
                }
    
                return View();
            }
    
            // GET: ViolationsTypes/Edit/
            public ActionResult Edit()
            {
                return View();
            }
    
            // POST: ViolationsTypes/Edit/
            [HttpPost]
            public ActionResult Edit(FormCollection collection)
            {
                try
                {
                    FileStream fsViolationsTypes = null;
                    ViolationType violationType = new ViolationType();
                    BinaryFormatter bfViolationsTypes = new BinaryFormatter();
                    LinkedList<ViolationType> ViolationsTypes = new LinkedList<ViolationType>();
                    string strViolationsTypesFile = Server.MapPath("~/App_Data/ViolationsTypes.tts");
    
                    if (!string.IsNullOrEmpty("ViolationName"))
                    {
                        if (System.IO.File.Exists(strViolationsTypesFile))
                        {
                            using (fsViolationsTypes = new FileStream(strViolationsTypesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                ViolationsTypes = (LinkedList<ViolationType>)bfViolationsTypes.Deserialize(fsViolationsTypes);
                            }
                        }
    
                        violationType.ViolationName = collection["ViolationName"];
    
                        LinkedListNode<ViolationType> vt = ViolationsTypes.Find(violationType);
    
                        vt.Value.Description = collection["Description"];
    
                        using (fsViolationsTypes = new FileStream(strViolationsTypesFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                        {
                            bfViolationsTypes.Serialize(fsViolationsTypes, ViolationsTypes);
                        }
                    }
    
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
    
            // GET: ViolationsTypes/PrepareDelete/
            public ActionResult PrepareDelete()
            {
                return View();
            }
    
            // GET: ViolationsTypes/ConfirmDelete/
            public ActionResult ConfirmDelete(FormCollection collection)
            {
                if (!string.IsNullOrEmpty(collection["ViolationName"]))
                {
                    FileStream fsViolationsTypes = null;
                    ViolationType violationType = new ViolationType();
                    BinaryFormatter bfViolationsTypes = new BinaryFormatter();
                    LinkedList<ViolationType> violationsTypes = new LinkedList<ViolationType>();
                    string strViolationsTypesFile = Server.MapPath("~/App_Data/ViolationsTypes.tts");
    
                    if (System.IO.File.Exists(strViolationsTypesFile))
                    {
                        using (fsViolationsTypes = new FileStream(strViolationsTypesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            violationsTypes = (LinkedList<ViolationType>)bfViolationsTypes.Deserialize(fsViolationsTypes);
                        }
    
                        violationType.ViolationName = collection["ViolationName"];
    
                        LinkedListNode<ViolationType> vt = violationsTypes.Find(violationType);
    
                        ViewBag.ViolationName = collection["ViolationName"];
                        ViewBag.Description = vt.Value.Description;
                    }
                }
    
                return View();
            }
    
            // GET: ViolationsTypes/Delete/
            public ActionResult Delete()
            {
                return View();
            }
    
            // POST: ViolationsTypes/Delete/
            [HttpPost]
            public ActionResult Delete(FormCollection collection)
            {
                try
                {
                    FileStream fsViolationsTypes = null;
                    BinaryFormatter bfViolationsTypes = new BinaryFormatter();
                    LinkedList<ViolationType> violationsTypes = new LinkedList<ViolationType>();
                    string strViolationsTypesFile = Server.MapPath("~/App_Data/ViolationsTypes.tts");
    
                    if (!string.IsNullOrEmpty("ViolationName"))
                    {
                        if (System.IO.File.Exists(strViolationsTypesFile))
                        {
                            using (fsViolationsTypes = new FileStream(strViolationsTypesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                violationsTypes = (LinkedList<ViolationType>)bfViolationsTypes.Deserialize(fsViolationsTypes);
                            }
                        }
    
                        if (violationsTypes.Count > 0)
                        {
                            ViolationType violationType = new ViolationType();
    
                            violationType.ViolationName = collection["ViolationName"];
                            violationsTypes.Remove(violationType);
    
                            using (fsViolationsTypes = new FileStream(strViolationsTypesFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                            {
                                bfViolationsTypes.Serialize(fsViolationsTypes, violationsTypes);
                            }
                        }
                    }
    
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
        }
    }
  3. In the ViolationsTypes class, right-click PrepareDelete() -> Add View...
  4. Make sure the View Name text box is displaying PrepareDelete.
    Click Add
  5. Create a form as follows:
    @model TrafficTicketsSystem1.Models.ViolationType
    
    @{
        ViewBag.Title = "Prepare Violation Type Delete";
    }
    
    <h2 class="maroon common-font text-center bold">Deleting Violation Type</h2>
    
    <hr />
    
    @using (Html.BeginForm("ConfirmDeletion", "ViolationsTypes", FormMethod.Post))
    {
        @Html.AntiForgeryToken()
    
        <div class="large-content">
            <div class="form-horizontal common-font">
                @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                <div class="form-group">
                    @Html.LabelFor(model => model.ViolationName, htmlAttributes: new { @class = "control-label col-md-4 maroon" })
                    <div class="col-md-4">
                        @Html.EditorFor(model => model.ViolationName, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.ViolationName, "", new { @class = "text-danger" })
                    </div>
                    <div class="col-md-4">
                        <p><input type="submit" value="Find Violation Type" class="btn btn-warning" /></p>
                    </div>
                </div>
            </div>
        </div>
    }
    
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Violations Types", "Index") ::
        @Html.ActionLink("Create New Violation Type", "Create") ::
        @Html.ActionLink("Review a Violation Type", "Details") ::
        @Html.ActionLink("Edit/Update Violation Type Definition", "PrepareEdit")</p>
  6. In the Solution Explorer, under Views, right-click ViolationsTypes -> Add -> View...
  7. Type ConfirmDelete as the View Name
  8. Click OK
  9. Create a form as follows:
    @{
        ViewBag.Title = "Confirm Camera Delete";
    }
    
    <h2 class="maroon common-font text-center bold">Confirm Camera Deletion</h2>
    
    <hr />
    
    @using (Html.BeginForm("Delete", "V", FormMethod.Post))
    {
        <div class="containment common-font">
            <table>
                <tr>
                    <td class="small-text bold maroon">Camera #</td>
                    <td>@Html.TextBox("CameraNumber", @ViewBag.CameraNumber as string, htmlAttributes: new { @class = "form-control" })</td>
                </tr>
                <tr>
                    <td></td>
                    <td></td>
                </tr>
                <tr>
                    <td class="maroon bold">Make</td>
                    <td>@Html.TextBox("Make", @ViewBag.Make as string, htmlAttributes: new { @class = "form-control", disabled = "disabled" })</td>
                </tr>
                <tr>
                    <td></td>
                    <td></td>
                </tr>
                <tr>
                    <td class="maroon bold">Model</td>
                    <td>@Html.TextBox("Model", @ViewBag.Model as string, htmlAttributes: new { @class = "form-control", disabled = "disabled" })</td>
                </tr>
                <tr>
                    <td></td>
                    <td></td>
                </tr>
                <tr>
                    <td class="maroon bold">Location</td>
                    <td>@Html.TextBox("Location", @ViewBag.Location as string, htmlAttributes: new { @class = "form-control large-text", disabled = "disabled" })</td>
                </tr>
            </table>
        </div>
    
        <hr />
    
        <p class="text-center"><input type="submit" value="Delete this Camera's Record" class="btn btn-warning" /></p>
        <div class="form-group">
            <label class="col-md-6 control-label"></label>
            <div class="col-md-6"></div>
        </div>
    }
    
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Cameras", "Index") ::
        @Html.ActionLink("Create New Camera", "Create") ::
        @Html.ActionLink("Review Camera Details", "Details") ::
        @Html.ActionLink("Edit/Update Camera Details", "PrepareEdit")</p>
  10. In the Solution Explorer, under Controllers, double-click CamerasController.cs to access it
  11. In the CamerasController class, create four methods as follows:
    using System.IO;
    using System.Web.Mvc;
    using System.Collections.Generic;
    using TrafficTicketsSystem1.Models;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace TrafficTicketsSystem1.Controllers
    {
        public class CamerasController : Controller
        {
            // GET: Cameras
            public ActionResult Index()
            {
                FileStream fsCameras = null;
                BinaryFormatter bfCameras = new BinaryFormatter();
                LinkedList<Camera> cameras = new LinkedList<Camera>();
                string strCamerasFile = Server.MapPath("~/App_Data/Cameras.tts");
    
                // If a file for Cameras records was proviously created, open it
                if (System.IO.File.Exists(strCamerasFile))
                {
                    using (fsCameras = new FileStream(strCamerasFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        /* After opening the file, get the list of records from it
                         * and store in the declared LinkedList<> variable. */
                        cameras = (LinkedList<Camera>)bfCameras.Deserialize(fsCameras);
                    }
                }
    
                return View(cameras);
            }
    
            // GET: Cameras/Details/
            public ActionResult Details()
            {
                return View();
            }
    
            // GET: Cameras/PrepareEdit/
            public ActionResult PrepareEdit()
            {
                return View();
            }
    
            // GET: Cameras/ConfirmEdit/
            public ActionResult ConfirmEdit(FormCollection collection)
            {
                if (!string.IsNullOrEmpty(collection["CameraNumber"]))
                {
                    FileStream         fsCameras      = null;
                    Camera             camera         = new Camera();
                    BinaryFormatter    bfCameras      = new BinaryFormatter();
                    LinkedList<Camera> cameras        = new LinkedList<Camera>();
                    string             strCamerasFile = Server.MapPath("~/App_Data/Cameras.tts");
    
                    if (System.IO.File.Exists(strCamerasFile))
                    {
                        using (fsCameras = new FileStream(strCamerasFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            cameras = (LinkedList<Camera>)bfCameras.Deserialize(fsCameras);
                        }
    
                        camera.CameraNumber = collection["CameraNumber"];
    
                        LinkedListNode<Camera> viewer = cameras.FindLast(camera);
    
                        ViewBag.CameraNumber = collection["CameraNumber"];
                        ViewBag.Make = viewer.Value.Make;
                        ViewBag.Model = viewer.Value.Model;
                        ViewBag.Location = viewer.Value.Location;
                    }
                }
    
                return View();
            }
    
            // GET: Cameras/Edit/
            public ActionResult Edit()
            {
                return View();
            }
    
            // POST: Cameras/Edit/
            [HttpPost]
            public ActionResult Edit(FormCollection collection)
            {
                try
                {
                    FileStream fsCameras = null;
                    Camera camera = new Camera();
                    BinaryFormatter bfCameras = new BinaryFormatter();
                    LinkedList<Camera> cameras = new LinkedList<Camera>();
                    string strCamerasFile = Server.MapPath("~/App_Data/Cameras.tts");
    
                    if (!string.IsNullOrEmpty("CameraNumber"))
                    {
                        if (System.IO.File.Exists(strCamerasFile))
                        {
                            using (fsCameras = new FileStream(strCamerasFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                cameras = (LinkedList<Camera>)bfCameras.Deserialize(fsCameras);
                            }
                        }
    
                        camera.CameraNumber = collection["CameraNumber"];
    
                        LinkedListNode<Camera> viewer = cameras.FindLast(camera);
    
                        viewer.Value.Make = collection["Make"];
                        viewer.Value.Model = collection["Model"];
                        viewer.Value.Location = collection["Location"];
    
                        using (fsCameras = new FileStream(strCamerasFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                        {
                            bfCameras.Serialize(fsCameras, cameras);
                        }
                    }
    
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
    
            // GET: Cameras/Create
            public ActionResult Create()
            {
                return View();
            }
    
            // POST: Cameras/Create
            [HttpPost]
            public ActionResult Create(FormCollection collection)
            {
                try
                {
                    FileStream fsCameras = null;
                    BinaryFormatter bfCameras = new BinaryFormatter();
                    LinkedList<Camera> cameras = new LinkedList<Camera>();
                    string strCamerasFile = Server.MapPath("~/App_Data/Cameras.tts");
    
                    if (!string.IsNullOrEmpty("CameraNumber"))
                    {
                        if (System.IO.File.Exists(strCamerasFile))
                        {
                            using (fsCameras = new FileStream(strCamerasFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                cameras = (LinkedList<Camera>)bfCameras.Deserialize(fsCameras);
                            }
                        }
    
                        Camera viewer = new Camera()
                        {
                            CameraNumber = collection["CameraNumber"],
                            Make = collection["Make"],
                            Model = collection["Model"],
                            Location = collection["Location"]
                        };
    
                        cameras.AddFirst(viewer);
    
                        using (fsCameras = new FileStream(strCamerasFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                        {
                            bfCameras.Serialize(fsCameras, cameras);
                        }
                    }
    
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
    
            // GET: Cameras/PrepareDelete/
            public ActionResult PrepareDelete()
            {
                return View();
            }
    
            // GET: Cameras/ConfirmDelete/
            public ActionResult ConfirmDelete(FormCollection collection)
            {
                if (!string.IsNullOrEmpty(collection["CameraNumber"]))
                {
                    FileStream fsCameras = null;
                    Camera camera = new Camera();
                    BinaryFormatter bfCameras = new BinaryFormatter();
                    LinkedList<Camera> cameras = new LinkedList<Camera>();
                    string strCamerasFile = Server.MapPath("~/App_Data/Cameras.tts");
    
                    if (System.IO.File.Exists(strCamerasFile))
                    {
                        using (fsCameras = new FileStream(strCamerasFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            cameras = (LinkedList<Camera>)bfCameras.Deserialize(fsCameras);
                        }
    
                        camera.CameraNumber = collection["CameraNumber"];
    
                        LinkedListNode<Camera> viewer = cameras.FindLast(camera);
    
                        ViewBag.CameraNumber = collection["CameraNumber"];
                        ViewBag.Make = viewer.Value.Make;
                        ViewBag.Model = viewer.Value.Model;
                        ViewBag.Location = viewer.Value.Location;
                    }
                }
    
                return View();
            }
    
            // GET: Cameras/Delete/
            public ActionResult Delete()
            {
                return View();
            }
    
            // POST: Cameras/Delete/
            [HttpPost]
            public ActionResult Delete(FormCollection collection)
            {
                try
                {
                    FileStream fsCameras = null;
                    BinaryFormatter bfCameras = new BinaryFormatter();
                    LinkedList<Camera> cameras = new LinkedList<Camera>();
                    string strCamerasFile = Server.MapPath("~/App_Data/Cameras.tts");
    
                    if (!string.IsNullOrEmpty("CameraNumber"))
                    {
                        if (System.IO.File.Exists(strCamerasFile))
                        {
                            using (fsCameras = new FileStream(strCamerasFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                cameras = (LinkedList<Camera>)bfCameras.Deserialize(fsCameras);
                            }
                        }
    
                        // If a file for cameras exists, ...
                        if (cameras.Count > 0)
                        {
                            // ... create a Camera object ...
                            Camera camera = new Camera();
                            /* ... that is equivalent to the Camera that uses the 
                             * camera number that the user typed in the form */
                            camera.CameraNumber = collection["CameraNumber"];
    
                            // Now that you have identified that camera, delete it
                            cameras.Remove(camera);
    
                            // After updating the list of cameras, save the file
                            using (fsCameras = new FileStream(strCamerasFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                            {
                                bfCameras.Serialize(fsCameras, cameras);
                            }
                        }
                    }
    
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
        }
    }
  12. In the CamerasController class, right-click PrepareDelete() -> Add View...
  13. Make sure the View Name text box is displaying PrepareDelete.
    Click Add
  14. Create a form as follows:
    @model TrafficTicketsSystem1.Models.Camera
    
    @{
        ViewBag.Title = "Prepare Camera Deletion";
    }
    
    <h2 class="maroon common-font text-center bold">Prepare Camera Deletion</h2>
    
    <hr />
    
    @using (Html.BeginForm("ConfirmDeletion", "Cameras", FormMethod.Post))
    {
        @Html.AntiForgeryToken()
    
        <div class="large-content">
            <div class="form-horizontal common-font">
                @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                <div class="form-group">
                    @Html.LabelFor(model => model.CameraNumber, htmlAttributes: new { @class = "control-label col-md-4 maroon" })
                    <div class="col-md-4">
                        @Html.EditorFor(model => model.CameraNumber, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.CameraNumber, "", new { @class = "text-danger" })
                    </div>
                    <div class="col-md-4">
                        <p><input type="submit" value="Find Camera" class="btn btn-warning small-text" /></p>
                    </div>
                </div>
            </div>
        </div>
    }
    
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Cameras", "Index") ::
        @Html.ActionLink("Create New Camera", "Create") ::
        @Html.ActionLink("Review Camera Details", "Details") ::
        @Html.ActionLink("Edit/Update Camera Details", "PrepareEdit")</p>
  15. In the Solution Explorer, under Views, right-click Cameras -> Add -> View...
  16. Type ConfirmDelete as the name of the view.
    Press Enter
  17. Change the document as follows:
    @{
        ViewBag.Title = "Confirm Camera Deletion";
    }
    
    <h2 class="maroon common-font text-center bold">Confirm Camera Deletion</h2>
    
    <hr />
    
    @using (Html.BeginForm("Delete", "Cameras", FormMethod.Post))
    {
        <div class="containment">
            <div class="small-content common-font">
                <table>
                    <tr>
                        <td class="small-text bold maroon">Camera #</td>
                        <td>@Html.TextBox("CameraNumber", @ViewBag.CameraNumber as string, htmlAttributes: new { @class = "form-control" })</td>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td></td>
                    </tr>
                    <tr>
                        <td class="maroon bold">Make</td>
                        <td>@Html.TextBox("Make", @ViewBag.Make as string, htmlAttributes: new { @class = "form-control", disabled = "disabled" })</td>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td></td>
                    </tr>
                    <tr>
                        <td class="maroon bold">Model</td>
                        <td>@Html.TextBox("Model", @ViewBag.Model as string, htmlAttributes: new { @class = "form-control", disabled = "disabled" })</td>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td></td>
                    </tr>
                    <tr>
                        <td class="maroon bold">Location</td>
                        <td>@Html.TextBox("Location", @ViewBag.Location as string, htmlAttributes: new { @class = "form-control", disabled = "disabled" })</td>
                    </tr>
                </table>
            </div>
        </div>
    
        <hr />
        
        <div class="form-group">
            <label class="col-md-6 control-label"></label>
            <div class="col-md-6">
                <input type="submit" value="Delete this Camera's Record" class="btn btn-warning" />
            </div>
        </div>
    }
    
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Cameras", "Index") ::
        @Html.ActionLink("Create New Camera", "Create") ::
        @Html.ActionLink("Review Camera Details", "Details") ::
        @Html.ActionLink("Edit/Update Camera Details", "PrepareEdit")</p>
  18. In the Solution Explorer, under Controllers, double-click VehiclesController.cs to access it
  19. In the VehiclesController class, create four methods as follows:
    using System.IO;
    using System.Web.Mvc;
    using System.Collections.Generic;
    using TrafficTicketsSystem1.Models;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace TrafficTicketsSystem1.Controllers
    {
        public class VehiclesController : Controller
        {
            // GET: Vehicles
            public ActionResult Index()
            {
                FileStream fsVehicles = null;
                BinaryFormatter bfVehicles = new BinaryFormatter();
                LinkedList<Vehicle> vehicles = new LinkedList<Vehicle>();
    
                string strVehiclesFile = Server.MapPath("~/App_Data/Vehicles.tts");
    
                if (System.IO.File.Exists(strVehiclesFile))
                {
                    using (fsVehicles = new FileStream(strVehiclesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        vehicles = (LinkedList<Vehicle>)bfVehicles.Deserialize(fsVehicles);
                    }
                }
    
                return View(vehicles);
            }
    
            // GET: Vehicles/Details/5
            public ActionResult Details()
            {
                return View();
            }
    
            // GET: Vehicles/PrepareEdit/
            public ActionResult PrepareEdit()
            {
                return View();
            }
    
            // GET: Vehicles/ConfirmEdit/
            public ActionResult ConfirmEdit(FormCollection collection)
            {
                if (!string.IsNullOrEmpty(collection["TagNumber"]))
                {
                    FileStream fsVehicles = null;
                    Vehicle vehicle = new Vehicle();
                    BinaryFormatter bfVehicles = new BinaryFormatter();
                    LinkedList<Vehicle> vehicles = new LinkedList<Vehicle>();
                    string strVehiclesFile = Server.MapPath("~/App_Data/Vehicles.tts");
    
                    if (System.IO.File.Exists(strVehiclesFile))
                    {
                        using (fsVehicles = new FileStream(strVehiclesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            vehicles = (LinkedList<Vehicle>)bfVehicles.Deserialize(fsVehicles);
                        }
    
                        vehicle.TagNumber = collection["TagNumber"];
    
                        LinkedListNode<Vehicle> car = vehicles.FindLast(vehicle);
    
                        ViewBag.TagNumber = collection["TagNumber"];
                        ViewBag.DrvLicNumber = car.Value.DrvLicNumber;
                        ViewBag.Make = car.Value.Make;
                        ViewBag.Model = car.Value.Model;
                        ViewBag.VehicleYear = car.Value.VehicleYear;
                        ViewBag.Color = car.Value.Color;
                    }
                }
    
                return View();
            }
    
            // GET: Vehicles/Edit/
            public ActionResult Edit()
            {
                return View();
            }
    
            // POST: Vehicles/Edit/
            [HttpPost]
            public ActionResult Edit(FormCollection collection)
            {
                try
                {
                    FileStream fsVehicles = null;
                    Vehicle vehicle = new Vehicle();
                    BinaryFormatter bfVehicles = new BinaryFormatter();
                    LinkedList<Vehicle> vehicles = new LinkedList<Vehicle>();
                    string strVehiclesFile = Server.MapPath("~/App_Data/Vehicles.tts");
    
                    if (!string.IsNullOrEmpty("CameraNumber"))
                    {
                        if (System.IO.File.Exists(strVehiclesFile))
                        {
                            using (fsVehicles = new FileStream(strVehiclesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                vehicles = (LinkedList<Vehicle>)bfVehicles.Deserialize(fsVehicles);
                            }
                        }
    
                        vehicle.TagNumber = collection["TagNumber"];
    
                        LinkedListNode<Vehicle> car = vehicles.FindLast(vehicle);
    
                        car.Value.TagNumber = collection["TagNumber"];
                        car.Value.Make = collection["Make"];
                        car.Value.Model = collection["Model"];
                        car.Value.VehicleYear = collection["VehicleYear"];
                        car.Value.Color = collection["Color"];
    
                        using (fsVehicles = new FileStream(strVehiclesFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                        {
                            bfVehicles.Serialize(fsVehicles, vehicles);
                        }
                    }
    
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
    
            // GET: Vehicles/Create
            public ActionResult Create()
            {
                return View();
            }
    
            // POST: Vehicles/Create
            [HttpPost]
            public ActionResult Create(FormCollection collection)
            {
                try
                {
                    bool driverFound = false;
                    FileStream fsVehicles = null, fsDrivers = null;
                    BinaryFormatter bfDrivers = new BinaryFormatter();
                    BinaryFormatter bfVehicles = new BinaryFormatter();
                    LinkedList<Driver> drivers = new LinkedList<Driver>();
                    LinkedList<Vehicle> vehicles = new LinkedList<Vehicle>();
                    string strDriversFile = Server.MapPath("~/App_Data/Drivers.tts");
                    string strVehiclesFile = Server.MapPath("~/App_Data/Vehicles.tts");
    
                    // Open the file of the drivers records
                    if (System.IO.File.Exists(strDriversFile))
                    {
                        using (fsDrivers = new FileStream(strDriversFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            /* After opening the file, get the list of records from it
                             * and store in the empty LinkedList<> collection we started. */
                            drivers = (LinkedList<Driver>)bfDrivers.Deserialize(fsDrivers);
    
                            // Navigate to each record
                            foreach (Driver person in drivers)
                            {
                                /* When you get to a record, find out if its DrvLicNumber value 
                                 * is the DrvLicNumber the user typed on the form. */
                                if (person.DrvLicNumber == collection["DrvLicNumber"])
                                {
                                    /* If you find the record with that DrvLicNumber value, 
                                     * make a note to indicate it. */
                                    driverFound = true;
                                    break;
                                }
                            }
                        }
                    }
    
                    /* If the driverFound is true, it means the driver's license 
                     * number is valid, which means we can save the record. */
                    if (driverFound == true)
                    {
                        // Check whether a file for vehicles exists already.
                        if (System.IO.File.Exists(strVehiclesFile))
                        {
                            // If a file for vehicles exists already, open it ...
                            using (fsVehicles = new FileStream(strVehiclesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                // ... and store the records in our vehicles variable
                                vehicles = (LinkedList<Vehicle>)bfVehicles.Deserialize(fsVehicles);
                            }
                        }
    
                        Vehicle car = new Vehicle()
                        {
                            TagNumber = collection["TagNumber"],
                            DrvLicNumber = collection["DrvLicNumber"],
                            Make = collection["Make"],
                            Model = collection["Model"],
                            VehicleYear = collection["VehicleYear"],
                            Color = collection["Color"]
                        };
    
                        LinkedListNode<Vehicle> node = new LinkedListNode<Vehicle>(car);
                        vehicles.AddLast(node);
    
                        using (fsVehicles = new FileStream(strVehiclesFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                        {
                            bfVehicles.Serialize(fsVehicles, vehicles);
                        }
                    }
    
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
    
            // GET: Vehicles/PrepareDelete/
            public ActionResult PrepareDelete()
            {
                return View();
            }
    
            // GET: Vehicles/ConfirmDelete/
            public ActionResult ConfirmDelete(FormCollection collection)
            {
                if (!string.IsNullOrEmpty(collection["TagNumber"]))
                {
                    FileStream fsVehicles = null;
                    Vehicle car = new Vehicle();
                    BinaryFormatter bfVehicles = new BinaryFormatter();
                    LinkedList<Vehicle> vehicles = new LinkedList<Vehicle>();
                    string strVehiclesFile = Server.MapPath("~/App_Data/Vehicles.tts");
    
                    if (System.IO.File.Exists(strVehiclesFile))
                    {
                        using (fsVehicles = new FileStream(strVehiclesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            vehicles = (LinkedList<Vehicle>)bfVehicles.Deserialize(fsVehicles);
                        }
    
                        car.TagNumber = collection["TagNumber"];
    
                        LinkedListNode<Vehicle> node = vehicles.FindLast(car);
    
                        ViewBag.TagNumber = node.Value.TagNumber;
                        ViewBag.DrvLicNumber = node.Value.DrvLicNumber;
                        ViewBag.Make = node.Value.Make;
                        ViewBag.Model = node.Value.Model;
                        ViewBag.VehicleYear = node.Value.VehicleYear;
                        ViewBag.Color = node.Value.Color;
                    }
                }
    
                return View();
            }
    
            // GET: Vehicles/Delete/
            public ActionResult Delete()
            {
                return View();
            }
    
            // POST: Drivers/Delete/
            [HttpPost]
            public ActionResult Delete(FormCollection collection)
            {
                try
                {
                    FileStream fsVehicles = null;
                    Vehicle car = new Vehicle();
                    BinaryFormatter bfVehicles = new BinaryFormatter();
                    LinkedList<Vehicle> vehicles = new LinkedList<Vehicle>();
                    string strVehiclesFile = Server.MapPath("~/App_Data/Vehicles.tts");
    
                    if (!string.IsNullOrEmpty("TagNumber"))
                    {
                        if (System.IO.File.Exists(strVehiclesFile))
                        {
                            using (fsVehicles = new FileStream(strVehiclesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                vehicles = (LinkedList<Vehicle>)bfVehicles.Deserialize(fsVehicles);
                            }
                        }
    
                        if (vehicles.Count > 0)
                        {
                            car.TagNumber = collection["TagNumber"];
    
                            //LinkedListNode<Vehicle> vehicle = vehicles.Find(car);
    
                            vehicles.Remove(car);
    
                            using (fsVehicles = new FileStream(strVehiclesFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                            {
                                bfVehicles.Serialize(fsVehicles, vehicles);
                            }
                        }
                    }
    
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
        }
    }
  20. In the VehiclesController class, right-click PrepareDelete() -> Add View...
  21. Make sure the View Name text box is displaying PrepareDelete.
    Click Add
  22. Create a form as follows:
    @model TrafficTicketsSystem1.Models.Vehicle
    
    @{
        ViewBag.Title = "Prepare Delete";
    }
    
    <h2 class="maroon common-font text-center bold">Prepare Vehicle Delete</h2>
    
    <hr />
    
    @using (Html.BeginForm("ConfirmDelete", "Vehicles", FormMethod.Post))
    {
        @Html.AntiForgeryToken()
    
        <div class="large-content">
            <div class="form-horizontal common-font">
                @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                <div class="form-group">
                    @Html.LabelFor(model => model.TagNumber, htmlAttributes: new { @class = "control-label col-md-4 maroon" })
                    <div class="col-md-4">
                        @Html.EditorFor(model => model.TagNumber, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.TagNumber, "", new { @class = "text-danger" })
                    </div>
                    <div class="col-md-4">
                        <p><input type="submit" value="Find Vehicle" class="btn btn-warning small-text" /></p>
                    </div>
                </div>
            </div>
        </div>
    }
    
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Cars - Vehicle", "Index") ::
        @Html.ActionLink("Create Vehicle Registration", "Create") ::
        @Html.ActionLink("Vehicle Details", "Details") ::
        @Html.ActionLink("Edit/Update Vehicle Registration", "PrepareEdit")</p>
  23. In the Solution Explorer, under Views, right-click Vehicles -> Add -> View...
  24. Type ConfirmDelete as the name of the view
  25. Click OK
  26. Create a form as follows:
    @{
        ViewBag.Title = "Confirm Vehicle Delete";
    }
    
    <h2 class="maroon common-font text-center bold">Confirm Vehicle Delete</h2>
    
    <hr />
    
    @using (Html.BeginForm("Delete", "Vehicles", FormMethod.Post))
    {
        <div class="containment">
            <div class="small-content common-font">
                <table>
                    <tr>
                        <td class="maroon bold">Tag #</td>
                        <td>@Html.TextBox("TagNumber", @ViewBag.TagNumber as string, htmlAttributes: new { @class = "form-control" })</td>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td></td>
                    </tr>
                    <tr>
                        <td class="small-text bold maroon">Drv. Lic. #</td>
                        <td>@Html.TextBox("DrvLicNumber", @ViewBag.DrvLicNumber as string, htmlAttributes: new { @class = "form-control" })</td>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td></td>
                    </tr>
                    <tr>
                        <td class="maroon bold">Make</td>
                        <td>@Html.TextBox("Make", @ViewBag.Make as string, htmlAttributes: new { @class = "form-control" })</td>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td></td>
                    </tr>
                    <tr>
                        <td class="maroon bold">Model</td>
                        <td>@Html.TextBox("Model", @ViewBag.Model as string, htmlAttributes: new { @class = "form-control" })</td>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td></td>
                    </tr>
                    <tr>
                        <td class="maroon bold">Vehicle Year</td>
                        <td>@Html.TextBox("VehicleYear", @ViewBag.VehicleYear as string, htmlAttributes: new { @class = "form-control" })</td>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td></td>
                    </tr>
                    <tr>
                        <td class="maroon bold">Color</td>
                        <td>@Html.TextBox("Color", @ViewBag.Color as string, htmlAttributes: new { @class = "form-control" })</td>
                    </tr>
                </table>
            </div>
        </div>
    
        <hr />
        
        <div class="form-group">
            <label class="col-md-6 control-label"></label>
            <div class="col-md-6">
                <input type="submit" value="Delete this Vehicle's Registration" class="btn btn-warning" />
            </div>
        </div>
    }
    
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Vehicles", "Index") ::
        @Html.ActionLink("Create New Vehicle", "Create") ::
        @Html.ActionLink("Review Vehicle Details", "Details") ::
        @Html.ActionLink("Edit/Update Vehicle Details", "PrepareEdit")</p>

Removing a Node by its Reference

An alternative is to delete a node based on its reference. To do this, use the following version:

public void Remove(LinkedListNode<T> node);

When calling this method, pass a reference to the node you want to delete. Here is an example:

<!DOCTYPE html>
<html>
<head>
<title>Numbers</title>
</head>
<body>
<h2>Numbers</h2>

@{
    List<double> values = new List<double>();
    values.Add(84.597);
    values.Add(6.47);
    values.Add(2747.06);
    values.Add(282.924);

    LinkedList<double> numbers = new LinkedList<double>(values);
    LinkedListNode<double> number = new LinkedListNode<double>(148.24);
    numbers.AddFirst(number);

    numbers.AddLast(18264.86);

    number = new LinkedListNode<double>(35.75);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(2222.06);
    numbers.AddFirst(number);

    LinkedListNode<double> last = new LinkedListNode<double>(827366.993);
    numbers.AddLast(last);

    number = new LinkedListNode<double>(4.19);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(66.18);
    numbers.AddFirst(number);

    LinkedListNode<double> reference = numbers.Find(148.24);
    numbers.AddBefore(reference, 9999.9999);

    LinkedListNode<double> other = numbers.Find(6.47);
    LinkedListNode<double> before = new LinkedListNode<double>(7777.7777);
    numbers.AddBefore(other, before);

    numbers.Remove(84.597);

    LinkedListNode<double> dismiss = numbers.Find(282.924);
    numbers.Remove(dismiss);
}

<ul>
    @foreach (double nbr in numbers)
    {
        if ((nbr == 7777.7777) || (nbr == 9999.9999))
        {
            <li style="color: tomato">Number: @nbr</li>
        }
        else if ((nbr == 6.47) || (nbr == 148.24))
        {
            <li style="color: blue">Number: @nbr</li>
        }
        else
        {
            <li>Number: @nbr</li>
        }
    }
</ul>
</body>
</html>

This would produce:

Linked List

Practical LearningPractical Learning: Deleting a Node by Reference

  1. In the Solution Explorer, under Controllers, double-click DriversController.cs to access it
  2. In the VehiclesController class, create four methods as follows:
    using System.IO;
    using System.Web.Mvc;
    using System.Collections.Generic;
    using TrafficTicketsSystem1.Models;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace TrafficTicketsSystem1.Controllers
    {
        public class DriversController : Controller
        {
            // GET: Drivers
            public ActionResult Index()
            {
                FileStream fsDrivers = null;
                BinaryFormatter bfDrivers = new BinaryFormatter();
                LinkedList<Driver> drivers = new LinkedList<Driver>();
                string strDriversFile = Server.MapPath("~/App_Data/Drivers.tts");
    
                if (System.IO.File.Exists(strDriversFile))
                {
                    using (fsDrivers = new FileStream(strDriversFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        drivers = (LinkedList<Driver>)bfDrivers.Deserialize(fsDrivers);
                    }
                }
    
                return View(drivers);
            }
    
            // GET: Drivers/Details
            public ActionResult Details()
            {
                return View();
            }
    
            // GET: Drivers/PrepareEdit/
            public ActionResult PrepareEdit()
            {
                return View();
            }
    
            // GET: Drivers/ConfirmEdit/
            public ActionResult ConfirmEdit(FormCollection collection)
            {
                if (!string.IsNullOrEmpty(collection["DrvLicNumber"]))
                {
                    FileStream fsDrivers       = null;
                    Driver driver              = new Driver();
                    BinaryFormatter bfDrivers  = new BinaryFormatter();
                    LinkedList<Driver> drivers = new LinkedList<Driver>();
                    string strDriversFile      = Server.MapPath("~/App_Data/Drivers.tts");
    
                    if (System.IO.File.Exists(strDriversFile))
                    {
                        using (fsDrivers = new FileStream(strDriversFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            drivers = (LinkedList<Driver>)bfDrivers.Deserialize(fsDrivers);
                        }
    
                        driver.DrvLicNumber = collection["DrvLicNumber"];
    
                        LinkedListNode<Driver> person = drivers.Find(driver);
    
                        ViewBag.DrvLicNumber = collection["DrvLicNumber"];
                        ViewBag.FirstName    = person.Value.FirstName;
                        ViewBag.LastName     = person.Value.LastName;
                        ViewBag.Address      = person.Value.Address;
                        ViewBag.City         = person.Value.City;
                        ViewBag.County       = person.Value.County;
                        ViewBag.State        = person.Value.State;
                        ViewBag.ZIPCode      = person.Value.ZIPCode;
                    }
                }
    
                return View();
            }
    
            // GET: Drivers/Edit/
            public ActionResult Edit()
            {
                return View();
            }
    
            // POST: Drivers/Edit/
            [HttpPost]
            public ActionResult Edit(FormCollection collection)
            {
                try
                {
                    FileStream fsDrivers       = null;
                    Driver driver              = new Driver();
                    BinaryFormatter bfDrivers  = new BinaryFormatter();
                    LinkedList<Driver> drivers = new LinkedList<Driver>();
                    string strDriversFile      = Server.MapPath("~/App_Data/Drivers.tts");
    
                    if (!string.IsNullOrEmpty("CameraNumber"))
                    {
                        if (System.IO.File.Exists(strDriversFile))
                        {
                            using (fsDrivers = new FileStream(strDriversFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                drivers = (LinkedList<Driver>)bfDrivers.Deserialize(fsDrivers);
                            }
                        }
    
                        driver.DrvLicNumber = collection["DrvLicNumber"];
    
                        LinkedListNode<Driver> person = drivers.Find(driver);
    
                        person.Value.FirstName = collection["FirstName"];
                        person.Value.LastName  = collection["LastName"];
                        person.Value.Address   = collection["Address"];
                        person.Value.City      = collection["City"];
                        person.Value.County    = collection["County"];
                        person.Value.State     = collection["State"];
                        person.Value.ZIPCode   = collection["ZIPCode"];
    
                        using (fsDrivers = new FileStream(strDriversFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                        {
                            bfDrivers.Serialize(fsDrivers, drivers);
                        }
                    }
    
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
    
            // GET: Drivers/Create
            public ActionResult Create()
            {
                return View();
            }
    
            // POST: Drivers/Create
            [HttpPost]
            public ActionResult Create(FormCollection collection)
            {
                try
                {
                    Driver drv = new Driver();
                    FileStream fsDrivers = null;
                    BinaryFormatter bfDrivers = new BinaryFormatter();
                    LinkedList<Driver> drivers = new LinkedList<Driver>();
                    string strDriversFile = Server.MapPath("~/App_Data/Drivers.tts");
    
                    // Make sure the user provides both the driver's license number and a state
                    if ((!string.IsNullOrEmpty("DrvLicNumber")) && (!string.IsNullOrEmpty("State")))
                    {
                        // Assuming the user provided a State value, make that
                        // Find out whether a file for drivers was created already
                        if (System.IO.File.Exists(strDriversFile))
                        {
                            // If that file exists, open it...
                            using (fsDrivers = new FileStream(strDriversFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                // ... and store the records in the LinkedList<Driver> variable
                                drivers = (LinkedList<Driver>)bfDrivers.Deserialize(fsDrivers);
    
                                // Check all the drivers records
                                foreach (Driver d in drivers)
                                {
                                    // When you get to a record, if its State is the same the user enter, make it the reference node
                                    if (d.State.Equals(collection["State"]))
                                    {
                                        drv = d;
                                    }
                                }
                            }
                        }
    
                        LinkedListNode<Driver> referenceNode = drivers.Find(drv);
    
                        // Prepare a driver's record to save
                        Driver person = new Driver()
                        {
                            DrvLicNumber = collection["DrvLicNumber"],
                            FirstName = collection["FirstName"],
                            LastName = collection["LastName"],
                            Address = collection["Address"],
                            City = collection["City"],
                            County = collection["County"],
                            State = collection["State"],
                            ZIPCode = collection["ZIPCode"],
                        };
    
                        // If there is no driver yet, then simply add the new driver as the last record
                        if (referenceNode == null)
                        {
                            drivers.AddLast(person);
                        }
                        else // if( referenceNode != null)
                        {
                            drivers.AddAfter(referenceNode, person);
                        }
    
                        using (fsDrivers = new FileStream(strDriversFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                        {
                            bfDrivers.Serialize(fsDrivers, drivers);
                        }
                    }
    
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
    
            // GET: Drivers/PrepareDelete/
            public ActionResult PrepareDelete()
            {
                return View();
            }
    
            // GET: Drivers/ConfirmDelete/
            public ActionResult ConfirmDelete(FormCollection collection)
            {
                if (!string.IsNullOrEmpty(collection["DrvLicNumber"]))
                {
                    FileStream fsDrivers = null;
                    Driver driver = new Driver();
                    BinaryFormatter bfDrivers = new BinaryFormatter();
                    LinkedList<Driver> drivers = new LinkedList<Driver>();
                    string strDriversFile = Server.MapPath("~/App_Data/Drivers.tts");
    
                    if (System.IO.File.Exists(strDriversFile))
                    {
                        using (fsDrivers = new FileStream(strDriversFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            drivers = (LinkedList<Driver>)bfDrivers.Deserialize(fsDrivers);
                        }
    
                        driver.DrvLicNumber = collection["DrvLicNumber"];
    
                        LinkedListNode<Driver> person = drivers.Find(driver);
    
                        ViewBag.DrvLicNumber = collection["DrvLicNumber"];
                        ViewBag.FirstName = person.Value.FirstName;
                        ViewBag.LastName = person.Value.LastName;
                        ViewBag.Address = person.Value.Address;
                        ViewBag.City = person.Value.City;
                        ViewBag.County = person.Value.County;
                        ViewBag.State = person.Value.State;
                        ViewBag.ZIPCode = person.Value.ZIPCode;
                    }
                }
    
                return View();
            }
    
            // GET: Drivers/Delete/
            public ActionResult Delete()
            {
                return View();
            }
    
            // POST: Drivers/Delete/
            [HttpPost]
            public ActionResult Delete(FormCollection collection)
            {
                try
                {
                    FileStream fsDrivers = null;
                    Driver driver = new Driver();
                    BinaryFormatter bfDrivers = new BinaryFormatter();
                    LinkedList<Driver> drivers = new LinkedList<Driver>();
                    string strDriversFile = Server.MapPath("~/App_Data/Drivers.tts");
    
                    if (!string.IsNullOrEmpty("DrvLicNumber"))
                    {
                        if (System.IO.File.Exists(strDriversFile))
                        {
                            using (fsDrivers = new FileStream(strDriversFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                drivers = (LinkedList<Driver>)bfDrivers.Deserialize(fsDrivers);
                            }
                        }
    
                        if (drivers.Count > 0)
                        {
                            driver.DrvLicNumber = collection["DrvLicNumber"];
    
                            LinkedListNode<Driver> viewer = drivers.Find(driver);
    
                            drivers.Remove(viewer);
    
                            using (fsDrivers = new FileStream(strDriversFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                            {
                                bfDrivers.Serialize(fsDrivers, drivers);
                            }
                        }
                    }
    
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
        }
    }
  3. In the Drivers class, right-click PrepareDelete() -> Add View...
  4. Make sure the View Name text box is displaying PrepareDelete.
    Click Add
  5. Create a form as follows:
    @model TrafficTicketsSystem1.Models.Driver
    
    @{
        ViewBag.Title = "Prepare Driver Edit";
    }
    
    <h2 class="maroon common-font text-center bold">Prepare Driver Edition</h2>
    
    <hr />
    
    @using (Html.BeginForm("ConfirmDeletion", "Drivers", FormMethod.Post))
    {
        @Html.AntiForgeryToken()
    
        <div class="large-content">
            <div class="form-horizontal common-font">
                @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                <div class="form-group">
                    @Html.LabelFor(model => model.DrvLicNumber, htmlAttributes: new { @class = "control-label col-md-4 maroon" })
                    <div class="col-md-4">
                        @Html.EditorFor(model => model.DrvLicNumber, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.DrvLicNumber, "", new { @class = "text-danger" })
                    </div>
                    <div class="col-md-4">
                        <p><input type="submit" value="Find Driver" class="btn btn-warning small-text" /></p>
                    </div>
                </div>
            </div>
        </div>
    }
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Drivers - Vehicles Owners", "Index") ::
        @Html.ActionLink("Issue a New Driver's License", "Create") ::
        @Html.ActionLink("Review a Driver's License", "Details") ::
        @Html.ActionLink("Edit/Update a Driver's License", "PrepareEdit")</p>
    
  6. In the Solution Explorer, under Views, right-click Drivers -> Add -> View...
  7. Type ConfirmDeletion as the View Name
  8. Click OK
  9. Create a form as follows:
    @{
        ViewBag.Title = "Confirm Driver Deletion";
    }
    
    <h2 class="maroon common-font text-center bold">Confirm Camera Deletion</h2>
    
    <hr />
    
    @using (Html.BeginForm("Delete", "Drivers", FormMethod.Post))
    {
        <div class="containment">
            <div class="small-content common-font">
                <table>
                    <tr>
                        <td class="small-text bold maroon">Drv. Lic. #</td>
                        <td>@Html.TextBox("DrvLicNumber", @ViewBag.DrvLicNumber as string, htmlAttributes: new { @class = "form-control" })</td>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td></td>
                    </tr>
                    <tr>
                        <td class="maroon bold">Make</td>
                        <td>@Html.TextBox("Make", @ViewBag.Make as string, htmlAttributes: new { @class = "form-control", disabled = "disabled" })</td>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td></td>
                    </tr>
                    <tr>
                        <td class="maroon bold">Model</td>
                        <td>@Html.TextBox("Model", @ViewBag.Model as string, htmlAttributes: new { @class = "form-control", disabled = "disabled" })</td>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td></td>
                    </tr>
                    <tr>
                        <td class="maroon bold">Location</td>
                        <td>@Html.TextBox("Location", @ViewBag.Location as string, htmlAttributes: new { @class = "form-control", disabled = "disabled" })</td>
                    </tr>
                </table>
            </div>
        </div>
    
        <hr />
    
        <div class="form-group">
            <label class="col-md-6 control-label"></label>
            <div class="col-md-6">
                <input type="submit" value="Delete this Camera's Record" class="btn btn-warning" />
            </div>
        </div>
    }
    
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Cameras", "Index") ::
        @Html.ActionLink("Create New Camera", "Create") ::
        @Html.ActionLink("Review Camera Details", "Details") ::
        @Html.ActionLink("Edit/Update Camera Details", "PrepareEdit")</p>
  10. In the Solution Explorer, under Controllers, double-click TrafficViolations.cs to access it
  11. In the class, create new methods as follows:
    using System;
    using System.IO;
    using System.Web.Mvc;
    using System.Collections.Generic;
    using TrafficTicketsSystem1.Models;
    using System.Runtime.Serialization.Formatters.Binary;
    
    namespace TrafficTicketsSystem1.Controllers
    {
        public class TrafficViolationsController : Controller
        {
            // GET: TrafficViolations
            public ActionResult Index()
            {
                FileStream fsTrafficViolations = null;
                BinaryFormatter bfTrafficViolations = new BinaryFormatter();
                LinkedList<TrafficViolation> violations = new LinkedList<TrafficViolation>();
    
                string strTrafficViolationsFile = Server.MapPath("~/App_Data/TrafficViolations.tts");
    
                if (System.IO.File.Exists(strTrafficViolationsFile))
                {
                    using (fsTrafficViolations = new FileStream(strTrafficViolationsFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        violations = (LinkedList<TrafficViolation>)bfTrafficViolations.Deserialize(fsTrafficViolations);
                    }
                }
    
                return View(violations);
            }
    
            // GET: Drivers/Details/
            public ActionResult Details()
            {
                return View();
            }
    
            // GET: TrafficViolations/PrepareEdit/
            public ActionResult PrepareEdit()
            {
                return View();
            }
    
            // GET: TrafficViolations/ConfirmEdit/
            public ActionResult ConfirmEdit(FormCollection collection)
            {
                FileStream fsTrafficViolations = null;
                BinaryFormatter bfTrafficViolations = new BinaryFormatter();
                LinkedList<TrafficViolation> violations = new LinkedList<TrafficViolation>();
                string strTrafficViolationsFile = Server.MapPath("~/App_Data/TrafficViolations.tts");
    
                if (System.IO.File.Exists(strTrafficViolationsFile))
                {
                    using (fsTrafficViolations = new FileStream(strTrafficViolationsFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        violations = (LinkedList<TrafficViolation>)bfTrafficViolations.Deserialize(fsTrafficViolations);
                    }
    
                    TrafficViolation violation = new TrafficViolation();
                    violation.TrafficViolationNumber = int.Parse(collection["TrafficViolationNumber"]);
    
                    LinkedListNode<TrafficViolation> node = violations.FindLast(violation);
    
                    BinaryFormatter bfCameras = new BinaryFormatter();
                    FileStream fsCameras = null, fsViolationsTypes = null;
                    LinkedList<Camera> cameras = new LinkedList<Camera>();
                    BinaryFormatter bfViolationsTypes = new BinaryFormatter();
                    string strCamerasFile = Server.MapPath("~/App_Data/Cameras.tts");
                    LinkedList<ViolationType> violationsTypes = new LinkedList<ViolationType>();
                    string strViolationsTypesFile = Server.MapPath("~/App_Data/ViolationsTypes.tts");
    
                    List<SelectListItem> itemsCameras = new List<SelectListItem>();
                    List<SelectListItem> paymentsStatus = new List<SelectListItem>();
                    List<SelectListItem> itemsPhotoAvailable = new List<SelectListItem>();
                    List<SelectListItem> itemsVideoAvailable = new List<SelectListItem>();
                    List<SelectListItem> itemsViolationsTypes = new List<SelectListItem>();
    
                    if (System.IO.File.Exists(strCamerasFile))
                    {
                        using (fsCameras = new FileStream(strCamerasFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            cameras = (LinkedList<Camera>)bfCameras.Deserialize(fsCameras);
    
                            foreach (Camera cmr in cameras)
                            {
                                itemsCameras.Add(new SelectListItem() { Text = cmr.CameraNumber, Value = cmr.CameraNumber, Selected = (node.Value.CameraNumber == cmr.CameraNumber) });
                            }
                        }
                    }
    
                    if (System.IO.File.Exists(strViolationsTypesFile))
                    {
                        using (fsViolationsTypes = new FileStream(strViolationsTypesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            violationsTypes = (LinkedList<ViolationType>)bfViolationsTypes.Deserialize(fsViolationsTypes);
    
                            foreach (ViolationType vt in violationsTypes)
                            {
                                itemsViolationsTypes.Add(new SelectListItem() { Text = vt.ViolationName, Value = vt.ViolationName, Selected = (node.Value.ViolationName == vt.ViolationName) });
                            }
                        }
                    }
    
                    itemsPhotoAvailable.Add(new SelectListItem() { Value = "Unknown" });
                    itemsPhotoAvailable.Add(new SelectListItem() { Text = "No", Value = "No", Selected = (node.Value.PhotoAvailable == "No") });
                    itemsPhotoAvailable.Add(new SelectListItem() { Text = "Yes", Value = "Yes", Selected = (node.Value.PhotoAvailable == "Yes") });
                    itemsVideoAvailable.Add(new SelectListItem() { Value = "Unknown" });
                    itemsVideoAvailable.Add(new SelectListItem() { Text = "No", Value = "No", Selected = (node.Value.VideoAvailable == "No") });
                    itemsVideoAvailable.Add(new SelectListItem() { Text = "Yes", Value = "Yes", Selected = (node.Value.VideoAvailable == "Yes") });
    
                    paymentsStatus.Add(new SelectListItem() { Value = "Unknown" });
                    paymentsStatus.Add(new SelectListItem() { Text = "Pending", Value = "Pending", Selected = (node.Value.PaymentStatus == "Pending") });
                    paymentsStatus.Add(new SelectListItem() { Text = "Rejected", Value = "Rejected", Selected = (node.Value.PaymentStatus == "Rejected") });
                    paymentsStatus.Add(new SelectListItem() { Text = "Cancelled", Value = "Cancelled", Selected = (node.Value.PaymentStatus == "Cancelled") });
                    paymentsStatus.Add(new SelectListItem() { Text = "Paid Late", Value = "Paid Late", Selected = (node.Value.PaymentStatus == "Paid Late") });
                    paymentsStatus.Add(new SelectListItem() { Text = "Paid On Time", Value = "Paid On Time", Selected = (node.Value.PaymentStatus == "Paid On Time") });
    
                    ViewBag.CameraNumber = itemsCameras;
                    ViewBag.PaymentStatus = paymentsStatus;
                    ViewBag.TagNumber = node.Value.TagNumber;
                    ViewBag.PaymentDate = node.Value.PaymentDate;
                    ViewBag.ViolationName = itemsViolationsTypes;
                    ViewBag.PhotoAvailable = itemsPhotoAvailable;
                    ViewBag.VideoAvailable = itemsVideoAvailable;
                    ViewBag.PaymentAmount = node.Value.PaymentAmount;
                    ViewBag.ViolationDate = node.Value.ViolationDate;
                    ViewBag.ViolationTime = node.Value.ViolationTime;
                    ViewBag.PaymentDueDate = node.Value.PaymentDueDate;
                    ViewBag.TrafficViolationNumber = node.Value.TrafficViolationNumber;
                }
    
                return View();
            }
    
            // GET: TrafficViolations/Edit/
            public ActionResult Edit()
            {
                return View();
            }
    
            // POST: TrafficViolations/Edit/
            [HttpPost]
            public ActionResult Edit(FormCollection collection)
            {
                try
                {
                    FileStream fsTrafficViolations = null;
                    TrafficViolation violation = new TrafficViolation();
                    BinaryFormatter bfTrafficViolations = new BinaryFormatter();
                    LinkedList<TrafficViolation> violations = new LinkedList<TrafficViolation>();
                    string strTrafficViolationsFile = Server.MapPath("~/App_Data/TrafficViolations.tts");
    
                    if (!string.IsNullOrEmpty("TrafficViolationNumber"))
                    {
                        if (System.IO.File.Exists(strTrafficViolationsFile))
                        {
                            using (fsTrafficViolations = new FileStream(strTrafficViolationsFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                violations = (LinkedList<TrafficViolation>)bfTrafficViolations.Deserialize(fsTrafficViolations);
                            }
                        }
    
                        violation.TrafficViolationNumber = int.Parse(collection["TrafficViolationNumber"]);
    
                        LinkedListNode<TrafficViolation> infraction = violations.FindLast(violation);
    
                        infraction.Value.CameraNumber = collection["CameraNumber"];
                        infraction.Value.TagNumber = collection["TagNumber"];
                        infraction.Value.ViolationName = collection["ViolationName"];
                        infraction.Value.ViolationDate = collection["ViolationDate"];
                        infraction.Value.ViolationTime = collection["ViolationTime"];
                        infraction.Value.PhotoAvailable = collection["PhotoAvailable"];
                        infraction.Value.VideoAvailable = collection["VideoAvailable"];
                        infraction.Value.PaymentDueDate = collection["PaymentDueDate"];
                        infraction.Value.PaymentDate = collection["PaymentDate"];
                        infraction.Value.PaymentAmount = double.Parse(collection["PaymentAmount"]);
                        infraction.Value.PaymentStatus = collection["PaymentStatus"];
    
                        using (fsTrafficViolations = new FileStream(strTrafficViolationsFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                        {
                            bfTrafficViolations.Serialize(fsTrafficViolations, violations);
                        }
                    }
    
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
    
            // GET: Drivers/PrepareCitation/
            public ActionResult PrepareCitation()
            {
                return View();
            }
    
            /* This function takes the available status of a photo and video taken during the traffic violation.
               The function returns a sentence that will instruct the driver about how to view the photo or video or the violation. */
            private string GetPhotoVideoOptions(string photo, string video)
            {
                var sentence = string.Empty;
                var pvAvailable = "No";
    
                if (photo == "Yes")
                {
                    if (video == "Yes")
                    {
                        pvAvailable = "Yes";
                        sentence = "To view the photo and/or video";
                    }
                    else
                    {
                        pvAvailable = "Yes";
                        sentence = "To see a photo";
                    }
                }
                else
                { // if (photo == "No")
                    if (video == "Yes")
                    {
                        pvAvailable = "Yes";
                        sentence = "To review a video";
                    }
                    else
                    {
                        pvAvailable = "No";
                    }
                }
    
                if (pvAvailable == "No")
                    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.";
            }
    
            // GET: Drivers/PresentCitation/
            public ActionResult PresentCitation(FormCollection collection)
            {
                FileStream fsTrafficViolations = null;
                BinaryFormatter bfTrafficViolations = new BinaryFormatter();
                LinkedList<TrafficViolation> violations = new LinkedList<TrafficViolation>();
                string strTrafficViolationsFile = Server.MapPath("~/App_Data/TrafficViolations.tts");
    
                if (System.IO.File.Exists(strTrafficViolationsFile))
                {
                    using (fsTrafficViolations = new FileStream(strTrafficViolationsFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        violations = (LinkedList<TrafficViolation>)bfTrafficViolations.Deserialize(fsTrafficViolations);
                    }
    
                    TrafficViolation violation = new TrafficViolation();
                    violation.TrafficViolationNumber = int.Parse(collection["TrafficViolationNumber"]);
    
                    LinkedListNode<TrafficViolation> nodeTrafficViolation = violations.FindLast(violation);
    
                    ViewBag.TrafficViolationNumber = collection["TrafficViolationNumber"];
    
                    ViewBag.ViolationDate = nodeTrafficViolation.Value.ViolationDate;
                    ViewBag.ViolationTime = nodeTrafficViolation.Value.ViolationTime;
                    ViewBag.PaymentAmount = nodeTrafficViolation.Value.PaymentAmount.ToString("C");
                    ViewBag.PaymentDueDate = nodeTrafficViolation.Value.PaymentDueDate;
    
                    ViewBag.PhotoVideo = GetPhotoVideoOptions(nodeTrafficViolation.Value.PhotoAvailable, nodeTrafficViolation.Value.VideoAvailable);
    
                    FileStream fsViolationsTypes = null;
                    ViolationType category = new ViolationType();
                    BinaryFormatter bfViolationsTypes = new BinaryFormatter();
                    LinkedList<ViolationType> categories = new LinkedList<ViolationType>();
                    string strViolationsTypesFile = Server.MapPath("~/App_Data/ViolationsTypes.tts");
    
                    if (System.IO.File.Exists(strViolationsTypesFile))
                    {
                        using (fsViolationsTypes = new FileStream(strViolationsTypesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            categories = (LinkedList<ViolationType>)bfViolationsTypes.Deserialize(fsViolationsTypes);
                        }
    
                        category.ViolationName = nodeTrafficViolation.Value.ViolationName;
    
                        LinkedListNode<ViolationType> type = categories.Find(category);
                        ViewBag.ViolationName = nodeTrafficViolation.Value.ViolationName;
                        ViewBag.ViolationDescription = type.Value.Description;
                    }
    
                    FileStream fsVehicles = null;
                    Vehicle car = new Vehicle();
                    BinaryFormatter bfVehicles = new BinaryFormatter();
                    LinkedList<Vehicle> vehicles = new LinkedList<Vehicle>();
    
                    string strVehiclesFile = Server.MapPath("~/App_Data/Vehicles.tts");
    
                    using (fsVehicles = new FileStream(strVehiclesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        vehicles = (LinkedList<Vehicle>)bfVehicles.Deserialize(fsVehicles);
                    }
    
                    car.TagNumber = nodeTrafficViolation.Value.TagNumber;
                    LinkedListNode<Vehicle> nodeVehicle = vehicles.FindLast(car);
    
                    ViewBag.Vehicle = nodeVehicle.Value.Make + " " + nodeVehicle.Value.Model + ", " +
                                      nodeVehicle.Value.Color + ", " + nodeVehicle.Value.VehicleYear + " (Tag # " +
                                      nodeVehicle.Value.TagNumber + ")";
    
                    FileStream fsDrivers = null;
                    Driver driver = new Driver();
                    BinaryFormatter bfDrivers = new BinaryFormatter();
                    LinkedList<Driver> drivers = new LinkedList<Driver>();
                    string strDriversFile = Server.MapPath("~/App_Data/Drivers.tts");
    
                    using (fsDrivers = new FileStream(strDriversFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        drivers = (LinkedList<Driver>)bfDrivers.Deserialize(fsDrivers);
                    }
    
                    driver.DrvLicNumber = nodeVehicle.Value.DrvLicNumber;
                    LinkedListNode<Driver> person = drivers.Find(driver);
    
                    ViewBag.DriverName = person.Value.FirstName + " " + person.Value.LastName + " (Drv. Lic. # " + driver.DrvLicNumber + ")";
                    ViewBag.DriverAddress = person.Value.Address + " " + person.Value.City + ", " + person.Value.State + " " + person.Value.ZIPCode;
    
                    FileStream fsCameras = null;
                    BinaryFormatter bfCameras = new BinaryFormatter();
                    LinkedList<Camera> cameras = new LinkedList<Camera>();
                    string strCamerasFile = Server.MapPath("~/App_Data/Cameras.tts");
                    LinkedList<ViolationType> violationsTypes = new LinkedList<ViolationType>();
    
                    using (fsCameras = new FileStream(strCamerasFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        cameras = (LinkedList<Camera>)bfCameras.Deserialize(fsCameras);
                    }
    
                    Camera camera = new Camera();
    
                    camera.CameraNumber = nodeTrafficViolation.Value.CameraNumber;
    
                    LinkedListNode<Camera> viewer = cameras.FindLast(camera);
    
                    ViewBag.Camera = viewer.Value.Make + " " + viewer.Value.Model + " (" + viewer.Value.CameraNumber + ")";
                    ViewBag.ViolationLocation = viewer.Value.Location;
                }
    
                return View();
            }
    
            // GET: TrafficViolations/Create
            public ActionResult Create()
            {
                Random rndNumber = new Random();
                BinaryFormatter bfCameras = new BinaryFormatter();
                FileStream fsCameras = null, fsViolationsTypes = null;
                LinkedList<Camera> cameras = new LinkedList<Camera>();
                BinaryFormatter bfViolationsTypes = new BinaryFormatter();
                string strCamerasFile = Server.MapPath("~/App_Data/Cameras.tts");
                LinkedList<ViolationType> violationsTypes = new LinkedList<ViolationType>();
                string strViolationsTypesFile = Server.MapPath("~/App_Data/ViolationsTypes.tts");
    
                List<SelectListItem> itemsCameras = new List<SelectListItem>();
                List<SelectListItem> paymentsStatus = new List<SelectListItem>();
                List<SelectListItem> itemsPhotoAvailable = new List<SelectListItem>();
                List<SelectListItem> itemsVideoAvailable = new List<SelectListItem>();
                List<SelectListItem> itemsViolationsTypes = new List<SelectListItem>();
    
                if (System.IO.File.Exists(strCamerasFile))
                {
                    using (fsCameras = new FileStream(strCamerasFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        cameras = (LinkedList<Camera>)bfCameras.Deserialize(fsCameras);
    
                        foreach (Camera cmr in cameras)
                        {
                            itemsCameras.Add(new SelectListItem() { Text = cmr.CameraNumber + " - " + cmr.Location, Value = cmr.CameraNumber });
                        }
                    }
                }
    
                if (System.IO.File.Exists(strViolationsTypesFile))
                {
                    using (fsViolationsTypes = new FileStream(strViolationsTypesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        violationsTypes = (LinkedList<ViolationType>)bfViolationsTypes.Deserialize(fsViolationsTypes);
    
                        foreach (ViolationType vt in violationsTypes)
                        {
                            itemsViolationsTypes.Add(new SelectListItem() { Text = vt.ViolationName, Value = vt.ViolationName });
                        }
                    }
                }
    
                itemsPhotoAvailable.Add(new SelectListItem() { Value = "Unknown" });
                itemsPhotoAvailable.Add(new SelectListItem() { Text = "No", Value = "No" });
                itemsPhotoAvailable.Add(new SelectListItem() { Text = "Yes", Value = "Yes" });
                itemsVideoAvailable.Add(new SelectListItem() { Value = "Unknown" });
                itemsVideoAvailable.Add(new SelectListItem() { Text = "No", Value = "No" });
                itemsVideoAvailable.Add(new SelectListItem() { Text = "Yes", Value = "Yes" });
    
                paymentsStatus.Add(new SelectListItem() { Value = "Unknown" });
                paymentsStatus.Add(new SelectListItem() { Text = "Pending", Value = "Pending" });
                paymentsStatus.Add(new SelectListItem() { Text = "Rejected", Value = "Rejected" });
                paymentsStatus.Add(new SelectListItem() { Text = "Cancelled", Value = "Cancelled" });
                paymentsStatus.Add(new SelectListItem() { Text = "Paid Late", Value = "Paid Late" });
                paymentsStatus.Add(new SelectListItem() { Text = "Paid On Time", Value = "Paid On Time" });
    
                ViewBag.CameraNumber = itemsCameras;
                ViewBag.PaymentStatus = paymentsStatus;
                ViewBag.PhotoAvailable = itemsPhotoAvailable;
                ViewBag.VideoAvailable = itemsVideoAvailable;
                ViewBag.ViolationName = itemsViolationsTypes;
                ViewBag.TrafficViolationNumber = rndNumber.Next(10000001, 99999999);
    
                return View();
            }
    
            // POST: TrafficViolations/Create
            [HttpPost]
            public ActionResult Create(FormCollection collection)
            {
                try
                {
                    bool vehicleFound = false;
                    BinaryFormatter bfDrivers = new BinaryFormatter();
                    FileStream fsTrafficViolations = null, fsVehicles = null;
                    LinkedList<Vehicle> vehicles = new LinkedList<Vehicle>();
                    BinaryFormatter bfTrafficViolations = new BinaryFormatter();
                    string strVehiclesFile = Server.MapPath("~/App_Data/Vehicles.tts");
                    LinkedList<TrafficViolation> trafficViolations = new LinkedList<TrafficViolation>();
                    string strTrafficViolationsFile = Server.MapPath("~/App_Data/TrafficViolations.tts");
    
                    // Open the file for the vehicles
                    if (System.IO.File.Exists(strVehiclesFile))
                    {
                        using (fsVehicles = new FileStream(strVehiclesFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            /* After opening the file, get the list of vehicles from it
                             * and store it in the LinkedList<Vehicle> variable. */
                            vehicles = (LinkedList<Vehicle>)bfDrivers.Deserialize(fsVehicles);
    
                            // Check each record
                            foreach (Vehicle car in vehicles)
                            {
                                /* When you get to a record, find out if its TagNumber value 
                                 * is the same as the tag number the user provided. */
                                if (car.TagNumber == collection["TagNumber"])
                                {
                                    /* If you find a record with that tag number, make a note. */
                                    vehicleFound = true;
                                    break;
                                }
                            }
                        }
                    }
    
                    /* If the vehicleFound is true, it means the car that committed the infraction has been identified. */
                    if (vehicleFound == true)
                    {
                        // Check whether a file for traffic violations was created already.
                        if (System.IO.File.Exists(strTrafficViolationsFile))
                        {
                            // If a file for traffic violations exists already, open it ...
                            using (fsTrafficViolations = new FileStream(strTrafficViolationsFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                // ... and store the records in our trafficViolations variable
                                trafficViolations = (LinkedList<TrafficViolation>)bfTrafficViolations.Deserialize(fsTrafficViolations);
                            }
                        }
    
                        TrafficViolation tv = new TrafficViolation()
                        {
                            TrafficViolationNumber = int.Parse(collection["TrafficViolationNumber"]),
                            CameraNumber = collection["CameraNumber"].Substring(0, 9),
                            TagNumber = collection["TagNumber"],
                            ViolationName = collection["ViolationName"],
                            ViolationDate = collection["ViolationDate"],
                            ViolationTime = collection["ViolationTime"],
                            PhotoAvailable = collection["PhotoAvailable"],
                            VideoAvailable = collection["VideoAvailable"],
                            PaymentDueDate = collection["PaymentDueDate"],
                            PaymentDate = collection["PaymentDate"],
                            PaymentAmount = double.Parse(collection["PaymentAmount"]),
                            PaymentStatus = collection["PaymentStatus"]
                        };
    
                        // If a list of traffic violations exists already, get the last one 
                        LinkedListNode<TrafficViolation> node = trafficViolations.Last;
    
                        if (node == null)
                        {
                            trafficViolations.AddFirst(tv);
                        }
                        else
                        {
                            // If the file contains a node already, add the new one before the last
                            trafficViolations.AddBefore(node, tv);
                        }
    
                        // After updating the list of traffic violations, save the file 
                        using (fsTrafficViolations = new FileStream(strTrafficViolationsFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                        {
                            bfTrafficViolations.Serialize(fsTrafficViolations, trafficViolations);
                        }
                    }
    
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
    
            // GET: TrafficViolations/PrepareDelete/
            public ActionResult PrepareDelete()
            {
                return View();
            }
    
            // GET: TrafficViolations/ConfirmDelete/
            public ActionResult ConfirmDelete(FormCollection collection)
            {
                if (!string.IsNullOrEmpty(collection["TrafficViolationNumber"]))
                {
                    FileStream fsTrafficViolations = null;
                    TrafficViolation violation = new TrafficViolation();
                    BinaryFormatter bfTrafficViolations = new BinaryFormatter();
                    LinkedList<TrafficViolation> violations = new LinkedList<TrafficViolation>();
                    string strTrafficViolationsFile = Server.MapPath("~/App_Data/TrafficViolations.tts");
    
                    if (System.IO.File.Exists(strTrafficViolationsFile))
                    {
                        using (fsTrafficViolations = new FileStream(strTrafficViolationsFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            violations = (LinkedList<TrafficViolation>)bfTrafficViolations.Deserialize(fsTrafficViolations);
                        }
    
                        violation.TrafficViolationNumber = int.Parse(collection["TrafficViolationNumber"]);
    
                        LinkedListNode<TrafficViolation> tv = violations.FindLast(violation);
    
                        ViewBag.TrafficViolationNumber = collection["TrafficViolationNumber"];
                        ViewBag.CameraNumber = tv.Value.CameraNumber;
                        ViewBag.TagNumber = tv.Value.TagNumber;
                        ViewBag.ViolationName = tv.Value.ViolationName;
                        ViewBag.ViolationDate = tv.Value.ViolationDate;
                        ViewBag.ViolationTime = tv.Value.ViolationTime;
                        ViewBag.PhotoAvailable = tv.Value.PhotoAvailable;
                        ViewBag.VideoAvailable = tv.Value.VideoAvailable;
                        ViewBag.PaymentDueDate = tv.Value.PaymentDueDate;
                        ViewBag.PaymentDate = tv.Value.PaymentDate;
                        ViewBag.PaymentAmount = tv.Value.PaymentAmount;
                        ViewBag.PaymentStatus = tv.Value.PaymentStatus;
                    }
                }
    
                return View();
            }
    
            // GET: TrafficViolations/Delete/
            public ActionResult Delete()
            {
                return View();
            }
    
            // POST: TrafficViolations/Delete/
            [HttpPost]
            public ActionResult Delete(FormCollection collection)
            {
                try
                {
                    FileStream fsTrafficViolations = null;
                    TrafficViolation violation = new TrafficViolation();
                    BinaryFormatter bfTrafficViolations = new BinaryFormatter();
                    LinkedList<TrafficViolation> violations = new LinkedList<TrafficViolation>();
                    string strTrafficViolationsFile = Server.MapPath("~/App_Data/TrafficViolations.tts");
    
                    if (!string.IsNullOrEmpty("TrafficViolationNumber"))
                    {
                        if (System.IO.File.Exists(strTrafficViolationsFile))
                        {
                            using (fsTrafficViolations = new FileStream(strTrafficViolationsFile, FileMode.Open, FileAccess.Read, FileShare.Read))
                            {
                                violations = (LinkedList<TrafficViolation>)bfTrafficViolations.Deserialize(fsTrafficViolations);
                            }
                        }
    
                        if (violations.Count > 0)
                        {
                            violation.TrafficViolationNumber = int.Parse(collection["TrafficViolationNumber"]);
    
                            LinkedListNode<TrafficViolation> tv = violations.FindLast(violation);
    
                            violations.Remove(violation);
    
                            using (fsTrafficViolations = new FileStream(strTrafficViolationsFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                            {
                                bfTrafficViolations.Serialize(fsTrafficViolations, violations);
                            }
                        }
                    }
    
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
        }
    }
  12. In the class, right-click PrepareDelete -> Add View...
  13. Make sure the View Name text box is displaying PrepareDelete.
    Click Add
  14. Create the form as follows:
    @model TrafficTicketsSystem1.Models.TrafficViolation
    
    @{
        ViewBag.Title = "Prepare Traffic Violation Delete";
    }
    
    <h2 class="bold common-font maroon text-center">Prepare to Delete Traffic Violation</h2>
    
    <hr />
    
    @using (Html.BeginForm("ConfirmDelete", "TrafficViolations", FormMethod.Post))
    {
        @Html.AntiForgeryToken()
    
        <div class="large-content">
            <div class="form-horizontal common-font">
                @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                <div class="form-group">
                    @Html.LabelFor(model => model.TrafficViolationNumber, htmlAttributes: new { @class = "control-label col-md-4 maroon" })
                    <div class="col-md-4">
                        @Html.EditorFor(model => model.TrafficViolationNumber, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.TrafficViolationNumber, "", new { @class = "text-danger" })
                    </div>
                    <div class="col-md-4">
                        <p><input type="submit" value="Find Traffic Violation" class="btn btn-warning" /></p>
                    </div>
                </div>
            </div>
        </div>
    }
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Traffic Violations", "Index") ::
        @Html.ActionLink("Process a New Traffic Violation", "Create") ::
        @Html.ActionLink("Review a Traffic Violation", "Details") ::
        @Html.ActionLink("Edit/Update a Traffic Violation", "PrepareEdit") ::
        @Html.ActionLink("Prepare/Review a Citation", "PrepareCitation")</p>
  15. In the Solution Explorer, under Views, right-click TrafficViolations -> Add -> View...
  16. Type ConfirmDeletion as the View Name
  17. Click OK
  18. Create a form as follows:
    @{
        ViewBag.Title = "Confirm Traffic Violation Delete";
    }
    
    <h2 class="common-font bold maroon text-center">Confirm Traffic Violation Delete</h2>
    
    <hr />
    
    @using (Html.BeginForm("Delete", "TrafficViolations", FormMethod.Post))
    {
        <div class="large-content">
            <div class="form-horizontal common-font">
                @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                <div class="form-group">
                    <label for="tvn" class="control-label col-md-5 maroon">Traffic Violation #</label>
                    <div class="col-md-7">
                        @Html.TextBox("TrafficViolationNumber", @ViewBag.TrafficViolationNumber as string, htmlAttributes: new { @class = "form-control", id = "tvn" })
                    </div>
                </div>
                <div class="form-group">
                    <label for="cmrNbr" class="control-label col-md-5 maroon">Camera #</label>
                    <div class="col-md-7">@Html.TextBox("CameraNumber", @ViewBag.CamerasNumbers as string, htmlAttributes: new { @class = "form-control", id = "cmrNbr" })</div>
                </div>
                <div class="form-group">
                    <label for="tagNbr" class="control-label col-md-5 maroon">Tag #</label>
                    <div class="col-md-7">@Html.TextBox("TagNumber", @ViewBag.TagNumber as string, htmlAttributes: new { @class = "form-control", id = "tagNbr" })</div>
                </div>
                <div class="form-group">
                    <label for="vType" class="control-label col-md-5 maroon">Violation Type</label>
                    <div class="col-md-7">@Html.TextBox("ViolationName", @ViewBag.ViolationsNames as string, htmlAttributes: new { @class = "form-control", id = "vType" })</div>
                </div>
                <div class="form-group">
                    <label for="vDate" class="control-label col-md-5 maroon">Violation Date</label>
                    <div class="col-md-7">@Html.TextBox("ViolationDate", @ViewBag.ViolationDate as string, htmlAttributes: new { @class = "form-control", id = "vDate" })</div>
                </div>
                <div class="form-group">
                    <label for="vTime" class="control-label col-md-5 maroon">Violation Time</label>
                    <div class="col-md-7">@Html.TextBox("ViolationTime", @ViewBag.ViolationTime as string, htmlAttributes: new { @class = "form-control", id = "vTime" })</div>
                </div>
                <div class="form-group">
                    <label for="photo" class="control-label col-md-5 maroon">Photo Available</label>
                    <div class="col-md-7">@Html.TextBox("PhotoAvailable", @ViewBag.PhotosAvailable as string, htmlAttributes: new { @class = "form-control", id = "photo" })</div>
                </div>
                <div class="form-group">
                    <label for="video" class="control-label col-md-5 maroon">Video Available</label>
                    <div class="col-md-7">@Html.TextBox("VideoAvailable", @ViewBag.VideosAvailable as string, htmlAttributes: new { @class = "form-control", id = "video" })</div>
                </div>
                <div class="form-group">
                    <label for="pdd" class="control-label col-md-5 maroon">Payment Due Date</label>
                    <div class="col-md-7">@Html.TextBox("PaymentDueDate", @ViewBag.PaymentDueDate as string, htmlAttributes: new { @class = "form-control", id = "pdd" })</div>
                </div>
                <div class="form-group">
                    <label for="pmtDate" class="control-label col-md-5 maroon">Payment Date</label>
                    <div class="col-md-7">@Html.TextBox("PaymentDate", @ViewBag.PaymentDate as string, htmlAttributes: new { @class = "form-control", id = "pmtDate" })</div>
                </div>
                <div class="form-group">
                    <label for="pmtAmount" class="control-label col-md-5 maroon">Payment Amount</label>
                    <div class="col-md-7">@Html.TextBox("PaymentAmount", @ViewBag.PaymentAmount as string, htmlAttributes: new { @class = "form-control", id = "pmtAmount" })</div>
                </div>
                <div class="form-group">
                    <label for="pmtStatus" class="control-label col-md-5 maroon">Payment Status</label>
                    <div class="col-md-7">@Html.TextBox("PaymentStatus", @ViewBag.PaymentsStatus as string, htmlAttributes: new { @class = "form-control", id = "pmtStatus" })</div>
                </div>
            </div>
        </div>
    
        <hr />
    
        <div class="form-group">
            <label class="col-md-6 control-label"></label>
            <div class="col-md-6">
                <p><input type="submit" value="Delete this Traffic Violation" class="btn btn-warning" /></p>
            </div>
        </div>
    }
    
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Traffic Violations", "Index") ::
        @Html.ActionLink("Process/Create a Traffic Violation", "Create") ::
        @Html.ActionLink("Edit/Update a Traffic Violation", "PrepareEdit") ::
        @Html.ActionLink("Delete/Remove a Traffic Violation", "PrepareDelete") ::
        @Html.ActionLink("Create/Review a Traffic Citation", "PrepareCitation")</p>
  19. In the Solution Explorer, under Home, expand Shared and double-click _Layout.cshtml
  20. Change the document as follows:
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Traffic Tickets System :: @ViewBag.Title</title>
        @Styles.Render("~/Content/css")
        @Scripts.Render("~/bundles/modernizr")
    </head>
    <body>
        <div class="navbar-top-fixed">
            <div class="row">
                <div class="col-md-3" style="background-color: rgb(133, 17, 0); height: 6.15em"></div>
                <div class="col-md-6" style="background-image: url(/Images/tts1.png); height: 6.15em"></div>
                <div class="col-md-3" style="background-image: url(/Images/tts2.png); height: 6.15em"></div>
            </div>
        </div>
    
        <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 TICKETS SYSTEM", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
                </div>
                <div class="navbar-collapse collapse">
                    <ul class="nav navbar-nav">
                        <li>@Html.ActionLink("CAMERAS", "Index", "Cameras")</li>
                        <li>@Html.ActionLink("DRIVERS", "Index", "Drivers")</li>
                        <li>@Html.ActionLink("VEHICLES", "Index", "Vehicles")</li>
                        <li>@Html.ActionLink("VIOLATIONS TYPES", "Index", "ViolationsTypes")</li>
                        <li>@Html.ActionLink("TRAFFIC VIOLATIONS", "Index", "TrafficViolations")</li>
                        <li>@Html.ActionLink("ABOUT US", "About", "Home")</li>
                        <li>@Html.ActionLink("CONTACT TTS", "Contact", "Home")</li>
                    </ul>
                </div>
            </div>
        </div>
        <div class="container body-content push-down">
            @RenderBody()
    
            <footer>
                <div class="row">
                    <div class="col-md-3">
                        <div class="bottom-title">LOCAL GOVERNMENTS</div>
                        <ul>
                            <li>@Html.ActionLink("Chesterworth County", "Index", "Home", htmlAttributes: new { @class = "bottom-lead" })</li>
                            <li>@Html.ActionLink("Ramses County", "Index", "Home", htmlAttributes: new { @class = "bottom-lead" })</li>
                            <li>@Html.ActionLink("Peyton County", "Index", "Home", htmlAttributes: new { @class = "bottom-lead" })</li>
                            <li>@Html.ActionLink("Clarendon County", "Index", "Home", htmlAttributes: new { @class = "bottom-lead" })</li>
                        </ul>
                    </div>
                    <div class="col-md-3">
                        <div class="bottom-title">CITY HALL</div>
                        <ul>
                            <li>@Html.ActionLink("Office of the Mayor", "Index", "Home", htmlAttributes: new { @class = "bottom-lead" })</li>
                            <li>@Html.ActionLink("Human Resources", "Index", "Home", htmlAttributes: new { @class = "bottom-lead" })</li>
                            <li>@Html.ActionLink("County Executive", "Index", "Home", htmlAttributes: new { @class = "bottom-lead" })</li>
                            <li>@Html.ActionLink("State Governor", "Index", "Home", htmlAttributes: new { @class = "bottom-lead" })</li>
                        </ul>
                    </div>
                    <div class="col-md-3">
                        <div class="bottom-title">PUBLIC SERVICES</div>
                        <ul>
                            <li>@Html.ActionLink("Laymans Library", "Index", "Home", htmlAttributes: new { @class = "bottom-lead" })</li>
                            <li>@Html.ActionLink("Entertainment", "Index", "Home", htmlAttributes: new { @class = "bottom-lead" })</li>
                            <li>@Html.ActionLink("Weekend Programs", "Index", "Home", htmlAttributes: new { @class = "bottom-lead" })</li>
                            <li>@Html.ActionLink("Kids/Teens Info", "Index", "Home", htmlAttributes: new { @class = "bottom-lead" })</li>
                        </ul>
                    </div>
                    <div class="col-md-3">
                        <div class="bottom-title">MISCELLANEOUS</div>
                        <ul>
                            <li>@Html.ActionLink("Labor/Regulations", "Index", "Home", htmlAttributes: new { @class = "bottom-lead" })</li>
                            <li>@Html.ActionLink("Taxes Information", "Index", "Home", htmlAttributes: new { @class = "bottom-lead" })</li>
                            <li>@Html.ActionLink("Seasonals/Weather", "Index", "Home", htmlAttributes: new { @class = "bottom-lead" })</li>
                            <li>@Html.ActionLink("Education", "Index", "Home", htmlAttributes: new { @class = "bottom-lead" })</li>
                        </ul>
                    </div>
                </div>
                <hr />
                <p class="text-center common-font yellow">&copy; @DateTime.Now.Year - Traffic Tickets System</p>
    
            </footer>
        </div>
    
        @Scripts.Render("~/bundles/jquery")
        @Scripts.Render("~/bundles/bootstrap")
        @RenderSection("scripts", required: false)
    </body>
    </html>
  21. In the Solution Explorer, under Views, expand Home
  22. Under Home, double-click Index.cshtml and change it as follows:
    @{
        ViewBag.Title = "Welcoome to TTS";
    }
    
    <div class="row">
        <div class="col-md-20">
            <div class="management">
                <br />
                <div class="box-title yellow">MANAGEMENT</div>
                <ul>
                    <li>@Html.ActionLink("Public Relations", "Index", "Home", htmlAttributes: new { @class = "manage-lead" })</li>
                    <li>@Html.ActionLink("Districts/Precincts", "Index", "Home", htmlAttributes: new { @class = "manage-lead" })</li>
                    <li>@Html.ActionLink("Crime Statistics", "Index", "Home", htmlAttributes: new { @class = "manage-lead" })</li>
                    <li>@Html.ActionLink("Neighborhood Watch", "Index", "Home", htmlAttributes: new { @class = "manage-lead" })</li>
                    <li>@Html.ActionLink("Social Calendar", "Index", "Home", htmlAttributes: new { @class = "manage-lead" })</li>
                    <li>@Html.ActionLink("Careers", "Index", "Home", htmlAttributes: new { @class = "manage-lead" })</li>
                    <li>@Html.ActionLink("Volunteers", "Index", "Home", htmlAttributes: new { @class = "manage-lead" })</li>
                    <li>@Html.ActionLink("Internal Affairs", "Index", "Home", htmlAttributes: new { @class = "manage-lead" })</li>
                    <li>@Html.ActionLink("Stress Management", "Index", "Home", htmlAttributes: new { @class = "manage-lead" })</li>
                    <li>@Html.ActionLink("Patrol Services", "Index", "Home", htmlAttributes: new { @class = "manage-lead" })</li>
                    <li>@Html.ActionLink("Field Services", "Index", "Home", htmlAttributes: new { @class = "manage-lead" })</li>
                    <li>@Html.ActionLink("Investigations", "Index", "Home", htmlAttributes: new { @class = "manage-lead" })</li>
                    <li>@Html.ActionLink("Communities", "Index", "Home", htmlAttributes: new { @class = "manage-lead" })</li>
                    <li>@Html.ActionLink("Forms & Fees", "Index", "Home", htmlAttributes: new { @class = "manage-lead" })</li>
                    <li>@Html.ActionLink("Press Releases", "Index", "Home", htmlAttributes: new { @class = "manage-lead" })</li>
                </ul>
                <hr />
            </div>
    
        </div>
        <div class="col-md-60">
            <div class="text-center">
                <img src="~/Images/tts3.png" class="bordered" />
            </div>
            <div>
                <p class="lead">The Solomon County Police Department is a division of the Solomon County government. This department is proud to insure the safety, security, and wellbeing of both our citizens and our visitors.</p>
    
                <div class="row">
                    <div class="col-md-30 while-box">
                        <h2>Government</h2>
                        <p>Citizens and visitors can get more information about the available services and duties.</p>
                    </div>
                    <div class="col-md-30 while-box">
                        <h2>Community</h2>
                        <p>Here you can find more information about public parks (recreatiional parks, etc).</p>
                    </div>
                    <div class="col-md-30 while-box">
                        <h2>Relations</h2>
                        <p>Here is information about our activities, how we operate, and our future projects.</p>
                    </div>
                </div>
            </div>
        </div>
        <div class="col-md-20">
            <div class="management">
                <br />
                <div class="box-title yellow">USEFUL INFO</div>
                <ul>
                    <li>@Html.ActionLink("Questions/Help", "Index", "Home", htmlAttributes: new { @class = "manage-lead" })</li>
                    <li>@Html.ActionLink("News and Events", "Index", "Home", htmlAttributes: new { @class = "manage-lead" })</li>
                    <li>@Html.ActionLink("Safety Tips", "Index", "Home", htmlAttributes: new { @class = "manage-lead" })</li>
                    <li>@Html.ActionLink("Knowledge Base", "Index", "Home", htmlAttributes: new { @class = "manage-lead" })</li>
                    <li>@Html.ActionLink("Interships", "Index", "Home", htmlAttributes: new { @class = "manage-lead" })</li>
                </ul>
                <br />
            </div>
            <div>
                <br />
                <img src="~/Images/tts4.png" />
                <br />
            </div>
        </div>
    </div>
    
    <br />
  23. To execute, on the main menu, click Debug -> Start Without Debugging

    Linked Lists - Traffic Tickets Management

  24. Click the VIOLATIONS TYPES link:

    Linked Lists - Getting Each Node of a Linked List

  25. On the webpage, click Create New Violation Type:

    Linked Lists - Getting Each Node of a Linked List

  26. Enter the following values:
    Violation Name: Speed
    Description:    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).

    Linked Lists

  27. Click Save this Violation Type
  28. In the same way, create the following records:

    Violation Name Description
    Stop Sign 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.
    Red Light Steady 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.
    Red Light Flashing 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 vehicle must first stop complete, the drive must observe around for pedestrians, animals, and other cars, and then cautiously.
    Red Light Right Turn 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.

    Linked Lists - Getting Each Node of a Linked List

  29. Click the Description of a Violation Type link:

  30. In the Violation Name text box, type Speed
  31. Click the Find button

    Label

  32. Click the CAMERAS link

    Linked Lists - Cameras - Index

  33. Click Create New Camera:

    Label

  34. Create a few records as follows:

    Camera # Make Model Location
    DGH-38460 Ashton Digital MPH-6000 Eastern Ave and Ashburry Drv
    ELQ-79284 Seaside International BL5 Monroe Str and Westview Rd
    MSR-59575 Ashton Digital MPH-6000 Concordia Blvd and Sunset Way
    DHT-29417 Woodson and Sons NG200 Temple Ave and Barclay Rd
    AHR-41518 Seaside International 442i Chesterwood Rd and Old Dutler Str
    HTR-93847 Ashton Digital 366d Monrovia Str at Moon Springs

    Label

  35. Click the DRIVERS link:

    Linked List - Traffic Tickets System - Drivers

  36. Click Issue New Driver's License:

    Text Box

  37. Create a few records as follows:

    Drv. Lic. # First Name Last Name Address City County State ZIP Code
    296 840 681 Simon Havers 1884 Stewart Ln Kittanning Armstrong PA 15638
    273-79-4157 Terrence McConnell 8304 Polland Str Meadowview Washington VA 24361
    A402-630-468 Patrick Atherton 10744 Quincy Blvd Cumberland Allegany MD 21502
    C-684-394-527 Sarah Cuchran 10804 Euton Rd Shawnee Land   VA 24450
    72938468 Victoria Huband 3958 Lubber Court Middletown New Castle DE 19709
    E-928-374-025 Jeannette Eubanks 794 Arrowhead Ave Vienna Dorchester MD 21869
    851608526 Patrick Whalley 10227 Woodrow Rd Shelbyville Bedford TN 38561
    593 804 597 George Higgins 884 Willingmont Drv Krumsville Berks PA 19530
    W639-285-940 David Woodbank 9703 Abington Ave Hurlock Dorchester MD 21643
    S-283-942-646 Emilie Sainsbury 4048 Utah Rd Denville Morris NJ 07961
    860586175 Kelly Murray 8622 Rutger Farms Str Rutger Farms Macon TN 37122

    Label

  38. Click the VEHICLES link:

    Linked Lists - Traffic Tickets Violations

  39. Click Register New Vehicle:

    Linked Lists - Vehicles

  40. Register a few vehicles using the following values:

    Tag # Drv. Lic. # Make Model Year Color
    8DE9275 296 840 681 Ford Focus SF 2000 Gray
    KLT4805 593 804 597 Toyota Corolla LE 2016 Maroon
    5293WPL C-684-394-527 Ford Transit Connect 2018 Navy
    FKEWKR 72938468 Toyota Camry 2010 Silver
    MKR9374 273-79-4157 Lincoln MKT 2018 Black
    KAS9314 W639-285-940 Cadillac Escalade 2008 Cream
    HAK3936 S-283-942-646 Chrysler Crossfire 2006 Red
    PER2849 26 840 681 Buick LeSabre 2012 Silver
    MWH4685 851608526 Honda Accord 1998 Blue
    971384 E-928-374-025 BMW 325i 2015 Navy
    394815 273-79-4157 Jeep Wrangler Sahara 1996 Black

    Linked List - Traffic Tickets System - Vehicles

  41. Click the TRAFFIC VIOLATIONS link:

    Linked Lists - Traffic Tickets System - Traffic Violations

  42. Click the Process a New Traffic Violation link:

    Linked Lists - Traffic Tickets System - Traffic Violations

  43. Add a few records as follows:
     
    Camera # Tag # Violation Type Violation Date Violation Time Photo Available Video Available Pmt Due Date Pmt Date Pmt Amt Pmt Status
    MSR-59575 KLT4805 Stop Sign 01/18/2018 09:12:35 No Yes 02/28/2018   75 Pending
    DHT-29417 971384 Speed 02/06/2018 11:58:06 No Yes 04/05/2018   85 Pending
    DGH-38460 PER2849 Red Light Steady 01/31/2018 05:15:18 Yes No 03/10/2018   125 Pending
    DHT-29417 FKEWKR Speed 03/05/2018 16:07:15 Yes Yes 04/22/2018   85 Pending
    MSR-59575 8DE9275 Stop Sign 01/18/2018 14:22:48 No Yes 03/10/2018   60 Pending
    ELQ-79284 KLT4805 Speed 04-12-2018 08:16:22 No Yes 06-08-2018   100 Pending
    HTR-93847 PER2849 Red Light Flashing 01/28/2018 22:14:53 No No 03/02/2018   45 Pending
    AHR-41518 MWH4685 Speed 03-31-2018 22:07:31 Yes No 05/15/2018   75 Pending
    DGH-38460 KAS9314 Red Light Right Turn 01-31-2018 12:30:11 Yes No 02-28-2018   60 Pending
    DHT-29417 971384 Speed 02/06/2018 19:04:47 Yes Yes 04-05-2018   85 Pending
    ELQ-79284 8DE9275 Speed 04-15-2018 15:25:53 Yes No 06/02/2018   40 Pending

    Linked Lists - Traffic Tickets System - Traffic Violations

  44. Click the Edit link for the record to change the payment dates, amounts, and status as follows:
     
    Camera # Tag # Violation Type Violation Date Violation Time Photo Available Video Available Pmt Due Date Pmt Date Pmt Amt Pmt Status
    MSR-59575 KLT4805 Stop Sign 01/18/2018 09:12:35 Yes Yes 02/28/2018 02-27-2018 75 Paid On Time
    DHT-29417 971384 Speed 02/06/2018 11:58:06 No Yes 04/05/2018 03/31/2018 85 Paid On Time
    DGH-38460 PER2849 Red Light Steady 01/31/2018 05:15:18 Yes No 03/10/2018   125 Pending
    DHT-29417 FKEWKR Speed 03/05/2018 16:07:15 No Yes 04/22/2018 04/15/2018 85 Paid On Time
    MSR-59575 8DE9275 Stop Sign 01/18/2018 14:22:48 No Yes 03/10/2018 03/27/2018 90 Paid Late
    ELQ-79284 KLT4805 Speed 04/12/2018 08:16:22 No Yes 06/08/2018   100 Cancelled
    HTR-93847 PER2849 Red Light Flashing 01/28/2018 22:14:53 No No 03/02/2018 03-01-2018 45 Rejected
    AHR-41518 MWH4685 Speed 03/31/2018 22:07:31 Yes No 05/15/2018   75 Pending
    DGH-38460 KAS9314 Red Light Right Turn 01/31/2018 12:30:11 Yes No 02-28-2018 04-02-2018 90 Paid Late
    DHT-29417 971384 Speed 02/06/2018 19:04:47 No Yes 04-05-2018 03-31-2018 85 Paid On Time
    ELQ-79284 8DE9275 Speed 04/15/2018 15:25:53 Yes No 06/02/2018   40 Pending

    Linked Lists - Traffic Tickets System - Traffic Violations

  45. Click Prepare/Review a Citation:

    Linked Lists - Traffic Tickets System - Traffic Violations

  46. Type a traffic violation number. Here is an example:

    Linked Lists - Traffic Tickets System - Traffic Violations

  47. Click Find Traffic Violation:

    Linked Lists - Traffic Tickets System - Traffic Violations

  48. Close the browser and return to your programming environment

Clearing a Linked List

Clearing a list consists of deleting all of its item. To do this, you could continuous call one of the versions of the Remove() method. A faster solution is to call the Clear() method. Its syntax is:

public void Clear();

Here is an example:

<!DOCTYPE html>
<html>
<head>
<title>Numbers</title>
</head>
<body>
<h2>Numbers</h2>

@{
    List<double> values = new List<double>();
    values.Add(84.597);
    values.Add(6.47);
    values.Add(2747.06);
    values.Add(282.924);

    LinkedList<double> numbers = new LinkedList<double>(values);
    LinkedListNode<double> number = new LinkedListNode<double>(148.24);
    numbers.AddFirst(number);

    numbers.AddLast(18264.86);

    number = new LinkedListNode<double>(35.75);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(2222.06);
    numbers.AddFirst(number);

    LinkedListNode<double> last = new LinkedListNode<double>(827366.993);
    numbers.AddLast(last);

    number = new LinkedListNode<double>(4.19);
    numbers.AddFirst(number);

    number = new LinkedListNode<double>(66.18);
    numbers.AddFirst(number);

    LinkedListNode<double> reference = numbers.Find(148.24);
    numbers.AddBefore(reference, 9999.9999);

    LinkedListNode<double> other = numbers.Find(6.47);
    LinkedListNode<double> before = new LinkedListNode<double>(7777.7777);
    numbers.AddBefore(other, before);

    numbers.Remove(84.597);

    LinkedListNode<double> dismiss = numbers.Find(282.924);
    numbers.Remove(dismiss);

    numbers.Clear();
}

<ul>
    @foreach (double nbr in numbers)
    {
        if ((nbr == 7777.7777) || (nbr == 9999.9999))
        {
            <li style="color: tomato">Number: @nbr</li>
        }
        else if ((nbr == 6.47) || (nbr == 148.24))
        {
            <li style="color: blue">Number: @nbr</li>
        }
        else
        {
            <li>Number: @nbr</li>
        }
    }
</ul>
</body>
</html>

Practical LearningPractical Learning: Ending the Lesson


Previous Copyright © 2004-2019, FunctionX Next