Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Angular JS with ASP.NET Web API

0.00/5 (No votes)
23 Apr 2015 2  
This tip is targeted towards learning the basics of Angular JS, using it with ASP.NET Web API.

Introduction

This tip is targeted towards learning the basics of Angular JS, using it with ASP.NET Web API. Focus would be more towards learning some concepts of Angular JS, like MVC architecture, data binding and SPA. It is assumed that target people for this tip have some basic knowledge of HTML and some JavaScript framework like jQuery.

We would build a small Search Engine application using Yahoo APIs on the background. I have used Visual Studio 2013 with Update 4 for building this application.

Project Setup

Start with creating a new ASP.NET Web Application project, name it as SearchEngine. Click on OK.

Select the template as MVC, select Web API. Click on OK.

Once the Solution is generated, right click on References, click on “Manage NuGet Packages..”. Search for AngularJS and click on Install button.

This would install required Angular scripts in \Scripts folder:

Creating Model

Next, we would create a Model class Restaurant, that would hold the restaurant information. Right click on Model folder and add a class, name it as Restaurant. Replace the contents of this class with the following:

namespace SearchEngine.Models
{
    public class Restaurant
    {
        public string Name { get; set; }
        public string Address { get; set; }
        public string Longitude { get; set; }
        public string Latitude { get; set; }
    }
} 

Web API Controller

Next, we would write a Web API to fetch the data from Yahoo API, populating the Model. Right click on Controllers folder, select Add, then New Scaffolded Item.

Select Web API 2 Controller – Empty, click on Add button.

Name it as RestaurantController. Replace the contents of RestaurantController class with the following:

using Newtonsoft.Json.Linq;
using SearchEngine.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Web;
using System.Web.Http;
using System.Web.Http.Description;

namespace SearchEngine.Controllers
{
    public class RestaurantController : ApiController
    {
        [ResponseType(typeof(List<restaurant>))]
        public IHttpActionResult Get(string location, string type)
        {
            string query = string.Format("select * from local.search 
            where location='{0}' and query='{1}'", location, type);

            var rests = this.FetchDataFromYahoo(query);
            if (rests == null)
                return this.NotFound();

            var restaurents = ParseJsonDataToRestaurent(rests);
            return this.Ok(restaurents);
        }

        private static List<restaurant> ParseJsonDataToRestaurent(string results)
        {
            JObject dataObject = JObject.Parse(results);
            if (dataObject.Count <= 0) return null;

            JArray jsonArray = (JArray)dataObject["query"]["results"]["Result"];

            List<restaurant> rests = new List<restaurant>();
            foreach (var rest in jsonArray)
            {
                rests.Add(new Restaurant
                {
                    Name = rest["Title"].ToString(),
                    Address = rest["Address"].ToString(),
                    Latitude = rest["Latitude"].ToString(),
                    Longitude = rest["Longitude"].ToString()
                });
            }

            return rests;
        }

        private string FetchDataFromYahoo(string query)
        {
            StringBuilder queryB = new StringBuilder();
            queryB.Append("http://query.yahooapis.com/v1/public/yql?q=");
            queryB.Append(HttpUtility.UrlEncode(query));
            queryB.Append("&format=json");
            queryB.Append("&diagnostics=false");

            return DownloadWebDataInJson(queryB.ToString());
        }

        private string DownloadWebDataInJson(string webQuery)
        {
            string results = string.Empty;
            using (WebClient wc = new WebClient())
            {
                results = wc.DownloadString(webQuery);
            }
            return results;
        }
    }
}</restaurant></restaurant></restaurant></restaurant>

For the purpose of simplicity, we have used Yahoo API in background, instead of DB. Similar data can be fetched from DB as well, instead of Yahoo API.

Testing Web API

Build the project and run it. When the home page shows up, replace your local URL with the following:

http://localhost:XXXXX/api/restaurant?location=Newyork&Type=Chinese

(Don’t forget to replace XXXXX with your local port).

It should display the restaurants’ data in the following format:

The above URL sent a request to the “Get” method above under RestaurantController, that returns the Restaurant data in List format.

UI Design

Next, we would design a UI to display the restaurants’ data.

Right click on Views -> Home, click on Add, then “MVC 5 Partial Page (Razor)”.

Enter the page name as Restaurant. Enter the following code in the page:

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

<div id="bodyContainer" ng-app="RestaurantApp">
<section id="content">
<div ng-controller="RestaurantCtrl" ng-init="restaurants()">
<p>{{title}}</p>

<div>
<div>
<div>Location</div>

<div><input ng-model="location" type="text" /></div>
</div>

<div>
<div>Type</div>

<div><input ng-model="type" type="text" /></div>
</div>

<div>
<div><button ng-click="restaurants1()" ng-disabled="queryDisabled" 
type="button">Requery</button></div>
</div>
</div>

<table border="1" cellpadding="5" cellspacing="5"> <thead> <tr> <th>Name</th> <th>Address</th> <th>Longitude</th> <th>Latitude</th> </tr> </thead> <tbody> <tr ng-repeat="rest in restaurants"> <td>{{rest.Name}}</td> <td>{{rest.Address}}</td> <td>{{rest.Longitude}}</td> <td>{{rest.Latitude}}</td> </tr> </tbody> </table> </div> </section> </div> @section scripts { @Scripts.Render("~/Scripts/angular.js") }

Few points to be noted in the above code:

  1. ng-app="RestaurantApp" – Angular JS directive to define the application area. It is typically placed near the root element on the html.
  2. ng-controller="RestaurantCtrl" - attaches a controller class to the view.
  3. ng-init="restaurants() – Evaluates the given expression, that can be used in the given scope.
  4. {{title}}Evaluates the value for the given variable declared inside controller, or any expression. E.g. {{5 + 1}}
  5. ng-model="location" – Binds the HTML control with the variable declared inside controller.
  6. ng-click="restaurants1()" – Binds the event with the method, defined inside controller. This event reloads the data from Web API, without refreshing the whole page.
  7. ng-repeat="rest in restaurants" – Used for looping, consider it like foreach loop.
  8. ng-disabled="queryDisabled" – Another angular directive that binds its value to a variable in Controller, for enabling/disabling any control.

Now we can link this page with our Home Page. Open the “_Layout.cshtml” file, given inside Views\Shared folder.

Replace the following links:

@Html.ActionLink("About", "About", "Home")
@Html.ActionLink("Contact", "Contact", "Home")

with:

@Html.ActionLink("Restaurants", "Restaurant", "Home")

For displaying ‘Restaurant’ page, we have to link it to our Home Controller as well. Open the HomeController.cs and add the following method in the last:

public ActionResult Restaurant()
{
	return View();
}

The above method would be called up from the changes that we have placed inside _Layout.cshtml, and this method would return the Restaurant.cshtml page that we added earlier.

Now you can build and run the application. If you visit the ‘Restaurants’ link available on the top of the Home Page, you can view something as follows (replace the port number (49944) with your local port).

As of now, this page is displaying data in raw format, or say variables given on the page are still not binded with the data received via Web API.

As a last task of the tip, we would add an Angular JS controller, that would connect this raw page with the data fetched from Web API.

Angular JS Controller

Right click on the Scripts folder and add a new folder, name it as ‘app’. Add a JavaScript file to this folder, and name it as restaurant-controller.js.

Place the following code inside the above JavaScript file:

angular.module("RestaurantApp", [])
.controller("RestaurantCtrl", function ($scope, $http) {
    $scope.restaurants = [];
    $scope.title = "";
    $scope.working = false;
    $scope.location = "Nashville, TN";
    $scope.type = "Fast Food";
    $scope.Count = 1;
    $scope.queryDisabled = true;

    $scope.restaurants = function () {
        $scope.working = true;
        $scope.title = "Loading Restaurants list...";
        $scope.restaurants = [];
        $scope.queryDisabled = true;

        $http.get("/api/restaurant", { params: 
	{ "location": $scope.location, "type": $scope.type } }).success
	(function (data, status, headers, config) {
            $scope.restaurants = data;
            $scope.title = "Displaying Restaurants list..."
            $scope.working = false;
            $scope.queryDisabled = false;
        }).error(function (data, status, headers, config) {
            $scope.title = data + status;
            $scope.working = false;
            $scope.queryDisabled = false;
        });
    };

    $scope.restaurants1 = $scope.restaurants;
}
);

Few points to be noted in the above code:

  1. $scope.location = "Nashville, TN"; - We have done some initialization in the code, these values would be visible on the UI when you run the application.
  2. $scope.queryDisabled = true; - This value is used for enabling/disabling the Requery button on the UI.
  3. $scope.restaurants1 = $scope.restaurants; - We have declared a new variable to bind it with the button, instead of using existing $scope.restaurants that is already binded with ng-init directive.
  4. params: { "location": $scope.location, "type": $scope.type } – Method to pass the parameters from Controller to Web API.

Now you have to just link the above Controller with Restaurant.cshtml file that we created earlier. Open Restaurant.cshtml file and add the highlighted script:

@section scripts {
    @Scripts.Render("~/Scripts/angular.js")
    @Scripts.Render("~/Scripts/app/restaurant-controller.js")
}

Now just build and run the application. Click on the Restaurants link, it should display the following view:

History

  • 30th April, 2015: Initial version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here