The Web API Controller

Introduction

ASP.NET MVC allows you to combine C#, JavaScript, and any appropriate library to create and maintain a database. This means that you can use AngularJS and Ajax in your Web API website.

Practical LearningPractical Learning: Introducing Databases in Views

  1. Start Microsoft Visual Studio
  2. On the main menu, click File -> New -> Project...
  3. In the New Project dialog box, click ASP.NET Web Application (.NET Framework) and change the project Name to Escape1
  4. Click OK
  5. In the New ASP.NET Web Application dialog box, click the Web API icon and click OK
  6. In the Solution Explorer, right-click Escape1 and click Manage NuGet Packages...
  7. Click the Browser button.
    Do a search on AngularJS (you must be connected to the Internet)
  8. In the list, click angularjs
  9. In the middle-right frame, click Install. If a dialog box comes up, read it and click OK
  10. In the Solution Explorer, right-click Escape1 -> Add -> New Folder
  11. Type BusinessControllers
  12. In the Solution Explorer, expand Views and expand Shared
  13. Double-click _Layout.cshtml to open
  14. Change the document as follows:
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width" />
        <title>ESCAPE :: @ViewBag.Title</title>
        @Styles.Render("~/Content/css")
        @Scripts.Render("~/bundles/modernizr")
    </head>
    <body>
        <div class="navbar navbar-inverse navbar-fixed-top">
            <div class="container">
                <div class="navbar-header">
                    <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>
                    @Html.ActionLink("ESCAPE", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
                </div>
                <div class="navbar-collapse collapse">
                    <ul class="nav navbar-nav">
                        <li>@Html.ActionLink("Home", "Index", "Home", new { area = "" }, null)</li>
                        <li>@Html.ActionLink("Customers", "Index", "Customers", new { area = "" }, null)</li>
                        <li>@Html.ActionLink("Cable Bills", "Index", "CableBills", new { area = "" }, null)</li>
                        <li>@Html.ActionLink("API", "Index", "Help", new { area = "" }, null)</li>
                    </ul>
                </div>
            </div>
        </div>
        <div class="container body-content">
            @RenderBody()
            <hr />
            <footer>
                <p class="text-center">&copy; @DateTime.Now.Year - Eastern Shore Cable and Production Entertainment</p>
            </footer>
        </div>
    
        @Scripts.Render("~/bundles/jquery")
        @Scripts.Render("~/bundles/bootstrap")
        @RenderSection("scripts", required: false)
    </body>
    </html>
  15. If you are using Microsoft SQL Server for your database
    1. Start Microsoft SQL Server and login/connect to the database
    2. In the Object Explorer, right-click the computer name and click New Query
    3. Type the following code:
      USE master;
      GO
      CREATE DATABASE CableDistribution;
      GO
      USE CableDistribution;
      GO
    4. To execute, right-click inside the Code Editor and click Execute
    5. Click inside the Code Editor, press Ctrl + A to select everything, and press Delete
  16. If you are using a local database
    1. In the Solution Explorer of Microsoft Visual Studio, right-click App_Data -> Add -> New Item...
    2. In the left frame of the Add New Item dialog box, click Data. In the middle frame, click SQL Server Database. Change the database Name to CableDistribution
    3. Click Add
    4. In the Solution Explorer, under App_Data, right-click CableDistribution.mdf and click Open
    5. In the Server Explorer, right-click CableDistribution.mdf and click New Query
  17. In both cases (the Query window in either Microsoft SQL Server or Microsoft Visual Studio), type the following code:
    CREATE TABLE Customers
    (
    	CustomerID		    INT IDENTITY(1, 1),
    	AccountNumber	    NVARCHAR(16)	NOT NULL,
    	FirstName		    NVARCHAR(25),
    	LastName		    NVARCHAR(25)	NOT NULL,
    	[Address]		    NVARCHAR(100),
    	City		        NVARCHAR(40)	NOT NULL,
    	County		        NVARCHAR(50),
    	[State]		        NVARCHAR(5)  	NOT NULL,
    	CableTVPackageType	NVARCHAR(25)	DEFAULT N'Basic',
    	CableTVPackageRate	DECIMAL(5, 2)	DEFAULT 0.00,
    	DVRService	        DECIMAL(5, 2)	DEFAULT 0.00,
    	SportsPackages	    DECIMAL(5, 2)	DEFAULT 0.00,
    	StateTaxRate	    DECIMAL(5, 2)	DEFAULT 0.00,
    	StateTaxAmount	    DECIMAL(5, 2)	DEFAULT 0.00,
    	LocalTaxRate	    DECIMAL(5, 2)	DEFAULT 0.00,
    	LocalTaxAmount	    DECIMAL(5, 2)	DEFAULT 0.00,
    	CONSTRAINT PK_Customers PRIMARY KEY(CustomerID)
    );
    GO
    CREATE TABLE CableBills
    (
    	CableBillID		    INT IDENTITY(1, 1) NOT NULL,
    	CustomerID		    INT		           NOT NULL,
    	CableTVPackageType	NVARCHAR(25),
    	TVPackageRate	    DECIMAL(6, 2),
    	DVRService	        DECIMAL(6, 2),
    	SportsPackages	    DECIMAL(6, 2),
    	StateTaxRate	    DECIMAL(6, 2),
    	StateTaxAmount	    DECIMAL(6, 2),
    	LocalTaxRate        DECIMAL(6, 2),
    	LocalTaxAmount      DECIMAL(6, 2),
    	SubTotal	        DECIMAL(6, 2),
    	FCCFee		        DECIMAL(6, 2) DEFAULT 0.00,
    	RightOfWayFee	    DECIMAL(6, 2) DEFAULT 0.00,
    	EnvironmentFee      DECIMAL(6, 2) DEFAULT 0.00,
    	PaymentDueDate      NVARCHAR(50)  NOT NULL,
    	AmountDue	        DECIMAL(5, 2) NOT NULL,
    	PaymentDate   NVARCHAR(50)  NOT NULL,
    	PaymentAmount DECIMAL(6, 2) NOT NULL,
    	CONSTRAINT FK_Customers FOREIGN KEY(CustomerID)
    			REFERENCES Customers(CustomerID),
    	CONSTRAINT PK_CableBills PRIMARY KEY(CableBillID)
    );
    GO
  18. To execute the code and create the tables, right-click inside the Query window and click Execute
  19. Close the Query window
  20. When asked whether you want to save, click No
  21. In the Solution Explorer, right-click Content -> Add -> Style Sheet
  22. Type CableDistribution as the name of the file
  23. Click Add
  24. Change the document as follows:
    body {
        background-color: #fff;
    }
    
    .bold          { font-weight: 600;     }
    .small         { width:       100px;   }
    .medium        { width:       150px;   }
    .large         { width:       175px;   }
    .top-alignment { padding-top: 7px;     }
    .navy          { color:       navy;    }
    .maroon        { color:       #800000; }
    .bill-contents { margin:      auto;
                     width:       800px;   }
    .common-font   { font-family: Georgia, Garamond, 'Times New Roman', serif; }
  25. In the Solution Explorer, right-click Models -> Add -> ADO.NET Entity Data Model
  26. Change the name to CableDistributionModel
  27. Click Add
  28. In the Entity Data Model Wizard, accept the EF Designer From Database

    Entity Data Model Wizard

    Click Next
  29. In the second page of the Entity Data Model Wizard
    • If you created your database in Microsoft SQL Server, click the New Connection button. In the Connection Properties dialog box, click the Change button, click Microsoft SQL Server, and click OK. In the Server Name text, type the name of the server or type (local). In the Select Or Enter A Database Name combo box, select CableDistribution. Click OK.
    • If you created a local database in Microsoft Visual Studio, make sure the top text box displays CableDistribution.mdf
  30. Click Next
  31. In the third page of the Entity Data Model Wizard, make sure Entity Framework 6.x is selected. Click Next
  32. In the fourth page of the Entity Data Model Wizard, click the check box of Tables
  33. Click Finish. If a Security Warning message box keeps coming up, read it and click OK
  34. On the main menu, click Build -> Build Solution

Creating a Web API Controller

To use a database in your Web API project, create a class derived from ApiController, a class to which we were introduced already. To get the class, create a scaffold controller using the Entity Framework.

Practical LearningPractical Learning: Introducing the Web API Controller

  1. In the Solution Explorer, right-click Controllers -> Add -> New Scaffolded Item...
  2. In the left frame of the Add Scaffold dialog box, click Web API
  3. In the middle frame of the dialog box, click Web API 2 Controller With Actions, Using Entity Framework

    Add Scaffold

  4. Click Add
  5. Click the arrow of the Model Class combo box and select Customer (Escape1.Models)
  6. Click the arrow of the Data Context Class and select CableDistributionEntities (Escape1.Models)

    Add Controller

  7. Click Add
  8. In the Solution Explorer, right-click Controllers -> Add -> Controller...
  9. In the Add Scaffold dialog box, click Web API 2 Controller With Actions, Using Entity Framework

    Add Scaffold

  10. Click Add
  11. In the Model Class combo box, select CableBill (Escape1.Models)
  12. In the Data Context Class combo box, make sure CableDistributionEntities (Escape1.Models) is selected and click Add

An AngularJS Controller to the Rescue

AngularJS supports all CRUD (create, read, update, and delete) database operations through its implementation of Ajax and Json. To proceed, use the Entity Framework to create a class that derives from ApiController.

Practical LearningPractical Learning: Introducing AngularJS and Databases

  1. In the Solution Explorer, right-click Scripts -> Add -> JavaScript File
  2. Type CableDistribution
  3. Click OK
  4. Type the following line in the document:
    var appEscape = angular.module('cableDistribution', []);
  5. In the Solution Explorer, right-click BusinessControllers -> Add -> Controller...
  6. In the central frame of the Add Scaffold dialog box, click MVC 5 Controller - Empty
  7. Click Add
  8. Type Customers to get CustomersController
  9. Click Add
  10. In the Solution Explorer, right-click BusinessControllers -> Add -> Controller...
  11. In the middle frame of the Add Scaffold dialog box, make sure MVC 5 Controller - Empty is selected.
    Click Add
  12. Type CableBills to get CableBillsController
  13. Click Add

Creating a Record

Introduction

If you create a controller using the Web API 2 Controller With Actions, Using Entity Framework, Microsoft Visual Studio declares an entity variable in each class. Along with other methods, Microsoft Visual Studio creates an action whose name starts with Post:

. . .

namespace Escape1.Controllers
{
    public class CableBillsController : ApiController
    {
        private CableDistributionEntities db = new CableDistributionEntities();

        . . .

        // POST: api/CableBills
        [ResponseType(typeof(CustomerAccount))]
        public IHttpActionResult GetCustomerAccount(int id)
        {
            CustomerAccount customerAccount = db.CustomerAccounts.Find(id);
            if (customerAccount == null)
            {
                return NotFound();
            }

            return Ok(customerAccount);
        }

        . . .
    }
}

That method contains the code necessary to add a record to the associated table.

Using the HTTP Service

To create a record in AngularJS, you can use the $http service in an AngularJS controller. You can pass an object to it as argument. You have many options.

The object you pass as argument to the $http service must carry the values or objects that will be saved. You can first create an object and then pass it to the service. Here is an example:

var connection = {
            
};
        
$http(connection).then(function () {
                       		. . .
                       },
			           function () {
                			. . .
           			   });

If you are not planning to use the object more than once, you can create it directly in the parentheses of the $http service.

One of the properties of the object, the form method, must have a value as POST. Another property of the object, the url, must specify the path to the entity collection of records. You must also specify the actual values that must be saved. Because we are dealing with an object used in a collection of records (a collection of objects), you can (should/must) provide an object that holds the values. You can first create an object from a var variable, then provide that object as the value of a property named data.

After creating the object for the $http service, in the function/argument that handles the success case of the service, you can call the Array.push() method to add the object to the collection of records. To do this, attach the data property to the argument passed to the function and pass it as argument to the Array.push() method. This could be done as follows

var bill = {
    InvoiceNumber: $scope.invoiceNbr,
    InvoiceAmount: $scope.total };

var connection = {
    method: 'POST',
    url: '../api/CableBills',
    data: bill
};
    
$http(connection).then(function (response) {
    $scope.bills.push(response.data);
    },
    function (response) {
           $scope.error = "Something went wrong";
    }
);

As always, if you are not planning to use an object many times, you can create it directly where it is needed. Here is an example:

$http({
        method: 'POST',
        url: '../api/CableBills',
        data: {
					InvoiceNumber: $scope.invoiceNbr,
				    InvoiceAmount: $scope.total
    		  }
    }).then(function (response) {
        $scope.bills.push(response.data);
            },
            function (response) {
                $scope.error = "Something went wrong";
            }
    );

Practical LearningPractical Learning: Creating a Record

  1. In the Solution Explorer, right-click Scripts -> Add -> JavaScript File
  2. Type CableBillsController
  3. Click OK
  4. In the Solution Explorer, right-click Scripts -> Add -> JavaScript File
  5. Type EditCustomerAccount as the name of the file
  6. Click OK
  7. In the Solution Explorer, right-click Scripts -> Add -> JavaScript File
  8. Type CustomersController
  9. Click OK
  10. In the empty document, type the following code:
    function processCustomers($scope, $http) {
        function resetForm() {
            $scope.acntNbr = "";
            $scope.fName = "";
            $scope.lName = "";
            $scope.adrs = "";
            $scope.ct = "";
            $scope.local = "";
            $scope.state = "";
            $scope.packType = "Basic";
            $scope.packRate = 0.00;
            $scope.dvr = 0.00;
            $scope.sport = 0.00;
            $scope.str = 0.00;
            $scope.sta = 0.00;
            $scope.ltr = 0.00;
            $scope.lta = 0.00;
        }
        $scope.createCustomerAccount = function () {
            var customer = {
                AccountNumber: $scope.acntNbr,
                FirstName: $scope.fName,
                LastName: $scope.lName,
                Address: $scope.adrs,
                City: $scope.ct,
                County: $scope.local,
                State: $scope.state,
                CableTVPackageType: $scope.packType,
                CableTVPackageRate: $scope.packRate,
                DVRService: $scope.dvr,
                SportsPackages: $scope.sport,
                StateTaxRate: $scope.str,
                StateTaxAmount: $scope.sta,
                LocalTaxRate: $scope.ltr,
                LocalTaxAmount: $scope.lta
            };
    
            $http({
                method: 'POST',
                url: '/api/Customers',
                data: customer
            }).
                then(function (response) {
                    $scope.customers.push(response.data);
                },
                    function (response) {
                        $scope.error = "Something went wrong";
                    });
    
            resetForm();
        }
    }
    
    appEscape.controller("CustomersController", ['$scope', '$http', processCustomers]);
  11. In the Solution Explorer, expand App_Start and double-click BundleConfig.cs to open the file
  12. Change the document as follows:
    using System.Web.Optimization;
    
    namespace Escape1
    {
        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",
                            "~/Scripts/angular.js",
                            "~/Scripts/CableDistribution.js",
                            "~/Scripts/CustomersController.js",
                            "~/Scripts/CableBillsController.js"));
    
                // 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/CableDistribution.css"));
            }
        }
    }
  13. In the Solution Explorer, under BusinessControllers, double-click CustomersController to acccess it
  14. Add an ActionResult method named Create as follows:
    using System.Web.Mvc;
    
    namespace Escape1.BusinessControllers
    {
        public class CustomersController : Controller
        {
            // GET: Customers
            public ActionResult Index()
            {
                return View();
            }
    
            // POST: Customers/Create
            public ActionResult Create()
            {
                return View();
            }
        }
    }
  15. In the document, right-click Create() and click Add View...
  16. In the Add View dialog box, make sure the View Name text box displays Create
    Click Add
  17. Change the document as follows:
    @{
        ViewBag.Title = "New Customer Account";
    }
    
    <h2 class="text-center common-font maroon bold">ESCAPE - New Customer Account</h2>
    <hr />
    
    <div ng-app="cableDistribution">
        <div class="bill-contents" ng-controller="CustomersController">
            <form name="CustomerAccount" method="post">
                <table class="tbl common-font">
                    <tr>
                        <td class="col-md-3"><label for="accountNumber" class="top-alignment">Account #:</label></td>
                        <td class="col-md-3"><input type="text" id="accountNumber" class="form-control medium" ng-model="acntNbr" /></td>
                        <td class="col-md-4">&nbsp;</td>
                        <td>&nbsp;</td>
                    </tr>
                    <tr>
                        <td class="col-md-3"><label for="firstName" class="top-alignment">First Name:</label></td>
                        <td class="col-md-3"><input type="text" id="firstName" class="form-control medium" ng-model="fName" /></td>
                        <td class="col-md-4"><label for="lastName" class="top-alignment">Last Name:</label></td>
                        <td><input type="text" id="lastName" class="form-control medium" ng-model="lName" /></td>
                    </tr>
                    <tr>
                        <td class="col-md-3"><label for="address" class="top-alignment">Address:</label></td>
                        <td class="col-md-3"><input type="text" id="Address" class="form-control medium" ng-model="adrs" /></td>
                        <td class="col-md-4"><label for="city" class="top-alignment">City:</label></td>
                        <td><input type="text" id="city" class="form-control medium" ng-model="ct" /></td>
                    </tr>
                    <tr>
                        <td class="col-md-3"><label for="counties" class="top-alignment">County:</label></td>
                        <td class="col-md-3"><input id="counties" class="form-control medium" ng-model="local" /></td>
                        <td class="col-md-4"><label for="state" class="top-alignment">State:</label></td>
                        <td><input id="state" class="form-control medium" ng-model="state" /></td>
                    </tr>
                    <tr>
                        <td class="col-md-3"><label for="cableTVPackage" class="top-alignment">Cable TV Package:</label></td>
                        <td class="col-md-3"><input id="cableTVPackage" class="form-control medium" ng-model="packType" /></td>
                        <td class="col-md-4"><label for="packageRate" class="top-alignment">Package Rate:</label></td>
                        <td><input id="packageRate" class="form-control medium" ng-model="packRate" /></td>
                    </tr>
                    <tr>
                        <td class="col-md-3"><label for="DVRService" class="top-alignment">DVR Service:</label></td>
                        <td class="col-md-3"><input type="number" id="DVRService" class="form-control medium" ng-model="dvr" /></td>
                        <td class="col-md-4"><label for="sportsPackages" class="top-alignment">Sports Packages:</label></td>
                        <td><input type="number" id="sportsPackages" class="form-control medium" ng-model="sport" /></td>
                    </tr>
                    <tr>
                        <td class="col-md-3"><label for="stateTaxRate" class="top-alignment">State Tax Rate:</label></td>
                        <td class="col-md-3"><input id="stateTaxRate" class="form-control medium" ng-model="str" /></td>
                        <td class="col-md-4"><label id="stateTaxAmount" class="top-alignment">State Tax Amt:</label></td>
                        <td><input id="stateTaxAmount" class="form-control medium" ng-model="sta" /></td>
                    </tr>
                    <tr>
                        <td class="col-md-3"><label for="localTaxRate" class="top-alignment">Local Tax Rate:</label></td>
                        <td class="col-md-3"><input id="localTaxRate" class="form-control medium" ng-model="ltr" /></td>
                        <td class="col-md-4"><label for="localTaxAmount" class="top-alignment">Local Tax Amt:</label></td>
                        <td><input id="localTaxAmount" class="form-control medium" ng-model="lta" /></td>
                    </tr>
                </table>
                <hr />
                <p class="text-center">
                    <input type="button" name="btnSaveCustomerAccount"
                           class="btn btn-primary" value="Save Customer Account" ng-click="createCustomerAccount()" />
                </p>
            </form>
        </div>
        <hr />
    
        <p class="text-center">
            @Html.ActionLink("Customers Accounts", "Index", "Customers", new { area = "" }, null) ::
            @Html.ActionLink("Customer Account Details", "Get", "Customers", new { area = "" }, null) ::
            @Html.ActionLink("Edit/Update a Customer's Account", "Update", "Customers", new { area = "" }, null) ::
            @Html.ActionLink("Delete a Customer's Account", "Delete", "Customers", new { area = "" }, null)
        </p>
    </div>
  18. To execute the application, press Ctrl + F5:

    Web API - Creating a Record

  19. To prepare a record, enter the following values in the text boxes:
    Account #:        162-38507-480
    First Name:       Henry
    Last Name:        Guggens
    Address:          11402 Edmonson Drv
    City:             Silver Spring
    County:           Montgomery
    State:            MD
    Cable TV Package: Performance		
    Package Rate:     32.28
    DVR Service:      4.95
    Sports Packages:  8.95
    State Tax Rate:   5.36
    State Tax Amount: 2.48
    Local Tax Rate:   7.44
    Local Tax Amount: 3.44
  20. Click the Save Customer Account button
  21. To create another record, enter the following values in the text boxes or select from combo boxes:
    Account #:        572-85304-755
    First Name:       Patricia
    Last Name:        Healey
    Address:          3997 Ghost Effect Str
    City:             Hedgesville
    County:           Berkeley
    State:            WV
    Cable TV Package: Basic		
    Package Rate:     18.72
    DVR Service:      0
    Sports Packages:  0
    State Tax Rate:   7.28
    State Tax Amount: 1.36
    Local Tax Rate:   8.36
    Local Tax Amount: 1.56
  22. Click the Save Customer Account button
  23. To create another record, enter the following values in the text boxes or select from combo boxes:
    Account #:          315-83064-962
    First Name:         Martha
    Last Name:          Thiel
    Address:            7284 Woorhies Ave
    City:               Alexandria
    State:              VA
    Cable TV Package:   Basic		
    Package Rate:       24.57
    DVR Service:        0
    Sports Packages:    12.45
    State Tax Rate:     6.82
    State Tax Amount:   2.81
    Local Tax Rate:     5.59
    Local Tax Amount:   2.30
  24. Click the Save Customer Account button
  25. To create another record, enter the following values in the text boxes or select from combo boxes:
    Account #:          850-28503-714
    First Name:         Paul
    Last Name:          Harland
    Address:            552 Sunny Tape Rd
    City:               College Park
    County:             Prince George
    State:              MD
    Cable TV Package:   Standard
    Package Rate:       26.68
    DVR Service:        7.85
    Sports Packages:    14.45
    State Tax Rate:     5.36
    State Tax Amount:   2.41
    Local Tax Rate:     8.27
    Local Tax Amount:   3.71
  26. Click the Save Customer Account button
  27. Close the browser and return to your programming environment

A Shorcut of the HTTP Service

In previous lessons, we saw that the $http service provides shortcuts to its operations. Instead of creating a POST-based operation to pass to the service, you can call its post() method. Pass two arguments to the method. The first argument is the URL of the POST path. The second argument is the object to add to the collection of records.

Practical LearningPractical Learning: Using an HTTP Service Shorcut

  1. In the Solution Explorer, under Scripts, double-click CableBillsController to access it
  2. In the empty document, type the following code:
    function processCableBills($scope, $http) {
        $scope.createCableBill = function () {
            var bill = {
                AccountNumber: $scope.acntNbr
            };
    
            $http.post('/api/CableBills', bill).
                then(function (response) {
                    $scope.bills.push(bill);
                },
                    function (response) {
                        $scope.error = "Something went wrong";
                    });
        }
    }
    
    appEscape.controller("CableBillsController", ['$scope', '$http', processCableBills]);

Viewing Records

Reading all Records

One of the CRUP operations of a database consists of using or opening a document that can display all records. If you create a controller using the Web API 2 Controller With Actions, Using Entity Framework, Microsoft Visual Studio creates a method whose name starts with Get. That method produces all of the records of the table associated with the controller class. You can access the related records in your AngularJS controller to view the records. To do this, use the $http service with the GET form method.

Practical LearningPractical Learning: Reading Records

  1. In the Solution Explorer, under Scripts, double-click CustomersController.js to access it
  2. Change the document as follows:
    function processCustomers($scope, $http) {
        
        . . .
    
        // Get All Customers
        $http({
            method: 'GET',
            url: '/api/Customers'
        }).
            then(function (response) {
                $scope.customers = response.data;
            },
                function (response) {
                    $scope.error = "Something went wrong when trying to get the list of customers";
                }
            );
    }
    
    appEscape.controller("CustomersController", ['$scope', '$http', processCustomers]);
  3. In the Solution Explorer, under BusinessControllers, double-click CustomersController.cs to access it
  4. In the document, right-click Index() and click Add View...
  5. In the Add View dialog box, make sure the View Name text box is displaying Index. Click Add
  6. Change the document as follows:
    @{
        ViewBag.Title = "Eastern Shore Cable and Production Entertainment - Customers Accounts";
    }
    
    <h2 class="text-center common-font bold maroon">Eastern Shore Cable and Production Entertainment</h2>
    <h2 class="text-center common-font bold navy">Customers Accounts</h2>
    
    <div ng-app="cableDistribution">
        <table class="table table-striped common-font" ng-controller="CustomersController">
            <tr>
                <td><b>Acnt ID</b></td>
                <td><b>Account #</b></td>
                <td><b>First Name</b></td>
                <td><b>Last Name</b></td>
                <td><b>Address</b></td>
                <td><b>City</b></td>
                <td><b>County</b></td>
                <td><b>State</b></td>
                <td><b>Cable TV Type</b></td>
                <td><b>Cable TV Rate</b></td>
                <td><b>DVR Service</b></td>
                <td><b>Sports Packages</b></td>
                <td><b>State Tax Rate</b></td>
                <td><b>State Tax Amount</b></td>
                <td><b>Local Tax Rate</b></td>
                <td><b>Local Tax Amount</b></td>
            </tr>
            <tr ng-repeat="client in customers">
                <td>{{client.CustomerID}}</td>
                <td>{{client.AccountNumber}}</td>
                <td>{{client.FirstName}}</td>
                <td>{{client.LastName}}</td>
                <td>{{client.Address}}</td>
                <td>{{client.City}}</td>
                <td>{{client.County}}</td>
                <td>{{client.State}}</td>
                <td>{{client.CableTVPackageType}}</td>
                <td>{{client.CableTVPackageRate}}</td>
                <td>{{client.DVRService}}</td>
                <td>{{client.SportsPackages}}</td>
                <td>{{client.StateTaxRate}}</td>
                <td>{{client.StateTaxAmount}}</td>
                <td>{{client.LocalTaxRate}}</td>
                <td>{{client.LocalTaxAmount}}</td>
            </tr>
        </table>
        <hr />
    </div>
    
    <p class="text-center">
        @Html.ActionLink("Review Customer Account", "Get", "Customers", new { area = "" }, null) ::
        @Html.ActionLink("Create a New Customer Account", "Create", "Customers", new { area = "" }, null)
        @Html.ActionLink("Edit/Update a Customer's Account", "Update", "Customers", new { area = "" }, null) ::
        @Html.ActionLink("Delete a Customer's Account", "Delete", "Customers", new { area = "" }, null)
    </p>
  7. To execute the application, press Ctrl + F5:

    Practical Learning

  8. Close the browser and return to your programming environment

A Shortcut to Get the HTTP Service

Instead of passing an object to $http, the service provides a shortcut as $http.get(). The method takes one argument as the path to the collection of records. The rest of the service follows the same logic as done above. Here is an example:

function read($scope, $http) {
    $http.get('/api/CableBills').
        then(function (response) {
            $scope.bills = response.data;
        },
        function (response) {
            $scope.error = "Something went wrong";
        });
}

appEscape.controller("BillsController", ['$scope', '$http', read]);

Selecting a Record

Sometimes you want to see the details of one particular Record. Once again, you have many options. In all cases, you need a value that can identify the particular record you want to open. Normally, that value would come from the primary key of the original table,, which justifies the reason the primary key should (must) also hold unique values. Therefore, to select a record, you must provide a value for the primary key.

You can start from the code we saw that you can use to get and display all of the records of a collection. This time, provide the record identification to the $http service through its GET method (an example is provided in the next Practical Learning section), or call the $http.get() method for the same goal. This could be done as follows:

function select($scope, $http) {
    $scope.findCustomer = function () {
        $http({
            method: 'GET',
            url: '../api/Customers'
        }).
            then(function (response) {
                var id = $scope.acntID;

                $scope.fName = response.data[id].FirstName;
                $scope.lName = response.data[id].LastName;
            },
            function (response) {
                $scope.error = "Something went wrong";
            }
        );
    }
}

appEscape.controller("AccountReviewController", ['$scope', '$http', select]);

This is based on the concept of arrays. Remember that arrays in C-based languages, which include JavaScript, are 0-based. Therefore, you should subtract 1 from the value used as index. This could be done as follows:

function select($scope, $http) {
    $scope.findCustomer = function () {
        $http({
            method: 'GET',
            url: '../api/Customers'
        }).
            then(function (response) {
                var id = $scope.acntID - 1;

                $scope.fName = response.data[id].FirstName;
                $scope.lName = response.data[id].LastName;
            },
            function (response) {
                $scope.error = "Something went wrong";
            }
        );
    }
}

appEscape.controller("AccountReviewController", ['$scope', '$http', select]);

Practical LearningPractical Learning: Selecting a Record

  1. In the Solution Explorer, under Scripts, double-click CustomersController to access it
  2. In the empty document, type the following code:
    function processCustomers($scope, $http) {
        . . .
    
        $scope.findCustomer = function () {
            $http({
                method: 'GET',
                url: '/api/Customers'
            }).
                then(function (response) {
                    var id = Number($scope.custID || 1) - 1;
    
                    $scope.acntNbr = response.data[id].AccountNumber;
                    $scope.fName = response.data[id].FirstName;
                    $scope.lName = response.data[id].LastName;
                    $scope.adrs = response.data[id].Address;
                    $scope.ct = response.data[id].City;
                    $scope.local = response.data[id].County;
                    $scope.state = response.data[id].State;
                    $scope.packType = response.data[id].CableTVPackageType;
                    $scope.packRate = response.data[id].CableTVPackageRate;
                    $scope.dvr = response.data[id].DVRService;
                    $scope.sport = response.data[id].SportsPackages;
                    $scope.str = response.data[id].StateTaxRate;
                    $scope.sta = response.data[id].StateTaxAmount;
                    $scope.ltr = response.data[id].LocalTaxRate;
                    $scope.lta = response.data[id].LocalTaxAmount;
                },
                    function (response) {
                        $scope.error = "Something went wrong";
                });
        }
    }
    
    appEscape.controller("CustomersController", ['$scope', '$http', processCustomers]);
  3. In the Solution Explorer, under BusinessControllers, double-click CustomersController.cs to access it
  4. Add a method named Get as follows:
    using System.Web.Mvc;
    
    namespace Escape1.BusinessControllers
    {
        public class CustomersController : Controller
        {
            // GET: Customers
            public ActionResult Index()
            {
                return View();
            }
    
            // POST: Customers/Create
            public ActionResult Create()
            {
                return View();
            }
    
            // GET: Customers/Get
            public ActionResult Get()
            {
                return View();
            }
        }
    }
  5. In the document, right-click Get() and click Add View...
  6. In the Add View dialog box, make sure the View Name text box is displaying Get. Click Add
  7. Change the document as follows:
    @{
        ViewBag.Title = "Customer Account Details";
    }
    
    <h2 class="text-center common-font maroon bold">ESCAPE - Customer Account Details</h2>
    <hr />
    
    <div ng-app="cableDistribution">
        <div class="bill-contents" ng-controller="CustomersController">
            <form name="CustomerAccount" method="post">
                <table class="tbl">
                    <tr>
                        <td class="col-md-3"><label for="customerID" class="top-alignment">Customer ID:</label></td>
                        <td class="col-md-3"><input type="number" id="customerID" class="form-control medium" ng-model="custID" /></td>
                        <td class="col-md-4">
                            <input type="button" name="btnSelectCustomer"
                                   class="btn btn-primary" value="Find Customer" ng-click="findCustomer()" />
                        </td>
                        <td>&nbsp;</td>
                    </tr>
                    <tr>
                        <td class="col-md-3"><label for="accountNumber" class="top-alignment">Account #:</label></td>
                        <td class="col-md-3"><span class="form-control medium">{{acntNbr}}</span></td>
                        <td class="col-md-4">&nbsp;</td>
                        <td>&nbsp;</td>
                    </tr>
                    <tr>
                        <td class="col-md-3"><label class="top-alignment">First Name:</label></td>
                        <td class="col-md-3"><span class="form-control medium">{{fName}}</span></td>
                        <td class="col-md-4"><label class="top-alignment">Last Name:</label></td>
                        <td><span class="form-control medium">{{lName}}</span></td>
                    </tr>
                    <tr>
                        <td class="col-md-3"><label class="top-alignment">Address:</label></td>
                        <td class="col-md-3"><span class="form-control medium">{{adrs}}</span></td>
                        <td class="col-md-4"><label for="city" class="top-alignment">City:</label></td>
                        <td><span class="form-control medium">{{ct}}</span></td>
                    </tr>
                    <tr>
                        <td class="col-md-3"><label for="counties" class="top-alignment">County:</label></td>
                        <td class="col-md-3"><span class="form-control medium">{{local}}</span></td>
                        <td class="col-md-4"><label for="state" class="top-alignment">State:</label></td>
                        <td><span class="form-control medium">{{state}}</span></td>
                    </tr>
                    <tr>
                        <td class="col-md-3"><label for="cableTVPackage" class="top-alignment">Cable TV Package:</label></td>
                        <td class="col-md-3"><span class="form-control medium">{{packType}}</span></td>
                        <td class="col-md-4"><label for="packageRate" class="top-alignment">Package Rate:</label></td>
                        <td><span class="form-control medium">{{packRate}}</span></td>
                    </tr>
                    <tr>
                        <td class="col-md-3"><label for="DVRService" class="top-alignment">DVR Service:</label></td>
                        <td class="col-md-3"><span class="form-control medium">{{dvr}}</span></td>
                        <td class="col-md-4"><label for="sportsPackages" class="top-alignment">Sports Packages:</label></td>
                        <td><span class="form-control medium">{{sport}}</span></td>
                    </tr>
                    <tr>
                        <td class="col-md-3"><label class="top-alignment">State Tax Rate:</label></td>
                        <td class="col-md-3"><span class="form-control medium">{{str}}</span></td>
                        <td class="col-md-4"><label id="stateTaxAmount" class="top-alignment">State Tax Amt:</label></td>
                        <td><span class="form-control medium">{{sta}}</span></td>
                    </tr>
                    <tr>
                        <td class="col-md-3"><label class="top-alignment">Local Tax Rate:</label></td>
                        <td class="col-md-3"><span class="form-control medium">{{ltr}}</span></td>
                        <td class="col-md-4"><label for="localTaxAmount" class="top-alignment">Local Tax Amt:</label></td>
                        <td><span class="form-control medium">{{lta}}</span></td>
                    </tr>
                </table>
            </form>
            <p>{{message}}</p>
        </div>
        <hr />
    </div>
    
    <p class="text-center">
        @Html.ActionLink("Customers Accounts", "Index", "Customers", new { area = "" }, null) ::
        @Html.ActionLink("Create a New Customer Account", "Create", "Customers", new { area = "" }, null)
        @Html.ActionLink("Edit/Update a Customer's Account", "Update", "Customers", new { area = "" }, null) ::
        @Html.ActionLink("Delete a Customer's Account", "Delete", "Customers", new { area = "" }, null)
    </p>
  8. To execute the application and test the webpage, on the main menu, click Debug -> Start Without Debugging

    Practical Learning

  9. In the Account ID text box, type 2
  10. Click the Find Customer button

    Practical Learning

  11. Close the form and return to your programming environment

Records Maintenance

Introduction

Records maintenance consists of viewing, editing, and deleting records.

To provide you with the means of opening and viewing a record, Microsoft Visual Studio creates another version of a Get... method and adds that method to the Web API controller class. That method takes the identifier of the record (a value of the primary key) as argument. Here is an example of such as method:

. . .
namespace Escape1.Controllers
{
    public class CustomerAccountsController : ApiController
    {
        private CableDistributionEntities db = new CableDistributionEntities();

        . . .

        // GET: api/Customers/5
        [ResponseType(typeof(CustomerAccount))]
        public IHttpActionResult GetCustomerAccount(int id)
        {
            CustomerAccount customerAccount = db.CustomerAccounts.Find(id);
            if (customerAccount == null)
            {
                return NotFound();
            }

            return Ok(customerAccount);
        }
       . . .
    }
}

In this case, the address of the GET method is:

api/Customers/{id}

To use this approach, provide the value of the record identifier after the URL value, as {id}.

ApplicationApplication: Viewing a Record

  1. In the Solution Explorer, under Scripts, double-click CustomersController.js to access it
  2. Change the findCustomer() function as follows:
    function processCustomers($scope, $http) {
        . . .
    
        $scope.findCustomer = function () {
            $http({
                method: 'GET',
                url: '/api/Customers/' + Number($scope.custID || 0)
            }).
                then(function (response) {
                    $scope.acntNbr = response.data.AccountNumber;
                    $scope.fName = response.data.FirstName;
                    $scope.lName = response.data.LastName;
                    $scope.adrs = response.data.Address;
                    $scope.ct = response.data.City;
                    $scope.local = response.data.County;
                    $scope.state = response.data.State;
                    $scope.packType = response.data.CableTVPackageType;
                    $scope.packRate = response.data.CableTVPackageRate;
                    $scope.dvr = response.data.DVRService;
                    $scope.sport = response.data.SportsPackages;
                    $scope.str = response.data.StateTaxRate;
                    $scope.sta = response.data.StateTaxAmount;
                    $scope.ltr = response.data.LocalTaxRate;
                    $scope.lta = response.data.LocalTaxAmount;
                },
                    function (response) {
                        $scope.error = "Something went wrong when trying to find the customer";
                    });
        }
    }
    
    appEscape.controller("CustomersController", ['$scope', '$http', processCustomers]);
  3. Click the Get.cshtml tab to access the document
  4. To execute the application, on the main menu, click Debug -> Start Without Debugging

    Practical Learning

  5. In the Account ID text box, type 4
  6. Click the Find Customer button

    Practical Learning

  7. Close the form and return to your programming environment

Editing a Record

If you create a Web API controller using the Entity Framework, to let you edit a record, Microsoft Visual Studio creates a method whose name starts with Put:

namespace Escape1.Controllers
{
    public class CustomerAccountsController : ApiController
    {
        private CableDistributionEntities db = new CableDistributionEntities();

        . . . No Change

        // PUT: api/Customers/5
        [ResponseType(typeof(void))]
        public IHttpActionResult PutCustomerAccount(int id, CustomerAccount customerAccount)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            if (id != customerAccount.AccountID)
            {
                return BadRequest();
            }

            db.Entry(customerAccount).State = EntityState.Modified;

            try
            {
                db.SaveChanges();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!CustomerAccountExists(id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }

            return StatusCode(HttpStatusCode.NoContent);
        }

        . . . No Change
    }
}

As you can see, this method takes two arguments. The first argument, which is the value you must provide to the $http service, is a value that would uniquely identify the record you want to change. As seen previously, it should emanate from the primary key of the table. The second argument is an object that holds the values of the replacement, of course without the primary key (we will see an example later).

Deleting a Record

Deleting a record consists of removing it from its table. To assist you with this, when you create a Web API controller, Microsoft Visual Studio adds Delete... to the controller. The method takes a primary key value as argument:

namespace Escape1.Controllers
{
    public class CustomerAccountsController : ApiController
    {
        private CableDistributionEntities db = new CableDistributionEntities();

        . . .

        // DELETE: api/Customers/5
        [ResponseType(typeof(CustomerAccount))]
        public IHttpActionResult DeleteCustomerAccount(int id)
        {
            CustomerAccount customerAccount = db.CustomerAccounts.Find(id);
            if (customerAccount == null)
            {
                return NotFound();
            }

            db.CustomerAccounts.Remove(customerAccount);
            db.SaveChanges();

            return Ok(customerAccount);
        }

        . . . 
    }
}

As you can see, the HTTP method to remove a record is DELETE. You can use it when creating an object to pass to an $http service. This would be done as follows:

$scope.findCustomer = function () {
    $http({
        method: 'DELETE',
        url: . . .
    }).
    then(function (response) {
        . . .
    },
    function (response) {
        . . .
    }
}

The $http service provides a shortcut to remove a record. It consists of calling a method named delete on the service.

When the Web API method to delete a record is called, it first looks for a record identified by the argument. If the record is found, the method removes it. If there is no such record, normally, the method doesn't do anything.

Practical LearningPractical Learning: Deleting a Record

  1. In the Solution Explorer, under Scripts, double-click CustomersController.js to access the file
  2. In the document, add a function named delete as follows:
    function processCustomers($scope, $http) {
        . . .
    
        $scope.deleteCustomerAccount = function () {
            var customer = {
                AccountNumber: $scope.acntNbr,
                FirstName: $scope.fName,
                LastName: $scope.lName,
                Address: $scope.adrs,
                City: $scope.ct,
                County: $scope.local,
                State: $scope.state,
                CableTVPackageType: $scope.packType,
                CableTVPackageRate: $scope.packRate,
                DVRService: $scope.dvr,
                SportsPackages: $scope.sport,
                StateTaxRate: $scope.str,
                StateTaxAmount: $scope.sta,
                LocalTaxRate: $scope.ltr,
                LocalTaxAmount: $scope.lta
            };
    
            var connection = {
                method: 'DELETE',
                url: '/api/Customers/' + Number($scope.custID || 0),
                data: customer
            };
            $http(connection).
                then(function (response) {
                    $scope.customers.splice(response.data, 1);
                },
                    function (response) {
                        $scope.error = "There was an error that prevented the record from being deleted.";
                    });
    
            resetForm();
        }
    }
    
    appEscape.controller("CustomersController", ['$scope', '$http', processCustomers]);
  3. In the Solution Explorer, under BusinessControllers, double-click CustomersController.cs to access it
  4. Add a method named Delete as follows:
    using System.Web.Mvc;
    
    namespace Escape1.BusinessControllers
    {
        public class CustomersController : Controller
        {
            // GET: Customers
            public ActionResult Index()
            {
                return View();
            }
    
            // POST: Customers/Create
            public ActionResult Create()
            {
                return View();
            }
    
            // GET: Customers/Get
            public ActionResult Get()
            {
                return View();
            }
    
            // DELETE: Customers/Delete
            public ActionResult Delete()
            {
                return View();
            }
        }
    }
  5. Right-click inside the Delete() method and click Add View...
  6. In the Add View dialog box, make sure the View Name text box displays Delete. Click Add
  7. Change the document as follows:
    @{
        ViewBag.Title = "Customer Account Removal";
    }
    
    <h2 class="text-center common-font maroon bold">Customer Account Removal</h2>
    <hr />
    <div ng-app="cableDistribution">
        <div class="bill-contents" ng-controller="CustomersController">
            <form name="CustomerAccount" method="post">
                <table class="tbl">
                    <tr>
                        <td class="col-md-3"><label for="customerID" class="top-alignment">Customer ID:</label></td>
                        <td class="col-md-3"><input type="number" id="customerID" class="form-control medium" ng-model="custID" /></td>
                        <td class="col-md-4">
                            <input type="button" name="btnSelectCustomer"
                                   class="btn btn-primary" value="Find Customer" ng-click="findCustomer()" />
                        </td>
                        <td>&nbsp;</td>
                    </tr>
                    <tr>
                        <td class="col-md-3"><label for="accountNumber" class="top-alignment">Account #:</label></td>
                        <td class="col-md-3"><span class="form-control medium">{{acntNbr}}</span></td>
                        <td class="col-md-4">&nbsp;</td>
                        <td>&nbsp;</td>
                    </tr>
                    <tr>
                        <td class="col-md-3"><label class="top-alignment">First Name:</label></td>
                        <td class="col-md-3"><span class="form-control medium">{{fName}}</span></td>
                        <td class="col-md-4"><label class="top-alignment">Last Name:</label></td>
                        <td><span class="form-control medium">{{lName}}</span></td>
                    </tr>
                    <tr>
                        <td class="col-md-3"><label class="top-alignment">Address:</label></td>
                        <td class="col-md-3"><span class="form-control medium">{{adrs}}</span></td>
                        <td class="col-md-4"><label for="city" class="top-alignment">City:</label></td>
                        <td><span class="form-control medium">{{ct}}</span></td>
                    </tr>
                    <tr>
                        <td class="col-md-3"><label for="counties" class="top-alignment">County:</label></td>
                        <td class="col-md-3"><span class="form-control medium">{{local}}</span></td>
                        <td class="col-md-4"><label for="state" class="top-alignment">State:</label></td>
                        <td><span class="form-control medium">{{state}}</span></td>
                    </tr>
                    <tr>
                        <td class="col-md-3"><label for="cableTVPackage" class="top-alignment">Cable TV Package:</label></td>
                        <td class="col-md-3"><span class="form-control medium">{{packType}}</span></td>
                        <td class="col-md-4"><label for="packageRate" class="top-alignment">Package Rate:</label></td>
                        <td><span class="form-control medium">{{packRate}}</span></td>
                    </tr>
                    <tr>
                        <td class="col-md-3"><label for="DVRService" class="top-alignment">DVR Service:</label></td>
                        <td class="col-md-3"><span class="form-control medium">{{dvr}}</span></td>
                        <td class="col-md-4"><label for="sportsPackages" class="top-alignment">Sports Packages:</label></td>
                        <td><span class="form-control medium">{{sport}}</span></td>
                    </tr>
                    <tr>
                        <td class="col-md-3"><label class="top-alignment">State Tax Rate:</label></td>
                        <td class="col-md-3"><span class="form-control medium">{{str}}</span></td>
                        <td class="col-md-4"><label id="stateTaxAmount" class="top-alignment">State Tax Amt:</label></td>
                        <td><span class="form-control medium">{{sta}}</span></td>
                    </tr>
                    <tr>
                        <td class="col-md-3"><label class="top-alignment">Local Tax Rate:</label></td>
                        <td class="col-md-3"><span class="form-control medium">{{ltr}}</span></td>
                        <td class="col-md-4"><label for="localTaxAmount" class="top-alignment">Local Tax Amt:</label></td>
                        <td><span class="form-control medium">{{lta}}</span></td>
                    </tr>
                </table>
                <hr />
    
                <p class="text-center">
                    <input type="button" name="btnDeleteCustomerAccount"
                           class="btn btn-primary" value="Delete Customer Account" ng-click="deleteCustomerAccount()" />
                </p>
            </form>
            <p>{{message}}</p>
        </div>
    </div>
    <hr />
    
    <p class="text-center">
        @Html.ActionLink("Customers Accounts", "Index", "Customers", new { area = "" }, null) ::
        @Html.ActionLink("Create a New Customer Account", "Create", "Customers", new { area = "" }, null) ::
        @Html.ActionLink("Customer Account Details", "Get", "Customers", new { area = "" }, null) ::
        @Html.ActionLink("Edit/Update a Customer's Account", "Update", "Customers", new { area = "" }, null) ::
    </p>
  8. To execute the application, on the main menu, click Debug -> Start Without Debugging

    Record Maintenance - Deleting a Record

  9. In the top text box, type 3
  10. Click the Find Customer button

    Practical Learning

  11. Click the Delete Customer Account button
  12. Close the browser and return to your programming environment

Assisting a User

Introduction

The codes we wrote earlier to perform record operations are just fine, but some of them are not professional. In some cases, although you need a value to complete a record, the user should not explicitly enter certain values, such as those resulting from expressions, like totals. You have many options to assist users. You can create combo boxes (or radio buttons, check boxes, etc). You can use expressions. You can perform calculations, etc.

Creating a Record

When creating a record, you can assist the user in many cases. For example, in some cases, instead of entering values, in case of a limited list of options, you can create a group of radio buttons, a check box, or a combo box. Instead of the user entering some numbers, you can create expressions to perform the necessary calculations.

Practical LearningPractical Learning: Assisting a User

  1. In the Solution Explorer, under Scripts, double-click CustomersController.js to access it
  2. Add a few functions as follows:
    function processCustomers($scope, $http) {
        // This is a limited list of the counties covered by our cable TV company
        $scope.MDCounties = ['Howard', 'Montgomery', 'Prince George'];
        $scope.PACounties = ["Adams", "Lancaster", "Dauphin", "York"];
        $scope.WVCounties = ['Berkeley', "Jefferson"];
    
        /* This function evaluates the customer's bill based on selections that
         * will be made on the controls and some values that will be entered in text boxes. */
        $scope.evaluateCustomerBill = function () {
            var dvrCost = Number($scope.dvr || 0);
            var sports = Number($scope.sport || 0);
            var package = Number($scope.packRate || 0);
            var stateRate = Number($scope.str || 0) * (package + dvrCost + sports) / 100;
            var localRate = Number($scope.ltr || 0) * (package + dvrCost + sports) / 100;
    
            $scope.sta = stateRate;
            $scope.lta = localRate;
            $scope.subTotal = package + dvrCost + sports + stateRate + localRate;
        }
    
        /* This function specifies the content of the County combo box based on the 
         *  state selected in the State combo box. */
        $scope.specifyCounties = function () {
            if ($scope.state == "MD") {
                $scope.str = 8.27;
                $scope.counties = $scope.MDCounties;
            }
            else if ($scope.state == "PA") {
                $scope.str = 3.86;
                $scope.counties = $scope.PACounties;
            }
            else if ($scope.state == "WV") {
                $scope.str = 6.28;
                $scope.counties = $scope.WVCounties;
            }
            else { // if($scope.state == "VA")
                $scope.str = 3.50;
                $scope.counties = null;
            }
    
            $scope.evaluateCustomerBill();
        }
    
        // This function specifies some random county tax rates for cable TV.
        $scope.setLocalTaxes = function () {
            if ($scope.local == 'Howard') { $scope.ltr = 9.13; }
            else if ($scope.local == 'Montgomery') { $scope.ltr = 7.75; }
            else if ($scope.local == 'Prince George') { $scope.ltr = 8.82; }
            else if ($scope.local == "Adams") { $scope.ltr = 4.69; }
            else if ($scope.local == "Lancaster") { $scope.ltr = 5.54; }
            else if ($scope.local == "York") { $scope.ltr = 8.86; }
            else if ($scope.local == 'Berkeley') { $scope.ltr = 7.39; }
            else if ($scope.local == "Jefferson") { $scope.ltr = 10.06; }
            else { $scope.ltr = 5.00; }
    
            $scope.evaluateCustomerBill();
        }
    
        // This function specifies some random cable TV rates.
        $scope.setTVPackageRate = function () {
            if ($scope.packType == "Standard") { $scope.packRate = 24.50; }
            else if ($scope.packType == "Performance") { $scope.packRate = 32.47; }
            else { $scope.packRate = 18.96; }
    
            $scope.evaluateCustomerBill();
        }
    
        // This function is used to empty the controls on the form after a record has been saved.
        function resetForm() {
            $scope.acntNbr = "";
            $scope.fName = "";
            $scope.lName = "";
            $scope.adrs = "";
            $scope.ct = "";
            $scope.local = "";
            $scope.state = "";
            $scope.packType = "Basic";
            $scope.packRate = 0.00;
            $scope.dvr = 0.00;
            $scope.sport = 0.00;
            $scope.str = 0.00;
            $scope.sta = 0.00;
            $scope.ltr = 0.00;
            $scope.lta = 0.00;
        }
        $scope.createCustomerAccount = function () {
            var customer = {
                AccountNumber: $scope.acntNbr,
                FirstName: $scope.fName,
                LastName: $scope.lName,
                Address: $scope.adrs,
                City: $scope.ct,
                County: $scope.local,
                State: $scope.state,
                CableTVPackageType: $scope.packType,
                CableTVPackageRate: $scope.packRate,
                DVRService: $scope.dvr,
                SportsPackages: $scope.sport,
                StateTaxRate: $scope.str,
                StateTaxAmount: $scope.sta,
                LocalTaxRate: $scope.ltr,
                LocalTaxAmount: $scope.lta
            };
    
            $http({
                method: 'POST',
                url: '/api/Customers',
                data: customer
            }).
                then(function (response) {
                    $scope.customers.push(response.data);
                },
                    function (response) {
                        $scope.error = "Something went wrong when trying to save the record.";
                    });
    
            resetForm();
        }
    
        // Get All Customers
        $http({
            method: 'GET',
            url: '/api/Customers'
        }).
            then(function (response) {
                $scope.customers = response.data;
            },
                function (response) {
                    $scope.error = "Something went wrong when trying to get the list of customers";
                }
        );
    
        $scope.findCustomer = function () {
            $http({
                method: 'GET',
                url: '/api/Customers'
            }).
                then(function (response) {
                    var id = Number($scope.custID || 1) - 1;
                    
                    $scope.acntNbr = response.data[id].AccountNumber;
                    $scope.fName = response.data[id].FirstName;
                    $scope.lName = response.data[id].LastName;
                    $scope.adrs = response.data[id].Address;
                    $scope.ct = response.data[id].City;
                    $scope.local = response.data[id].County;
                    $scope.state = response.data[id].State;
                    $scope.packType = response.data[id].CableTVPackageType;
                    $scope.packRate = response.data[id].CableTVPackageRate;
                    $scope.dvr = response.data[id].DVRService;
                    $scope.sport = response.data[id].SportsPackages;
                    $scope.str = response.data[id].StateTaxRate;
                    $scope.sta = response.data[id].StateTaxAmount;
                    $scope.ltr = response.data[id].LocalTaxRate;
                    $scope.lta = response.data[id].LocalTaxAmount;
                },
                    function (response) {
                        $scope.error = "For some reason, the customer record could not be located.";
                    });
        }
    
        $scope.deleteCustomerAccount = function () {
            var customer = {
                AccountNumber: $scope.acntNbr,
                FirstName: $scope.fName,
                LastName: $scope.lName,
                Address: $scope.adrs,
                City: $scope.ct,
                County: $scope.local,
                State: $scope.state,
                CableTVPackageType: $scope.packType,
                CableTVPackageRate: $scope.packRate,
                DVRService: $scope.dvr,
                SportsPackages: $scope.sport,
                StateTaxRate: $scope.str,
                StateTaxAmount: $scope.sta,
                LocalTaxRate: $scope.ltr,
                LocalTaxAmount: $scope.lta
            };
    
            var connection = {
                method: 'DELETE',
                url: '/api/Customers/' + Number($scope.custID || 0),
                data: customer
            };
            $http(connection).
                then(function (response) {
                    $scope.customers.splice(response.data, 1);
                },
                    function (response) {
                        $scope.error = "There was an error that prevented the record from being deleted.";
                    });
    
            resetForm();
        }
    }
    
    appEscape.controller("CustomersController", ['$scope', '$http', processCustomers]);
  3. In the Solution Explorer, under BusinessControllers, double-click CustomersController.cs to access it
  4. In the document, right-click Create() and click Go To View
  5. Change its code as follows:
    @{
        ViewBag.Title = "New Customer Account";
    }
    
    <h2 class="text-center common-font maroon bold">ESCAPE - New Customer Account</h2>
    <hr />
    
    <div ng-app="cableDistribution">
        <div class="bill-contents" ng-controller="CustomersController">
            <form name="CustomerAccount" method="post">
                <div class="row form-group">
                    <div class="col-md-3 text-right">
                        <label for="accountNumber" class="top-alignment">Account #:</label>
                    </div>
                    <div class="col-md-3">
                        <input type="text" id="accountNumber" class="form-control" ng-model="acntNbr" />
                    </div>
                </div>
                <div class="row form-group">
                    <div class="col-md-3 text-right">
                        <label for="firstName" class="top-alignment">First Name:</label>
                    </div>
                    <div class="col-md-3">
                        <input type="text" id="firstName" class="form-control" ng-model="fName" />
                    </div>
                    <div class="col-md-3 text-right">
                        <label for="lastName" class="top-alignment">Last Name:</label>
                    </div>
                    <div class="col-md-3">
                        <input type="text" id="lastName" class="form-control" ng-model="lName" />
                    </div>
                </div>
                <div class="row form-group">
                    <div class="col-md-3 text-right">
                        <label for="address" class="top-alignment">Address:</label>
                    </div>
                    <div class="col-md-9">
                        <input type="text" id="address" class="form-control" ng-model="adrs" />
                    </div>
                </div>
                <div class="row form-group">
                    <div class="col-md-3 text-right">
                        <label for="city" class="top-alignment">City:</label>
                    </div>
                    <div class="col-md-3">
                        <input type="text" id="city" class="form-control" ng-model="ct" />
                    </div>
                    <div class="col-md-3 text-right">
                        <label for="state" class="top-alignment">State:</label>
                    </div>
                    <div class="col-md-3">
                        <select id="state" class="form-control" ng-model="state" ng-change="specifyCounties()">
                            <option value="MD">MD</option>
                            <option value="PA">PA</option>
                            <option value="VA">VA</option>
                            <option value="WV">WV</option>
                        </select>
                    </div>
                </div>
                <div class="row form-group">
                    <div class="col-md-3 text-right">
                        <label class="top-alignment">&nbsp;</label>
                    </div>
                    <div class="col-md-3">
                        &nbsp;
                    </div>
                    <div class="col-md-3 text-right">
                        <label for="county" class="top-alignment">County:</label>
                    </div>
                    <div class="col-md-3">
                        <select name="county" class="form-control" ng-model="local" ng-change="setLocalTaxes()">
                            <option ng-repeat="county in counties">{{county}}</option>
                        </select>
                    </div>
                </div>
                <div class="row form-group">
                    <div class="col-md-3 text-right">
                        <label for="cableTVPackage" class="top-alignment">Cable TV Package:</label>
                    </div>
                    <div class="col-md-3">
                        <select id="cableTVPackage" class="form-control" ng-model="packType" ng-change="setTVPackageRate()">
                            <option value="Basic">Basic</option>
                            <option value="Standard">Standard</option>
                            <option value="Performance">Performance</option>
                        </select>
                    </div>
                    <div class="col-md-3 text-right">
                        <label for="packageRate" class="top-alignment">Package Rate:</label>
                    </div>
                    <div class="col-md-3">
                        <span class="form-control">{{packRate}}</span>
                    </div>
                </div>
                <div class="row form-group">
                    <div class="col-md-3 text-right">
                        <label for="dvrService" class="top-alignment">DVR Service:</label>
                    </div>
                    <div class="col-md-3">
                        <input type="number" id="dvrService" class="form-control" ng-model="dvr" ng-change="evaluateCustomerBill()" />
                    </div>
                    <div class="col-md-3 text-right">
                        <label for="sportsPackages" class="top-alignment">Sports Packages:</label>
                    </div>
                    <div class="col-md-3">
                        <input type="number" id="sportsPackages" class="form-control" ng-model="sport" ng-change="evaluateCustomerBill()" />
                    </div>
                </div>
                <div class="row form-group">
                    <div class="col-md-3 text-right">
                        <label class="top-alignment">State Tax Rate:</label>
                    </div>
                    <div class="col-md-3">
                        <span class="form-control">{{str | number : 2}} %</span>
                    </div>
                    <div class="col-md-3 text-right">
                        <label for="StateTaxes" class="top-alignment">State Tax Amount:</label>
                    </div>
                    <div class="col-md-3">
                        <span class="form-control">{{sta | number : 2}}</span>
                    </div>
                </div>
                <div class="row form-group">
                    <div class="col-md-3 text-right">
                        <label class="top-alignment">Local Tax Rate:</label>
                    </div>
                    <div class="col-md-3">
                        <span class="form-control">{{ltr | number : 2}} %</span>
                    </div>
                    <div class="col-md-3 text-right">
                        <label for="StateTaxes" class="top-alignment">Local Tax Amount:</label>
                    </div>
                    <div class="col-md-3">
                        <span class="form-control">{{lta | number : 2}}</span>
                    </div>
                </div>
                <div class="row form-group">
                    <div class="col-md-3 text-right">
                        <label class="top-alignment">&nbsp;</label>
                    </div>
                    <div class="col-md-3">
                        &nbsp;
                    </div>
                    <div class="col-md-3 text-right">
                        <label class="top-alignment">Sub-Total:</label>
                    </div>
                    <div class="col-md-3">
                        <span class="form-control">{{subTotal | number : 2}}</span>
                    </div>
                </div>
                <hr />
                <p class="text-center">
                    <input type="button" name="btnCreateCustomerBill"
                           class="btn btn-primary" value="Create Customer Bill" ng-click="saveAccount()" />
                </p>
            </form>
        </div>
        <hr />
    
        <p class="text-center">
            @Html.ActionLink("Customers Accounts", "Index", "Customers", new { area = "" }, null) ::
            @Html.ActionLink("Customer Account Details", "Get", "Customers", new { area = "" }, null) ::
            @Html.ActionLink("Edit/Update a Customer's Account", "Update", "Customers", new { area = "" }, null) ::
            @Html.ActionLink("Delete a Customer's Account", "Delete", "Customers", new { area = "" }, null)
        </p>
    </div>
  6. In the Solution Explorer, under Scripts, double-click CableBillsController.js to access it
  7. Change the document as follows:
    function
  8. In the Solution Explorer, under BusinessControllers, double-click CableBillsController.cs to access the file
  9. In the class, create a method named Create as follows:
    using System.Web.Mvc;
    
    namespace Escape1.BusinessControllers
    {
        public class CableBillsController : Controller
        {
            // GET: CableBills
            public ActionResult Index()
            {
                return View();
            }
    
            // POST: CableBills/Create
            public ActionResult Create()
            {
                return View();
            }
        }
    }
  10. In the document, right-click Create() and click Add View...
  11. Make sure the View Name text box of the Add View dialog box displays Create. Click Add
  12. Change the document as follows:
    @{
        ViewBag.Title = "Customer Bill Preparation";
    }
    
    <h2 class="text-center common-font maroon bold">Customer Bill Preparation</h2>
    
    <hr />
    <div ng-app="cableDistribution">
    
        <div class="bill-contents" ng-controller="CableBillsController">
            <form name="CustomerBill" method="post">
                <div class="row form-group">
                    <div class="col-md-3 text-right">
                        <label for="customerID" class="top-alignment">Customer ID:</label>
                    </div>
                    <div class="col-md-3">
                        <input type="number" id="customerID" class="form-control medium" ng-model="custID" />
                    </div>
                    <div class="col-md-4">
                        <input type="button" name="btnFindCustomer"
                               class="btn btn-primary" value="Find Customer" ng-click="findCustomer()" />
                    </div>
                </div>
                <div class="row form-group">
                    <div class="col-md-3 text-right">
                        <label for="address" class="top-alignment">Account #:</label>
                    </div>
                    <div class="col-md-3">
                        <span class="form-control">{{acntNbr}}</span>
                    </div>
                    <div class="col-md-3 text-right" ">
                        <label for="accountID" class="top-alignment">Customer Name:</label>
                    </div>
                    <div class="col-md-3">
                        <span class="form-control">{{fName}} {{lName}}</span>
                    </div>
                </div>
                <div class="row form-group">
                    <div class="col-md-3 text-right">
                        <label for="firstName" class="top-alignment">Address:</label>
                    </div>
                    <div class="col-md-3">
                        <span class="form-control">{{adrs}}</span>
                    </div>
                    <div class="col-md-3">
                        <span class="form-control">{{ct}}</span>
                    </div>
                    <div class="col-md-3">
                        <span class="form-control">{{state}}</span>
                    </div>
                </div>
                <hr />
                <div class="row form-group">
                    <div class="col-md-3 text-right">
                        <label for="cableTVPackage" class="top-alignment">Cable TV Package:</label>
                    </div>
                    <div class="col-md-3">
                        <span class="form-control">{{packType}} at {{packRate}})</span>
                    </div>
                    <div class="col-md-3 text-right">
                        <label class="top-alignment">State Taxes: </label>
                    </div>
                    <div class="col-md-3">
                        <span class="form-control">{{str | number : 2}} % => {{sta | number : 2}}</span>
                    </div>
                </div>
                <div class="row form-group">
                    <div class="col-md-3 text-right">
                        <label class="top-alignment">Sports Packages:</label>
                    </div>
                    <div class="col-md-3">
                        <span class="form-control">{{sport}}</span>
                    </div>
                    <div class="col-md-3 text-right">
                        <label class="top-alignment">Local Taxes:</label>
                    </div>
                    <div class="col-md-3">
                        <span class="form-control">{{ltr | number : 2}} % => {{lta | number : 2}}</span>
                    </div>
                </div>
                <div class="row form-group">
                    <div class="col-md-3 text-right">
                        <label class="top-alignment">DVR Service:</label>
                    </div>
                    <div class="col-md-3">
                        <span class="form-control">{{dvr}}</span>
                    </div>
                    <div class="col-md-3 text-right">
                        <label class="top-alignment">Sub-Total:</label>
                    </div>
                    <div class="col-md-3">
                        <span class="form-control">{{subTotal | number : 2}}</span>
                    </div>
                </div>
                <hr />
                <div class="row form-group">
                    <div class="col-md-3 text-right">
                        <label class="top-alignment">FCC Fee:</label>
                    </div>
                    <div class="col-md-3">
                        <span class="form-control">{{fcc | number : 2}}</span>
                    </div>
                    <div class="col-md-3 text-right">
                        <label for="StateTaxes" class="top-alignment">Right of Way Fee:</label>
                    </div>
                    <div class="col-md-3">
                        <span class="form-control">{{row | number : 2}}</span>
                    </div>
                </div>
                <div class="row form-group">
                    <div class="col-md-3 text-right">
                        <label for="address" class="top-alignment">Environment Fee:</label>
                    </div>
                    <div class="col-md-3">
                        <span class="form-control">{{environment | number : 2}}</span>
                    </div>
                    <div class="col-md-3 text-right">
                        <label class="top-alignment">Payment Due Date:</label>
                    </div>
                    <div class="col-md-3">
                        <span class="form-control">{{pmtDueDate | number : 2}}</span>
                    </div>
                </div>
                <div class="row form-group">
                    <div class="col-md-3">&nbsp;</div>
                    <div class="col-md-3">&nbsp;</div>
                    <div class="col-md-3 text-right">
                        <label class="top-alignment">Amount Due:</label>
                    </div>
                    <div class="col-md-3">
                        <span class="form-control">{{amtDue | number : 2}}</span>
                    </div>
                </div>
                <hr />
                <p class="text-center">
                    <input type="button" name="btnSaveCableBill"
                           class="btn btn-primary" value="Save Customer Bill" ng-click="CreateCableBill()" />
                </p>
            </form>
        </div>
        <hr />
    </div>
    
    <p class="text-center">
        @Html.ActionLink("Cable Bills", "Index", "CableBills", new { area = "" }, null) ::
        @Html.ActionLink("Cable Bill Details", "Get", "CableBills", new { area = "" }, null) ::
        @Html.ActionLink("Edit/Update a Cable Bill", "Update", "CableBills", new { area = "" }, null) ::
        @Html.ActionLink("Delete/Cancel a Cable Bill", "Delete", "CableBills", new { area = "" }, null)
    </p>

Editing a Record

Just as seen for creating a record, when editing a record, you should make sure the user works as little as possible. Of course, to start, you must request a unique value from the user so you can locate and display the record that should be edited. Second, you should populate the form with good and flexible controls so that the user can make selections when possible and type values only when necessary.

Practical LearningPractical Learning: Using an HTTP Service Shorcut

  1. In the Solution Explorer, under Scripts, double-click EditCustomerAccount.js to access it
  2. In the empty document, type the following code:
    function locate($scope, $http, $window) {
        $scope.calculateBill = function () {
            var dvrCost = Number($scope.dvr || 0);
            var sports = Number($scope.sport || 0);
            var package = Number($scope.packRate || 0);
            var stateRate = Number($scope.str || 0) * (package + dvrCost + sports) / 100;
            var localRate = Number($scope.ltr || 0) * (package + dvrCost + sports) / 100;
    
            $scope.sta = stateRate;
            $scope.lta = localRate;
            $scope.subTotal = package + dvrCost + sports + stateRate + localRate;
        }
    
        $scope.findCustomer = function () {
            $http({
                method: 'GET',
                url: '../api/Customers/' + Number($scope.acntID || 0),
            }).
                then(function (response) {
                    $scope.acntNbr = response.data.AccountNumber;
                    $scope.fName = response.data.FirstName;
                    $scope.lName = response.data.LastName;
                    $scope.adrs = response.data.Address;
                    $scope.ct = response.data.City;
                    $scope.local = response.data.County;
                    $scope.state = response.data.State;
                    $scope.packType = response.data.CableTVPackageType;
                    $scope.packRate = response.data.CableTVPackageRate;
                    $scope.dvr = response.data.DVRService;
                    $scope.sport = response.data.SportsPackages;
                    $scope.str = response.data.StateTaxRate;
                    $scope.ltr = response.data.LocalTaxRate;
    
                    $scope.calculateBill();
            },
            function (response) {
                $scope.message = "Something went wrong";
            }
            );
        }
        function resetForm() {
            $scope.acntID = "";
            $scope.acntNbr = "";
            $scope.fName = "";
            $scope.lName = "";
            $scope.adrs = "";
            $scope.ct = "";
            $scope.local = "";
            $scope.state = "";
            $scope.packType = "Basic";
            $scope.packRate = 0.00;
            $scope.dvr = 0.00;
            $scope.sport = 0.00;
            $scope.str = 0.00;
            $scope.ltr = 0.00;
        }
        $scope.updateAccount = function () {
            var index = Number($scope.acntID || 0);
    
            var customer = {
                AccountID: index,
                AccountNumber: $scope.acntNbr,
                FirstName: $scope.fName,
                LastName: $scope.lName,
                Address: $scope.adrs,
                City: $scope.ct,
                County: $scope.local,
                State: $scope.state,
                CableTVPackageType: $scope.packType,
                CableTVPackageRate: $scope.packRate,
                DVRService: $scope.dvr,
                SportsPackages: $scope.sport,
                StateTaxRate: $scope.str,
                StateTaxAmount: $scope.sta,
                LocalTaxRate: $scope.ltr,
                LocalTaxAmount: $scope.lta,
                SubTotal: 0.00
            };
    
            var connection = {
                method: 'PUT',
                url: '../api/Customers/' + index,
                data: customer
            };
            $http(connection).
                then(function (response) {
                    $scope.customers = response.data;
                },
                function (response) {
                    $scope.error = "Either you didn't enter an account ID, or the one you entered is not valid.";
                });
    
            resetForm();
        }
    }
    
    appEscape.controller("AccountUpdateController", ['$scope', '$http', locate]);
  3. In the Solution Explorer, under BusinessControllers, double-click CustomersController.cs to access it
  4. Change the class as follows:
    using System.Web.Mvc;
    
    namespace Escape1.BusinessControllers
    {
        public class CustomersController : Controller
        {
            // GET: Customers
            public ActionResult Index()
            {
                return View();
            }
    
            // POST: Customers/Create
            public ActionResult Create()
            {
                return View();
            }
    
            // GET: Customers/Get
            public ActionResult Get()
            {
                return View();
            }
    
            // PUT: Customers/Edit
            public ActionResult Edit()
            {
                return View();
            }
    
            // DELETE: Customers/Delete
            public ActionResult Delete()
            {
                return View();
            }
        }
    }
  5. In the class, right-click Edit() and click Add View...
  6. In the Add View dialog box, make sure tjhe View Name text box is displaying Edit. Click Add
  7. Change the document as follows:
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8" />
    <title>ESCAPE - Edit/Update Customer Account</title>
    <link href="../Content/bootstrap.css" rel="stylesheet" />
    <link href="../Content/CableCompany.css" rel="stylesheet" />
    <script src="../Scripts/angular.min.js"></script>
    <script src="../Scripts/BusinessManagement.js"></script>
    <script src="../Scripts/EditCustomerAccount.js"></script>
    </head>
    <body ng-app="cableDistribution">
        <div>
            <h1 class="text-center common-font maroon bold">ESCAPE - Edit/Update Customer Account</h1></body>
    </html>
  8. To execute the application, press Ctrl + F5:

    Web API - Creating a Record

  9. In the Account ID text box, type 2
  10. Click the Find Customer button:

    Web API - Creating a Record

  11. Change the following values in the text boxes:
    Address: 3997 Ghost Effect Street
    Cable TV Package: Standard
    Package Rate: 27.75
  12. Click the Update Customer Account button
  13. Close the browser and return to your programming environment
  14. To execute the application, press Ctrl + F5
  15. Close the browser and return to your programming environment
  16. Close your programming environment

Previous Copyright © 2017-2019, FunctionX Next