Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Java

How to Use JS Calling A WebService By Post Both SOAP And JSON

3.29/5 (6 votes)
8 Apr 2009CPOL2 min read 73.4K   306  
WebService Both SOAP AND JSON
Image 1

Introduction

Here is a full example of how to use JS to call a webservice by both SOAP and JSON.

Background

Now almost everybody talks about Ajax and webservices. I tried too and I wrote a JS to do the work! After reading my article, you will find things are really simple!

There is something different about my sample. It really works in Internet Explorer 6, Internet Explorer 7, Opera, and also Netscape. You will find that in Firefox3, it doesn't support the synchronism function to call a webservice. I also find that we can't create more than one instance of xmlhttprequest object in Internet Explorer 6. I fixed the problem. It really works well, but is not supported in Internet Explorer 5, because it does not support the push() function. I haven't tried to test it in Internet Explorer 5.

You might want to know that xmlhttprequest does not support the cross-domain webservice.

Using the Code

Here is the file of kuuy.SoapRequest.js:

JavaScript
   (function() {
    //If you read the oriented Ajax JS, it's used to register a namespace
    var Namespace = {
        Register: function(_Name) {
            var o = window;
            var x = false;
            for (var a = _Name.split("."); a.length > 0; ) {
                //remove the top element
                var s = a.shift();
                if (a.length == 0) { if (o[s]) { x = true; } }
                if (!o[s]) { o[s] = {}; }
                o = o[s];
            }
            if (x) { return 1; }
        }
    }
    Namespace.Register("kuuy");
    var xmlPId = null;
    //XMLparser,we call it ajax activeobject
    var xmlHttp = (function() {
        if (window.XMLHttpRequest) {
            return new XMLHttpRequest();
        }
        else {
            if (xmlPId) {
                return new ActiveXObject(xmlPId);
            }
            else {
                var parserIds = ["Msxml2.XMLHTTP.6.0", 
		"MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"];
                for (var pid in parserIds) {
                    try {
                        xmlPId = pid;
                        return new ActiveXObject(parserIds[pid]);
                    } catch (e) { }
                }
                throw new Error("don't support the xmlrequest object~!");
            }
        }
    })();
    //Parameter
    kuuy.Parameter = function() {
        return {
            Name: null,
            Value: null,
            Init: function() {
                if (arguments[0].length == 2) 
		{ this.Name = arguments[0][0]; this.Value = arguments[0][1]; }
                return this;
            }
}.Init(arguments);
        }
        //SOAPRequest,We Instanced it,and then call the method Open
        kuuy.SOAPRequest = function() {
            return {
                URL: null, //url
                Method: null, //the method we calling
                Params: null, //parameters
                Callback: null, //callback a function
                WSDLS: null, //webservice descriptions
                Init: function() {
                    switch (arguments[0].length) {
                        case 2:
                            this.URL = arguments[0][0];
                            this.Callback = arguments[0][1];
                            break;
                        case 3:
                            this.URL = arguments[0][0];
                            this.Method = arguments[0][1];
                            this.Callback = arguments[0][2];
                            this.WSDLS = new Array();
                            break;
                    }
                    this.Params = new Array();
                    return this;
                },
                AddParam: function()//add a parameter
                {
                    switch (arguments.length) {
                        case 1: this.Params.push(arguments[0]); break;
                        case 2: this.Params.push
			(new kuuy.Parameter(arguments[0], arguments[1])); break;
                    }
                },
              //Open the request
                Open: function() {
                    var obj = this;
                    if (this.WSDLS) {
                        var wsdl = this.WSDLS[this.URL];
                        if (!wsdl) {
                            xmlHttp.open
				("GET", this.URL + "?wsdl", true); //async request
                            xmlHttp.onreadystatechange = function() {
                                if (xmlHttp.readyState == 4) {
                                    if (xmlHttp.status == 200 || xmlHttp.status == 0) {
                                       //the soap request
                (function() { obj.Post.call(obj, xmlHttp.responseXML); })();
                                    }
                                }
                            };
                            xmlHttp.send(null);
                        }
                        else
                            (function() { obj.Post.call(this); })();
                    }
                    else {
                        var data = "";
                        for (var par in this.Params) {
                            data += this.Params[par].Name + 
					"=" + this.Params[par].Value;
                        }
                        xmlHttp.open("POST", this.URL, true); //asnyc request
                        xmlHttp.setRequestHeader("Content-type", 
				"application/x-www-form-urlencoded");
                        xmlHttp.setRequestHeader("Content-Length", data.length);
                        xmlHttp.onreadystatechange = function() {
                            if (xmlHttp.readyState == 4) {
                                if (xmlHttp.status == 200 || xmlHttp.status == 0) {
                                    obj.Callback(xmlHttp.responseText);
                                }
                            }
                        }
                        xmlHttp.send(data);
                    }
                },
                Post: function() {
                    if (!this.WSDLS[this.URL])
                        this.WSDLS[this.URL] = arguments[0];
                    var wsdl = this.WSDLS[this.URL];
                    var ns = (wsdl.documentElement.attributes["targetNamespace"] + 
				"" == "undefined") ? 
                    wsdl.documentElement.attributes.getNamedItem
				("targetNamespace").nodeValue : 
			wsdl.documentElement.attributes["targetNamespace"].value;
                    //method we calling
                    var soapaction = ((ns.lastIndexOf("/") 
			!= ns.length - 1) ? ns + "/" : ns) + this.Method;
                    var parsXml = "";
                    for (var par in this.Params) {
                        parsXml += "<" + this.Params[par].Name + ">" + 
			this.Params[par].Value + "</" + 
					this.Params[par].Name + ">"; ;
                    }
                    var data = "<?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:Body>" +
                        "<" + this.Method + " xmlns=\"" + ns + "\">" +
                        parsXml +
                        "</" + this.Method + "></soap:Body></soap:Envelope>";
                    xmlHttp.open("POST", this.URL, true); //asyc request
                    xmlHttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
                    xmlHttp.setRequestHeader("SOAPAction", soapaction);
                    xmlHttp.setRequestHeader("Content-Length", data.length);
                    var obj = this;
                    xmlHttp.onreadystatechange = function() {
                        if (xmlHttp.readyState == 4) {
                            if (xmlHttp.status == 200 || xmlHttp.status == 0) {
                                obj.Callback(xmlHttp.responseText);
                            }
                        }
                    }
                    xmlHttp.send(data);
                }
}.Init(arguments);
            }
        })();

Then we need a class which we call EnhancedWebService in .NET 3.5. DataContractJsonSerializer makes the use of JSON easier. We also need a class we call if JSONHelper has to Serialise and DeSerialise the JSON Object.

Here is the class of JSONHelper.cs:

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization.Json;
using System.IO;
namespace kuuy.Components
{
    public class JSONHelper
    {
        //Serialize
        public static string Serialize<T>(T obj)
        {
            string reVal = string.Empty;
            using (MemoryStream m = new MemoryStream())
            {
                DataContractJsonSerializer serializer = 
			new DataContractJsonSerializer(obj.GetType());
                serializer.WriteObject(m, obj);
                reVal = Encoding.UTF8.GetString(m.ToArray());
                m.Flush();
            }
            return reVal;
        }
        //Deserialize
        public static T Deserialize<T>(string json)
        {
            return Deserialize<T>(json, Activator.CreateInstance<T>().GetType());
        }
        //Deserialize(Dynamic Type)
        public static T Deserialize<T>(string json, Type type)
        {
            T obj = Activator.CreateInstance<T>();//Instance
            using (MemoryStream m = new MemoryStream(Encoding.UTF8.GetBytes(json)))
            {
                DataContractJsonSerializer serializer = 
			new DataContractJsonSerializer(type);
                obj = (T)serializer.ReadObject(m);
                m.Flush();
            }
            return obj;
        }
    }
}

Don't forget to add the reference of System.ServiceModel.Web.

Here is the code of EnhancedWebService.cs:

C#
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Runtime.Serialization;
using System.IO;
using System.Web;
namespace kuuy.Components.Services
{
    //WebService Extension
    public class EnhancedWebService : System.Web.Services.WebService
    {
        public EnhancedWebService()
            : base()	//Base Construct
        {
            string ServiceMethodName = GetMethodName();
            bool IsJSON = Context.Request.QueryString["out"] == "json";
            if (IsJSON) InterceptJSONMethodRequest(ServiceMethodName);
        }
        private string GetMethodName()//Get the method we are calling
        {
            return Context.Request.Url.Segments
		[Context.Request.Url.Segments.Length - 1];//URL Segment('\')
        } 
        private void InterceptJSONMethodRequest(string ServiceMethodName)
        {
            JSONMethodAttribute JMA = GetMethodJSONMethodAttribute
			(ServiceMethodName);//Description Class
            if (JMA == null)
            {
                Context.Response.Write("throw new Exception('The Web Service method " +
                                       ServiceMethodName + " is not available " +
                                       "as a JSON function. For more " +
                                       "information contact " +
                                       "the Web Service Administrators.');");
            }
            else
            {
                //ToDo: deserialize parameters, call target method, 
                //      deserialize and write return value
                Type Service = this.GetType();
                MethodInfo JSONMethod = 
		Service.GetMethod(ServiceMethodName);//Get Parameters
                if (JSONMethod == null) return;
                //Parameters
                ParameterInfo[] JSONMethodParameters = JSONMethod.GetParameters();
                object[] CallParameters = new object[JSONMethodParameters.Length];
              
                for (int i = 0; i < JSONMethodParameters.Length; i++)
                {
                    //Parameter
                    ParameterInfo TargetParameter = JSONMethodParameters[i];
                    string RawParameter = HttpUtility.UrlDecode
			(Context.Request.Form[TargetParameter.Name]);//Get Value
                    if (RawParameter == null || RawParameter == "")
                        throw new Exception("Missing parameter " + 
				TargetParameter.Name + ".");
                    CallParameters[i] = JSONHelper.Deserialize<object>
				(RawParameter, TargetParameter.ParameterType);
                }
                object JSONMethodReturnValue = JSONMethod.Invoke(this, CallParameters);
                string SerializedReturnValue = 
			JSONHelper.Serialize<object>
			(JSONMethodReturnValue);//Return JSON Object
                Context.Response.Write(SerializedReturnValue);
            }
            Context.Response.Flush();
            Context.Response.End();
        }
        private JSONMethodAttribute GetMethodJSONMethodAttribute
			(string WebServiceMethodName)
        {
            MethodInfo ActiveMethod = this.GetType().GetMethod(WebServiceMethodName);
            JSONMethodAttribute JMA = null;
            if (ActiveMethod != null)
            {
                object[] Attributes = ActiveMethod.GetCustomAttributes(true);
                foreach (object Attribute in Attributes)
                {
                    if (Attribute.GetType() == typeof(JSONMethodAttribute))
                    {
                        JMA = (JSONMethodAttribute)Attribute;
                    }
                }
            }
            return JMA;
        }
    }
    //WebService Description
    public class JSONMethodAttribute : System.Attribute
    {
        public JSONMethodAttribute()
        {
        }
    }
}

Now all the code is shown above. We need to make it work now. Here is my example:

HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "

http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="
http://www.w3.org/1999/xhtml" >
<head>
    <title></title>
    <script src="js/kuuy.SOAPRequest.js" type="text/javascript"></script>
    <script type="text/javascript">
        var pattern = /webservice\.htm/gi;
        var callback = function(o) {
            alert(o);
        }
        function JSONRequest() {
            var url = document.location.href.replace
		(pattern, "WebService1.asmx/JSONService?out=json");
            var request = new kuuy.SOAPRequest(url, callback);
            request.AddParam("input", "88.88.88.88");
            request.Open(); 	//Send SOAP Request
        }
        function SOAPRequest() {
            var url = document.location.href.replace(pattern, "WebService1.asmx");
            var method = "JSONService";
            var request = new kuuy.SOAPRequest(url, method, callback);
            request.AddParam("input", "88.88.88.88");
            request.Open(); 	//Send SOAP Request
        }
    </script>
</head>
<body>
    <input type="button" onclick="JSONRequest()" value="JOSN"/>
    <input type="button" onclick="SOAPRequest()" value="SOAP"/>
</body>
</html>

You can download my full example. It's really simple and effective. Good luck!

Though I have no job and nobody will hire me, I never stop learning. I wish this will help you! Thanks for reading!

If you have any questions, you can email me at kuuy@hotmail.com.

History

  • 2009-04-07 Initial post

License

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