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

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