Monday, March 15, 2010

Calling web service using javascript. Part - 1

Many a times there was this pressing need where I had to call a web service method and get the output and use it in javascript. There were many options available like making use of javascript to call web service method or using some third party javascript library or by making use of webservice behavior (HTML Component (HTC) file) or making use of AJAX and calling an ASPX page which in turn calls a webservice in the code behind and returns the output as XML or if you are using ASP.NET 2.0 then you can make use of “ScriptManager”. We will see all the above ways of invoking a webservice one by one except making use of third party javascript library. As there are many third party javascript libraries available in the internet so we will not concentrate on any as each have different ways of implementation.  Lets see each of the methods in action one by one.

Using javascript to invoke web service methods

One of the simplest and easiest way is to invoke web service methods is by making use of “XMLHttpRequest” objects in javascript. Before invoking the web service method using javascript lets see the web service methods which we are going to be invoked using javascript. Below are two sample methods which we are going to be invoked using javascript.

public class TestService : System.Web.Services.WebService
{
        [WebMethod]
        public string HelloWorld()
        {
            return "Hello World";
        }
        [WebMethod]
        public string CombineName(string firstName, string midleName, string lastName)
        {
            return string.Concat(string.Concat(firstName, " - ", midleName), " - ", lastName);
        }
}

The above two methods are pretty straight forward, one returns a string and the other takes three string arguments and combines them and returns as a string. We will see how to call a web service method without parameters and with parameters. Lets first see how to call the “HelloWorld” web method which doesn’t take any parameter. Below is the javascript code for invoking the “HelloWorld” web method.

function webServiceCallWithoutParameters()
{
        var xmlHttpReq = new XMLHttpRequest();
        xmlHttpReq.open("POST", "http://localhost/TestService.asmx/HelloWorld", false);       
        xmlHttpReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        xmlHttpReq.send();       
        alert(xmlHttpReq.responseXML.childNodes[1].text);
}

In the above javascript function we are making use of “XMLHttpRequest” object to invoke web service method. We are making use of the “open” method which takes three arguments, first argument says whether the method used is “POST” or “GET”, second argument is the url for the web service and the third argument is to specify whether the “XMLHttpRequest” should be synchronous or asynchronous. The url for a .NET web method always ends with the name of the web method preceded by the url of the web service as shown in the above e.g. Once we have set the url and the method used to call the web service, in the next line we are setting the “Content-Type” for the request using the “setReqeustHeader” method of the “XMLHttpReqeust” object. Its very important to set the “Content-Type” of the request to “application/x-www-form-urlencoded” when you are trying to invoke a web service method, if the “Content-Type” is not set to “application/x-www-form-urlencoded” the following error will be thrown when you try to pass arguments to a web service method.

status: 500
statusText: Internal Server Error
responseText: System.InvalidOperationException: Request format is invalid: . at System.Web.Services.Protocols.HttpServerProtocol.ReadParameters() at System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()

The status property of the “XMLHttpReqeust” object will have a value of 500, the “statusText” will be having “Internal Server Error” as the message and the “responseText” will have the type of error. To solve the problem set the “Content-Type” for the request as shown in the above e.g.

Now let’ see how to pass parameters to a web method.

var xmlHttpReq = new XMLHttpRequest();
xmlHttpReq.open("POST", "http://localhost:3150/TestService.asmx/CombineName", false);
xmlHttpReq.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xmlHttpReq.send("firstName=Sandeep&midleName=mid&lastName=p r");
alert(xmlHttpReq.responseXML);

In the above javascript function we are invoking the “CombineName” web method which takes three parameters. Everything else is the same as the previous javascript function except for the “send” method of the “XMLHttpReqeust” object. In the “send” method we are passing the parameters separated by the ampersand (&) symbol. To pass parameter to a web method you can use the “send” method of the “XMLHttpRequest” object. The parameters and their values should be separated by the “equal to” (=) symbol and each set of parameters should be separated by the ampersand symbol.

After this the next obvious question would be how to send complex objects to a web methods. There is no straight forward way of doing this, one can make use of Javascript Object Notations (JSON). You can find lots of e.g. on how to pass JSON over the net. Also you can use “WebService” behavior (HTC file) to send and receive complex objects or one can use “ScriptManager” to send and receive complex objects. We will see “HTC file” and “ScriptManager” usage in subsequent blogs. Receiving a complex object is pretty easy. When you invoke a web method and if that web method returns a complex object then the object will be serialized into a XML and the XML can be accessed through the “responseText” or “responseXML” property of the “XMLHttpRequest” object. Lets see with an e.g. Below is the web method code which returns a “Car” complex object.

[WebMethod]
public Car GetCarObject()
{
     return new Car { Model = "Ferrari", Color = "Ferrari Red", CC = 2555 };
}

//Car Class is pasted below.

public class Car
{
    public string Model
    {
        get;   set;
    }
    public int CC
    {
        get;   set;
    }
    public string Color
    {
        get;   set;
    }
}

The above web method is pretty straight forward. It creates an instance of a “Car” class and returns the same. The “Car” class is also pasted. The javascript method to invoke the above web method which returns “Car” complex object is pasted below.

function getComplexObject()
{
    var xmlHttpReq = new XMLHttpRequest();
    xmlHttpReq.open("POST", "http://localhost:3150/TestService.asmx/GetCarObject", false);
    xmlHttpReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    xmlHttpReq.send();
    alert(xmlHttpReq.responseText);
}

The output returned in the form of the XML is pasted below.

<?xml version="1.0" encoding="utf-8"?>
<Car xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/">
  <Model>Ferrari</Model>
  <CC>2555</CC>
  <Color>Ferrari Red</Color>
</Car>

As you can see in the above XML the complex object returned by the web method is serialized as XML. That's about invoking web methods using javascript. In my next blog we will see how to invoke web methods using “WebService behviour” or by using “HTC file”. Till then try to know more.

Sandeep

8 comments:

  1. This is excellent - just what I was looking for.
    Works great and very simple to invoke the webservice from javascript.
    Thank you for posting this.

    ReplyDelete
  2. Hi.
    This looks like the tutorial im after :)
    But im having a problem,,, I'm always getting null in return.
    I have used the simple code from the top but it always returns null....
    Can you help me with this?

    ReplyDelete
    Replies
    1. Hi Paal,
      Sure. If you can mail me your solution I can help you with the problem.

      Delete
  3. hi

    can u tell me how to call webservices in javascript

    ReplyDelete
  4. Thanks very much for this. Exactly what I was looking for. Sending warm thoughts to you!

    ReplyDelete
  5. calling HelloWorld() is not working in firfox. Please help me with this.

    Lepak V

    ReplyDelete
  6. holas que tal cuando trato de consumir el servicio web me sale este error "origin null is not allowed by Access.
    control allow origin" mmm con ambos ejemplos q pusite :( ayuda

    ReplyDelete
  7. nice work done... we can also look at http://www.morgantechspace.com/2014/04/Call-WebsService-from-JavaScript-with-and-without-jquery.html

    ReplyDelete

Please provide your valuable comments.