Saturday 3 August 2019

Call (Consume) REST WCF Service (SVC) using AngularJS in ASP.Net with C# and VB.Net

In this article I will explain with an example, how to call (consume) REST WCF Service (SVC) using AngularJS in ASP.Net with C# and VB.Net.
This article also explains how to modify the WCF Service (SVC) configuration in order to make it accessible via AngularJS and AJAX in ASP.Net.
 
 
Database
For database I am using the Microsoft’s Northwind Database. You can download the same using the link below.
 
 
Adding Service to Project
The very first thing you need to do is add a WCF service to your project by clicking on Add New Items as shown below.
Call (Consume) REST WCF Service (SVC) using AngularJS in ASP.Net with C# and VB.Net
 
 
Configuring the WCF Service
We need to make some configuration changes to the ASP.Net WCF service in order to make it available to jQuery and JavaScript.
1. Adding AspNetCompatibilityRequirements Attribute
The AspNetCompatibilityRequirements attribute needs to be added for the Service class in order to make the WCF service behave like an ASP.Net Web Service (ASMX) and will able to process requests via HTTP POST calls made using AJAX.
 
C#
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Service : IService
{
}
 
VB.Net
<ServiceContract()> _
<AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Allowed)> _
Public Class Service
 
End Class
 
2. Adding ASP.Net AJAX endpoint behavior
A new Endpoint Behavior named ServiceAspNetAjaxBehavior is added to the Web.Config. This behavior will set the binding to WebHttpBinding, which is very important in order to accessing WCF Service using HTTP methods.
C#
<system.serviceModel>
      <behaviors>
            <serviceBehaviors>
                  <behavior name="ServiceBehavior">
                        <serviceMetadata httpGetEnabled="true"/>
                        <serviceDebug includeExceptionDetailInFaults="true"/>
                  </behavior>
            </serviceBehaviors>
        <endpointBehaviors>
            <behavior name="ServiceAspNetAjaxBehavior">
                <enableWebScript />
            </behavior>
        </endpointBehaviors>
      </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
    <services>
            <service behaviorConfiguration="ServiceBehaviorname="Service">
                  <endpoint address="" binding="webHttpBindingcontract="IServicebehaviorConfiguration="ServiceAspNetAjaxBehavior">
                  </endpoint>
                  <endpoint address="mexbinding="mexHttpBindingcontract="IMetadataExchange"/>
            </service>
      </services>
</system.serviceModel>
 
 
Building the WCF Service Method
The IService Interface has a method GetCustomers which is decorated with OperationContract attribute.
The IService Interface has been implemented in a class named Service which contains the definition of the GetCustomers method.
This method accepts prefix parameter and gets all records from the Customers Table of the Northwind Database which matches the prefix parameter.
The records are fetched using SqlDataReader and are populated into JSON object array.
Finally the JSON object array is returned back in the form of serialized JSON string.
C#
IService.cs
using System;
using System.ServiceModel;
using System.ServiceModel.Web;
 
[ServiceContract]
public interface IService
{
    [OperationContract]
    string GetCustomers(string prefix);
}
 
Service.cs
using System;
using System.ServiceModel;
using System.Configuration;
using System.Data.SqlClient;
using System.Collections.Generic;
using System.ServiceModel.Activation;
using System.Web.Script.Serialization;
 
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Service : IService
{
      public string GetCustomers(string prefix)
      {
        List<object> customers = new List<object>();
        string sql = "SELECT * FROM Customers WHERE ContactName LIKE @prefix + '%'";
        using (SqlConnection conn = new SqlConnection())
        {
            conn.ConnectionString = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
            using (SqlCommand cmd = new SqlCommand(sql))
            {
                cmd.Parameters.AddWithValue("@prefix", prefix);
                cmd.Connection = conn;
                conn.Open();
                using (SqlDataReader sdr = cmd.ExecuteReader())
                {
                    while (sdr.Read())
                    {
                        customers.Add(new
                        {
                            CustomerId = sdr["CustomerId"],
                            Name = sdr["ContactName"],
                            Country = sdr["Country"]
                        });
                    }
                }
                conn.Close();
            }
            return (new JavaScriptSerializer().Serialize(customers));
        }
    }
}
 
VB.Net
IService.vb
Imports System.ServiceModel
 
<ServiceContract()>
Public Interface IService
 
    <OperationContract()>
    Function GetCustomers(ByVal prefix As StringAs String
 
End Interface
 
Service.vb
Imports System.ServiceModel
Imports System.Configuration
Imports System.Data.SqlClient
Imports System.Collections.Generic
Imports System.ServiceModel.Activation
Imports System.Web.Script.Serialization
<AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Allowed)> _
Public Class Service
    Implements IService
    Public Function GetCustomers(ByVal prefix As StringAs String Implements IService.GetCustomers
        Dim customers As New List(Of Object)()
        Dim sql As String = "SELECT * FROM Customers WHERE ContactName LIKE @prefix + '%'"
        Using conn As New SqlConnection()
            conn.ConnectionString = ConfigurationManager.ConnectionStrings("constr").ConnectionString
            Using cmd As New SqlCommand(sql)
                cmd.Parameters.AddWithValue("@prefix", prefix)
                cmd.Connection = conn
                conn.Open()
                Using sdr As SqlDataReader = cmd.ExecuteReader()
                    While sdr.Read()
                        customers.Add(New With { _
                             .CustomerId = sdr("CustomerId"), _
                             .Name = sdr("ContactName"), _
                             .Country = sdr("Country") _
                        })
                    End While
                End Using
                conn.Close()
            End Using
            Return (New JavaScriptSerializer().Serialize(customers))
        End Using
    End Function
End Class
 
 
Client Side AJAX JSON Call using AngularJS
The below HTML Markup consists of an HTML DIV to which ng-app and ng-controller AngularJS directives have been assigned.
The HTML DIV consists of an HTML TextBox, Button and Table which will be populated from JSON array using ng-repeat directive.
Note: If you want to learn more about these directives please refer my article Introduction to AngularJS.
 
The Button has been assigned ng-click directive. When the Button is clicked, the Search function of the Controller gets called.
Note: If you want to learn more about ng-click directive, please refer my article ng-click directive example.
 
Inside the Search function, the $http service is used to make an AJAX call to the WCF Service’s method. The $http service has following properties and methods.
Properties
1. method – The method type of HTTP Request i.e. GET or POST.
2. url – URL of the WCF Service along with its method.
3. dataType - The format of the data i.e. XML or JSON.
4. data – The parameters to be sent to the WCF Service’s method i.e. the Prefix TextBox value.
5. headers - List of headers to be specified for the HTTP Request.
 
Event Handler
1. success – This event handler is triggered once the AJAX call is successfully executed.
2. error – This event handler is triggered when the AJAX call encounters an error.
The response from the AJAX call is received in JSON format inside the Success event handler of the $http service. It is assigned to the Customers variable.
The ng-repeat directive as the name suggests repeats the element based on the length of the collection, in this scenario it will repeat the TR element (HTML Table Row).
The TBODY element of the HTML Table has been assigned ng-repeat directive in order to iterate through all the items of the Customers JSON array.
For each JSON object in the Customers JSON array, a TR element (HTML Table Row) is generated and appended into the HTML Table.
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
<body>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular.min.js"></script>
    <script type="text/javascript">
        var app = angular.module('MyApp', [])
        app.controller('MyController'function ($scope, $http, $window) {
            $scope.IsVisible = false;
            $scope.Search = function () {
                var post = $http({
                    method: "POST",
                    url: "Services/Service.svc/GetCustomers",
                    dataType: 'json',
                    data: { prefix: $scope.Prefix },
                    headers: { "Content-Type""application/json" }
                });
 
                post.success(function (data, status) {
                    $scope.Customers = eval(data.d);
                    $scope.IsVisible = true;
                });
 
                post.error(function (data, status) {
                    $window.alert(data.Message);
                });
            }
        });
    </script>
    <div ng-app="MyApp" ng-controller="MyController">
        Name:
        <input type="text" ng-model="Prefix" />
        <input type="button" value="Submit" ng-click="Search()" />
        <hr />
        <table cellpadding="0" cellspacing="0" ng-show="IsVisible">
            <tr>
                <th>Customer Id</th>
                <th>Name</th>
                <th>Country</th>
            </tr>
            <tbody ng-repeat="m in Customers">
                <tr>
                    <td>{{m.CustomerId}}</td>
                    <td>{{m.Name}}</td>
                    <td>{{m.Country}}</td>
                </tr>
            </tbody>
        </table>
    </div>
</body>
</html>

No comments:

Post a Comment