Click here to Skip to main content
Click here to Skip to main content

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

By , 8 Apr 2009
Rate this:
Please Sign up or sign in to vote.

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:

   (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:

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:

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:

<!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)

About the Author

qubing

China China
No Biography provided

Comments and Discussions

 
Questioncan support more Params? [modified] PinmemberJLKEngine0085-Jun-10 18:12 
GeneralMy vote of 1 Pinmemberbinarycheese14-Apr-09 3:38 
GeneralRe: My vote of 1 Pinmemberqubing17-Apr-09 23:33 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140421.2 | Last Updated 8 Apr 2009
Article Copyright 2009 by qubing
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid