Thursday, September 27, 2012

Basics of Web Service in ASP.NET

Understanding the Basics of Web Service in ASP.NET 

Introduction

This article aims at understanding the need for a web service, the benefits of having a web service and how we can create a basic web service and consume it.

Background

Connectivity between applications is very important. Connectivity in any case is very important for that matter but it specially is very important between applications. Connecting web application used to be a big challenge before the advent of technologies like SOAP (Simple Object Access Protocol). The reason it was so difficult was, there were so many technologies people were working in. The applications were hosted on different types of servers, etc. But these things should not be a barrier to facilitate the communication between applications. The only requirement was to have some standards to follow and standard ways of doing things so that the applications become capable of communicating with other applications irrespective of the technologies used.

SOAP and Web Services

SOAP and XML created the solution for the problem that developers were facing before. SOAP is a standard XML based protocol that communicated over HTTP. We can think of SOAP as message format for sending messaged between applications using XML. It is independent of technology, platform and is extensible too.
We have SOAP and XML to give us connectivity between applications. Does it mean that I have to write XML and SOAP specific things myself to facilitate this communications? I could do that but that will be very time consuming and sometimes error prone too.
Where does Web Services come in picture? Well, Web services is the mechanism that ASP.NET framework provides to make it easy for us to write code to facilitate connectivity between applications. As ASP.NET developer, If I need an application that will be used by many other applications then I can simply decide to write a web service for it and ASP.NET framework will take care of doing the low level SOAP and XML work for us.
The other side of the coin is, if our ASP.NET application wants to use a web service, i.e., an application that is providing me SOAP based interface for communication. So what we are going to do now is write a small Web service to see how we can have our application communication-ready for other applications and secondly, we will try to consume a webservice to understand how we can use other applications from our application.
Web service article image

Creating a Web Service

Let us write a simple module that will provide basic arithmetic operations to other applications. The user of our application will have to provide us 2 numbers and we will perform the requested operation like Addition, Subtraction and Multiplication.
So, the first thing we need to do is to create our web service. We can do this by creating a website of type ASP.NET Web service. This will give us a skeleton to write our web service code in.
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Service : System.Web.Services.WebService
{
    public Service () {

        //Uncomment the following line if using designed components
        //InitializeComponent();
    }

    [WebMethod]
    public string HelloWorld() {
        return "Hello World";
    }
}
The attribute WebService tells that this class contains the code for web service. The namespace is what is used to identify the web service. The WebMethod attribute specifies the methods which our web service is providing.
Let us now go ahead and write code to have our functions in this webservice.
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class Service : System.Web.Services.WebService
{
    public Service ()
    {
        //Uncomment the following line if using designed components
        //InitializeComponent();
    }

    [WebMethod]
    public int Add(int x, int y)
    {
        return x+y;
    }

    [WebMethod]
    public int Subtract(int x, int y)
    {
        return x - y;
    }

    [WebMethod]
    public int Multiply(int x, int y)
    {
        return x * y;
    }
}
We have a very basic web service implemented which can let the user have some basic arithmetic operations. Now to create the WebService binary, we will have to use the following command on Visual Studio Command Prompt.
>CSC /t:library /out:ArithmeticServiceImpl.dll App_code\Service.cs
This will create a DLL file for our web service. This DLL file can be used by any client by using the SOAP protocol. If we need to test our web service for how it works over the SOAP protocol, we can view the service.asmx file in the browser and see what functions our web service is exposing.
Web service article image
We can even test these methods here and see the XML file that contains the service description.

Consuming a WebService

There are three ways we can consume a WebService:
  1. Using HTTP-POST method.
  2. Using XMLHttp that will use SOAP to call our the service
  3. Using WSDL generated proxy class
The HTTP-Post method can be used by calling .asmx file directly from client. We can directly use the method name and the parameter names will be taken from our input fields on form.
<html>
    <body>
        <form action="http://localhost/.../Service.asmx/Multiply"  method="POST">
                <input name="x"></input>
                <input name="y"></input>

                <input type="submit" value="Enter"> </input>
        </form>
    </body></html>
When this form get submitted, the web service's method will be called. The second method where we can use theXMLHttp over SOAP to access the webservice is used when we want to use the web service using full capability of SOAP.
The third way of using the web service is by generating a Proxy class for the web service and then using that proxy class. This method is, to me, more type safe and less error prone as once we have the proxy class generated, it can take care of SOAP messages, serialization and ensure that all the problems can be handled at compile time instead of runtime.
To use this service, we need to do "Add Web reference" and add the webservice reference. Alternatively I can also useWSDL.exe, a command line tool, to generate the proxy classes and use them. "Add web Reference" is also using the same WSDL.exe to generate the proxy classes.
Web service article image
Now let us write some code to use the proxy class to perform the operations, the proxy class will then communicate to the web service using SOAP and get back the results to us.
protected void Button1_Click(object sender, EventArgs e)
{
    if (txtX.Text != string.Empty
        && txtY.Text != string.Empty)
    {
        try
        {
            int x = Convert.ToInt32(txtX.Text);
            int y = Convert.ToInt32(txtY.Text);

            ArithmeticService.Service service = new ArithmeticService.Service();

            Label1.Text = "Sum: " + service.Add(x, y).ToString();
            Label2.Text = "Difference: " + service.Subtract(x, y).ToString();
            Label3.Text = "Multiplication: " + service.Multiply(x, y).ToString();
        }
        catch(Exception)
        {
            throw;
        }
    }
}
Let us run the website to see the results
Web service article image

Points of Interest

We saw how to create a web service in ASP.NET and how we can consume a web service in ASP.NET. One interesting area that we did not see here is how we can use web service from AJAX. ASP.NET also provides a mechanism usingscriptManager that will generate the JavaScript proxy for a webservice and we can use it to call the webservice methods. Also, if we want to customize the security of our web service, we can do that too using custom SOAP headers.

Understanding Windows Communication Foundation (WCF)


A Beginner's Tutorial for Understanding Windows Communication Foundation (WCF)

Introduction

This article is an introduction to the Windows Communication Foundation (WCF). We will try to see the basic concepts behind WCF and will try to implement a small WCF service. We will also work out some small examples of how a WCF service can be consumed.

Background

Like I said in my earlier article on Web Services, communication between applications is very important. Web services provide an efficient way of facilitating communication between applications. But there are limitations with web services too. The major limitation with web services is that the communication can happen over HTTP only. A second limitation with web services is that it provides singlex communication and there is no way to have half duplex or full duplex communication using web services.
Windows Communication Foundation (WCF) comes to the rescue when we find ourselves not able to achieve what we want to achieve using web services, i.e., other protocols support and even duplex communication. With WCF, we can define our service once and then configure it in such a way that it can be used via HTTP, TCP, IPC, and even Message Queues. We can consume Web Services using server side scripts (ASP.NET), JavaScript Object Notations (JSON), and even REST (Representational State Transfer).
The following table illustrates the differences between a web service and a WCF service:
Web ServiceWCF Service
Communication can happen over HTTP onlyCommunication can happen over HTTP, TCP, IPC, or even MSMQ.
Only Singlex and request-response communication is possibleIt can be configured to have singlex, request-response, or even full duplex communication.
They work in an stateless fashion over HTTP and are hosted inside a web server like IISThese can be hosted in many ways inside IIS, inside a Windows service, or even self hosted.
Note: Apart from these differences, there are other differences related to instance management, sessions, and data representation and serialization. We will not discuss these here as they tend to be digressing for beginners.
A WCF service can be visualized as:
wcf artcile image

Understanding the basics

When we say that a WCF service can be used to communicate using different protocols and from different kinds of applications, we will need to understand how we can achieve this. If we want to use a WCF service from an application, then we have three major questions:
  1. Where is the WCF service located from a client's perspective?
  2. How can a client access the service, i.e., protocols and message formats?
  3. What is the functionality that a service is providing to the clients?
Once we have the answer to these three questions, then creating and consuming the WCF service will be a lot easier for us. The WCF service has the concept of endpoints. A WCF service provides endpoints which client applications can use to communicate with the WCF service. The answer to these above questions is what is known as the ABC of WCF services and in fact are the main components of a WCF service. So let's tackle each question one by one.
Address: Like a webservice, a WCF service also provides a URI which can be used by clients to get to the WCF service. This URI is called as the Address of the WCF service. This will solve the first problem of "where to locate the WCF service?" for us.
Binding: Once we are able to locate the WCF service, we should think about how to communicate with the service (protocol wise). The binding is what defines how the WCF service handles the communication. It could also define other communication parameters like message encoding, etc. This will solve the second problem of "how to communicate with the WCF service?" for us.
Contract: Now the only question we are left up with is about the functionalities that a WCF service provides. Contract is what defines the public data and interfaces that WCF service provides to the clients.

Using the code

As an ASP.NET developer, we will find ourselves in the need of using a WCF service or perhaps write a WCF service. What we will do next is to implement a small WCF service and see how the ABC of WCF is to be implemented. We will then write a small application to consume this WCF service.
The service that we will create will provide arithmetic operations on a Pair data type. This Pair type will also be exposed by our service to the applications. We will simply provide addition and subtraction functionality for the Pairdata type.
Note: We will host this WCF service inside an ASP.NET website, i.e., IIS hosting, and will be consuming it from an ASP.NET website. So let us create an empty ASP.NET website and then add a WCF service to it.
wcf artcile image

Creating a WCF Service

Let us start by looking at the Contract part of the WCF service. We need to expose a Pair data type from our service so this class will have to be decorated with the DataContract attribute. This attribute specifies that this data type can be used by consumers of this WCF service. Also, the public properties of this class will have to be decorated with theDataMember attribute to specify that clients can use these properties and to indicate that they will be needing serialization and deserialization.
[DataContract]
public class Pair
{
    int m_first;
    int m_second;

    public Pair()
    {
        m_first = 0;
        m_second = 0;
    }

    public Pair(int first, int second)
    {
        m_first = first;
        m_second = second;
    }

    [DataMember]
    public int First
    {
        get { return m_first; }
        set { m_first = value; }
    }

    [DataMember]
    public int Second
    {
        get { return m_second; }
        set { m_second = value; }
    }
}
Now we have specified the Data contract that our service is exposing. The next thing is to specify the service contracts and major operations of this service. Let us create an interface that will list the major functionalities provided by this service. We will then have to decorate this interface with the ServiceContract attribute to specify that this interface is being exposed by this service and can be used by the clients.
We will then have to write methods for all major operations provided by this service and decorate them with theOperationContract attribute to specify that these operations of this interface can be used by the clients.
public interface IPairArihmeticService
{
    [OperationContract]
    Pair Add(Pair p1, Pair p2);

    [OperationContract]
    Pair Subtract(Pair p1, Pair p2);
}
Now we have specified all the DataContractServiceContract, and the OperationContract of our small service. Now the major thing left in this service is to implement the functionalities. To do that, let's have a small class that will implement the interface we just created.
public class PairArihmeticService : IPairArihmeticService
{
    Pair IPairArihmeticService.Add(Pair p1, Pair p2)
    {
        Pair result = new Pair();

        result.First = p1.First + p2.First;
        result.Second = p1.Second + p2.Second;

        return result;
    }

    Pair IPairArihmeticService.Subtract(Pair p1, Pair p2)
    {
        Pair result = new Pair();

        result.First = p1.First - p2.First;
        result.Second = p1.Second - p2.Second;

        return result;
    }
}
Let us try to visualize what we have done so far. This class diagram will show the classes we created so far and decorated them with attributes to specify the data contract, service contract, and operation contracts.
wcf artcile image
We have our Contract part declared and defined. Now let us see how we can configure the other things. We need to make this service visible to the client applications and let the client applications extract the meta data information out of this service. To do this we need to specify the service behavior in the web.config.
<system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
The important thing to notice here is the httpGetEnabled="true" which enables this service to provide its meta data when a client requests for it. Now let us build this website to build our WCF service. Let us set the .SVC file as the start page and run the website to see what happens.
wcf artcile image

Consuming a WCF Service

We have seen how to create a WCF service. Let us now see how we can consume a WCF service. Let us start by adding a default ASP.NET website in the same solution. We then need to add a service reference to the WCF service we just created.
wcf artcile image
Adding this service reference will mainly do two things:
  1. Create the Address and Binding part to access this service in the web.config file.
  2. Create the proxy class for us to access the service.
So let us first look at the Address and Binding in the web.config to complete the ABC part of the WCF service.
<system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_IPairArihmeticService"/>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://localhost:1062/WcfTestWebSite/PairArihmeticService.svc" 
          binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IPairArihmeticService" 
          contract="PairServiceReference.IPairArihmeticService" 
          name="BasicHttpBinding_IPairArihmeticService"/>
    </client>
</system.serviceModel>
This web.config shows the address of the WCF service, the binding to use the webservice, and the contract that is being exposed by this web service. All this was generated by extracting the meta data from the service.
Now let us look at how to use the proxy class that was generated. We will use this proxy class to call the methods of the WCF service and then extract the results out of it.
PairServiceReference.Pair p1 = new PairServiceReference.Pair();
p1.First = Convert.ToInt32(txtP1First.Text);
p1.Second = Convert.ToInt32(txtp1Second.Text);

PairServiceReference.Pair p2 = new PairServiceReference.Pair();
p2.First = Convert.ToInt32(txtP2First.Text);
p2.Second = Convert.ToInt32(txtp2Second.Text);

PairServiceReference.PairArihmeticServiceClient pairServiceClient = 
           new PairServiceReference.PairArihmeticServiceClient();
PairServiceReference.Pair addResult = pairServiceClient.Add(p1, p2);

PairServiceReference.Pair minusResult = pairServiceClient.Subtract(p1, p2);

lblsum.Text = addResult.First.ToString() + ", " + addResult.Second.ToString();
lblminus.Text = minusResult.First.ToString() + ", " + minusResult.Second.ToString();
Note: The above code snippet refers to control IDs. Please see the source code for that.
Now we have successfully consumed the WCF service from our ASP.NET website. Before we wrap up, let us now build this web site and see the results.
wcf artcile image
Note: While using the source code, the service reference will have to be updated to added again as the address of the service that was being used was specific to my system. It could differ on other systems.

Points of interest

What we have tried to do here is to understand some basic concepts of a WCF service. We created a sample WCF service. We have also created a sample website to consume the WCF service.
There are various alternatives when it comes to hosting, accessing, and using a WCF service. We have only looked at one particular way. One good exercise would be to change this service to make it accessible via AJAX. It is more like a WCF service involves some code and some configuration. If we need to use different sets of ABCs for this service, then the code (logic) will not change, the only change that will be required is in the configurations.



Example 2:


WCF Basics :


IService.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace sampleWCF
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.

   [ServiceContract(Namespace = "")]
    public interface IAddService
    {
        [OperationContract(Name = "IGetdata")]
        CaseResponse IGetdata(CaseRequest getdata);

    }

    [MessageContract]
    public class userRequest
    {
        [MessageHeader(Name="hai")]
        public int  intNo1;
        [MessageHeader]
        public int  intNo2;
        
    }

    
    [MessageContract]
    public class CaseRequest
    {
        [MessageHeader]
        public int no1;
        [MessageHeader]
        public int no2;
        
    }

    [MessageContract]
    public class CaseResponse
    {
        [MessageBodyMember]
        public int result;
    }


}




Service1.svc.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace sampleWCF
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
    public class Service1 : IAddService
    {
       

        #region IAddService Members

        
        public CaseResponse IGetdata(CaseRequest getdata)
        {

            int noc = 0;
            CaseResponse result = new CaseResponse();

                    try
            {

                int noa = getdata.no1;
                int nob = getdata.no2;

                userRequest obj = new userRequest();
                obj.intNo1 = noa;
                obj.intNo2 = nob;
                noc = IAdd(obj);        
                result.result = noc;
                
            }
            catch (Exception ex)
            {

                return result;
  
            }

            return result;

        }


        public int IAdd(userRequest AddData)
        {

            return AddData.intNo1 + AddData.intNo2;

        }

        #endregion
    }
}



Webform1.aspx

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using sampleWCF.ServiceReference1;

namespace sampleWCF
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            
            int result = 0;

         //   ServiceReference1.IAddService obj = new ServiceReference1.IAddService();
            
            Service1 obj = new Service1();
            
          //  result=obj.

            CaseRequest  objCaseRequest = new CaseRequest();

            objCaseRequest.no1 = 7;
            objCaseRequest.no2 = 9;
         
            result =Convert.ToInt16(obj.IGetdata(objCaseRequest).result);             


        }
    }
}