Wednesday 13 January 2010

How to call WebService/ScriptService from javascript


Web service/Script Service:
With the release of .Net framework 3.5 they shipped a good way of communication with webservice.
Web service was also available in old version of .Net, but there was a lack of mechanism using which we can call web service using JavaScript. This new way of calling web service in JavaScript also called script services.
Web Method/Script Method:
As in web service we add [webmethod] attribute, t o call same web method in JavaScript you have to add [scriptmethod] attribute on the method.
[System.Web.Script.Services.ScriptMethod]   
    public string HelloWorld()
OR to make all method in the particular web service you can add [ScriptService] attribute above definition of web service.
[System.Web.Script.Services.ScriptService]
public class WebService : System.Web.Services.WebService
How Create Web Service/ScriptService:
It is simple to add web service using visual studio. When you add web service default template will be added in the solution. To make this web service to behave as scriptservice add Attribute [System.Web.Script.Services.ScriptService] on the WebService.cs Class.

How to consume web service (Script Service) using JavaScript:
To use webservice add referance of  WebService.asmx to ScriptManager.

(1)  <asp:ScriptManager ID="ScriptManager" runat="server">
        <Services>
            <asp:ServiceReference Path="~/WebService.asmx" InlineScript="true"/>
        </Services>
 </asp:ScriptManager>

(2)now on the page where you want to call web service add following script.

<script type="text/javascript" language="javascript">
        function CallHelloworld() {
            WebService. HelloWorld(OnSuccess, onFailed, null);
        }
        function OnSuccess(result) {
            alert(result);
        }
        function onFailed(err) {
            alert(err);
        }
</script>

How to consume web service (Script Service) Having SOAP Header using JavaScript:
For enhancing Security of the webservice some time we have to pass some sensitive information.
We have to pass this information in essence to call that method regardless of from where you are consuming it. It may from JavaScript or Server side code or in any other application.
How to set SOAP Header from server side code;

Suppose this is header added in the web service:

public class WebService : System.Web.Services.WebService
{
    public AuthHeader objAuthHeader = new AuthHeader();
    public class AuthHeader : SoapHeader
    {
        public string UserName;
        public string Password;
    }
.
.
.
And this is the method protected with that SOAP Header.
   
    [WebMethod]
    [SoapHeader("objAuthHeader")]
    public List<Company> GetEmployees()
    {
  if (objAuthHeader.Password == "MyPassword")
        {
            //Do Sensitive process
  }
    }

To Call this method we can use below code.

        localhost.WebService wc = new localhost.WebService();
        wc.AuthHeaderValue = new localhost.AuthHeader();
        wc.AuthHeaderValue.UserName = "MyName";
        wc.AuthHeaderValue.Password = "MyPassword";
        wc.GetEmployees();


How to set SOAP Header from Javascript/Client Side code;

We have to create a request object  in SOAP format with header value in it and then we have to send it to the server.in response thet soap request server will return result in XML Document format.to utilize output we have to process thet document in javascript.

Here is the requestTemplate:

function CallprotectedService() {

            var requestTemplate = '<?xml version=\"1.0\" encoding=\"utf-8\"?>' +
                                '<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">' +
                                  '<soap:Header>' +
                                    '<AuthHeader xmlns="http://InternetServices/WebServices/">' +
                                      '<Username>MyName</Username>' +
                                      '<Password>MyPassword</Password>' +
                                    '</AuthHeader>' +
                                  '</soap:Header>' +
                                  '<soap:Body>' +
                                     '<GetEmployee xmlns="http://InternetServices/WebServices/" />' +
                                  '</soap:Body>' +
                                '</soap:Envelope>';
            var request = new Sys.Net.WebRequest();
            request.set_url('../WebService.asmx');
            request.set_body(requestTemplate);
            request.set_httpVerb('POST');
            request.get_headers()['Content-Length'] = requestTemplate.length;
            request.get_headers()['SOAPAction'] = "http://InternetServices/WebServices/GetEmployees";
            request.get_headers()['Content-Type'] = 'text/xml; charset=utf-8';
            request.add_completed(onComplete);
            request.invoke();
        }

//Here is the function in which you have to traverse XML document to utilize //response returned by SOAP request.

function onComplete(response, args) {
            var contentType = response.getResponseHeader('Content-Type');
            if (contentType.startsWith('text/xml')) {
                result = response.get_xml();
            }
            else {
                result = response.get_responseData();
            }
            alert(result.documentElement.getElementsByTagName('GetEmployeesResult')[0].firstChild.childNodes[0].text);           
        }


While creating service please keep in mind that SOAP request template is case sensitive and make sure you have concatenation it properly.


Size of scripts exposed when you drop Script Manager on the Page is 400kb.please consider this when you implement in your application.

Hope this will help you.

Thanks.