Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Consuming JSON ASMX Web Services with AngularJS: A Beginners Experience !

4.97/5 (20 votes)
7 Jan 2015CPOL3 min read 126.2K   2.6K  
A step by step tutorial showing how to consume an ASMX Service from an application using AngularJS, highlighting common pitfalls.

Introduction

This article will explain how to consume an ASMX service using AngularJS. The scope of this article is limited to illustrate a simple example of creating and consuming JSON ASMX services using AngularJS. Pitfalls personally faced by the author, being new to both Web Services and AngularJS, are highlighted in this article to spare our fellow beginners the "start-up" agony. It is to be noted that ASMX web service is now a legacy technology. Recently, more advanced technologies are used to build Web Services with better performance.

To build our sample application, we have used AngularJS version 1.2.16. This article demonstrates how AngularJS will retrieve a list of Questions from a database. The ASMX web service is hosted in the same web application. In this example, I used ASPX Webform and an MSAccess backend, but you can use HTML page instead of the Webform and, of course, any database.

For calling the service, we need to use the $http.get() method of AngularJS, which sends a Request to the server. The ASMX service then sends a response in JSON format, that will be parsed and consumed in AngularJS.

Definitions

JSON (JavaScript Object Notation) is a lightweight, language independent, data-interchange format. JSON is syntax for storing and exchanging text information. JSON is smaller than XML, faster and easier to parse. [1,2]

A Web Service is a method of communication between two electronic devices over any network. It is designed to allow applications built using different technologies to communicate with each other using international standards.

AngularJS "lets you extend HTML vocabulary for your application. The resulting environment is extraordinarily expressive, readable, and quick to develop." [3]

Using the Code: Step by Step

The business logic of the sample application is quite simple. The QuestionID and QuestionText were stored in Questions table in Quiz.mdb. When the service Web Method is invoked, the service connects to the database, retrieves a list of questions as a DataTable, uses System.Web.Script.Serialization.JavaScriptSerializer() method to Convert DataTable to JSON String, and finally, supplies a list of Questions to be returned in JSON format.

Step (1) Create a New Web Application

Create a new Web Site, then create a new ASMX Web Service and a new WebForm or new HTML page.

Step (2) Create a Simple Database

In this example, I used MSAccess. You can use any database, of course. you will only need to change the connection string.

Image 1

Step (3) Write the Code for your Business Logic

C#
// in this sample, and as described in the article, 
// this is a simple method that will connect to the database, 
// execute an SQL command and return data in form of a DataTable 
public DataTable GetDataTable()
    {
        DataTable dataTable = new DataTable();
        using (OleDbConnection conn = new OleDbConnection
        ("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=|DataDirectory|Quiz.mdb"))
        {
            OleDbCommand cmd = conn.CreateCommand();
            cmd.CommandText = "select * from Questions";

            cmd.CommandType = CommandType.Text;

            if (conn.State != ConnectionState.Open)
                conn.Open();

            OleDbDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);

            dataTable.Load(dr);
        }
        return dataTable;
    }
//once the datatable is ready, it has to be converted to JSON to be consumable with AngularJS, 
//the following function uses Javascript serializer to do the conversion

    public String ConvertDataTableTojSonString(DataTable dataTable)
    {
        System.Web.Script.Serialization.JavaScriptSerializer serializer =
               new System.Web.Script.Serialization.JavaScriptSerializer();

        List<Dictionary<String, Object>> tableRows = new List<Dictionary<String, Object>>();

        Dictionary<String, Object> row;

        foreach (DataRow dr in dataTable.Rows)
        {
            row = new Dictionary<String, Object>();
            foreach (DataColumn col in dataTable.Columns)
            {
                row.Add(col.ColumnName, dr[col]);
            }
            tableRows.Add(row);
        }
        return serializer.Serialize(tableRows);
    }  

Step (4) Setup your [WebMethod]

The definition of the Web Method makes it enabled for invoking. Also setup the Response.ContentType to be in JSON format.

C#
[WebService(Namespace = "AnyNameSpace")]

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, 
// uncomment the following line. 
[System.Web.Script.Services.ScriptService]
public class WebService : System.Web.Services.WebService

{  
// Business Logic Code goes here

[WebMethod] // by writing this line, you tell your service to enable this method / function 
  //for public consumption. If you remove this line, the method can not be invoked.
    [ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
    public void HelloWorld()
    {
        JavaScriptSerializer js = new JavaScriptSerializer();
        Context.Response.Clear();
        Context.Response.ContentType = "application/json";
        HelloWorldData data = new HelloWorldData();
        data.Message = ConvertDataTableTojSonString(GetDataTable());
        Context.Response.Write(js.Serialize(data.Message));
    }

    public class HelloWorldData
    {
        public String Message;
    }
}

Step (5) Test your Web Service

Run the Code and Click "Invoke". If you have done everything properly, you should see a message like this:

Image 2

It is important to note that you have to use the data.Message not only data in HelloWorld()

Image 3

If, you use data not data.Message you will not get an error (initially), but you will experience a run time error because AngularJS will fail to parse it.

Step (6) Define the Configuration in web.config

Define the webServices protocols under the section <system.web>.

C++
<webServices>
   <protocols>
        <add name="HttpGet"/>
        <add name="HttpPost"/>
   </protocols>
</webServices> 

Failing to configure the webServices section properly might lead to the following error:

Image 4

Step (7) Prepare Your WebForm (or HTML Page)

The Directive ng-app is used to "auto-bootstrap" an AngularJS application. The questionsController will get the data from the $scope, which in turn gets its data from $http.get() function and parses the message content using JSON.parse() method. Pitfalls include the wrong placing of directives and the improper parsing of JSON.

HTML
<html ng-app="serviceConsumer">
<head runat="server">
    <title>consume JSON web service</title>
    <script src="js/angular.js"></script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <div ng-controller="questionsController">
            search:<input type="text" ng-model="search" />
            <table>
                <tr ng-repeat="i in questions | filter:search">
                    <td>
                        {{i.QuestionID}}
                    </td>
                    <td>
                        {{i.QuestionText }}
                    </td>
                </tr>
            </table>
        </div>
        <br />
    </div>
    <script>

        var app = angular.module('serviceConsumer', []);

        app.controller('questionsController', function ($scope, $http) {

            var url = "WebService.asmx/HelloWorld";

            $http.get(url)
                       .success(function (data) {

                           var myjson = JSON.parse(data);

                           $scope.questions = JSON.parse(myjson);

                       })
        })
                         
    </script>
    </form>
</body>
</html>  

Step (8) Running Your Application on a different Domain

If you run your service consuming application on a domain different from the domain providing the webservice, you might face an "Access-Control" error.

Image 5

In this case, adding the following section to Web.config will solve this issue.

XML
<system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*"/>
        <add name="Access-Control-Allow-Headers" value="Content-Type"/>
      </customHeaders>
    </httpProtocol>
  </system.webServer>

 

References

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)