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

A proxy generator to WebServices for JavaScript and AJAX

By , 20 Sep 2005
 

Introduction

From the languages and programming environments like C, the .NET CLR and Java we know the proxy generation mechanisms that are based on IDL and RPC for a long time. These generated classes and files enable the programmer to call a server-side method by calling a local method with the same name. The implementation of network transfer is taken off from your application code.

If you want to implement a communication from JavaScript to web services using SOAP, it is very important to use an approach that needs only a small amount of code. Complex and long scripts tend to be buggy.

This proxy generator can be used on its own but is also a part of an AJAX framework available through my blog site that is still under development.

Some AJAX implementations use their own way to transport information between the client and the server. This implementation uses the standard SOAP protocol and works on Internet Explorer and the Firefox browser.

How it works - in short

Web services can be described by using the formal description standard for web services called WSDL (Web Service Description Language). Everything we need to know for calling a web service is available in this XML formatted information and all we need to do is transform this information into a JavaScript source code syntax that can be directly executed by using an XSLT based translation. A common include file is used for bringing the core implementations of the SOAP protocol.

Using the proxy

To make these proxy functions work, a common JavaScript include (ajax.js) file and a file that generates the web service specific code must be included:

<script type="text/javascript" src="ajax.js"></script>
<script type="text/javascript" 
   src="GetJavaScriptProxy.aspx?service=CalcService.asmx">
</script>

The implementation of real communication details are implemented in the ajax.js file. A variable named proxies is created as an empty JavaScript object and this is the only global variable that we need. The individual proxies are then attached to this object to minimize the naming conflicts that may occur.

The second script include now retrieves the WSDL description of the web service and generates the specific JavaScript for this service containing local proxy methods that can be called to execute the corresponding method on the server.

Asynchronous calls

Calling a server-side method may look like this:

proxies.CalcService.CalcPrimeFactors.func = 
          displayFactors;  // hook up a method that 
                           // gets the response
proxies.CalcService.CalcPrimeFactors(12); // now call the server

// The return value is passed to this function as a parameter
function displayFactors (retVal) {
  document.getElementById("outputField").value = retVal;
} // displayFactors

Here you seen an asynchronous call. The function CalcPrimeFactors() returns immediately and the client side scripting continues. After a few milliseconds (or longer) the server will send back the result of the called method of the web service and the value will be passed to the hooked up method as a parameter.

Synchronous calls

There is also a synchronous version that can be used. In this case, the function attribute must remain unset or null and the result of the server-side method is directly returned from the client side method call. This way of calling the server may block for some milliseconds because no user-events like typing or clicking are processed during the call.

proxies.CalcService.func = null; // no hook up function !
var f = proxies.CalcService.CalcPrimeFactors(12);
// call the server and return the result.

Implementation details

Here is a sample extract of the code that is generated for the client to show how the mechanism works.

The include file ajax.js generates the global object named ajax:

var proxies = new Object();

Per WebService, an object named like the WebService is attached to the ajax object to hold the service specific information like the URL and the namespace of the WebService:

// JavaScript proxy for webservices
// A WebService for the calculation of prime factors.
proxies.CalcService = {
  url: "http://localhost:1049/CalcFactors/CalcService.asmx",
  ns: "http://www.mathertel.de/CalcFactorsService/"
} // proxies.CalcService

For each web service method, a function on the client is created that mirrors the method on the server. The information we need to build up the full SOAP message is attached to the function object as attributes:

// Add 2 numbers.
proxies.CalcService.AddInteger = 
        function () { return(proxies.callSoap(arguments)); }
proxies.CalcService.AddInteger.fname = "AddInteger";
proxies.CalcService.AddInteger.service = proxies.CalcService;
proxies.CalcService.AddInteger.action = 
        "http://www.mathertel.de/CalcFactors/AddInteger";
proxies.CalcService.AddInteger.params = 
                           ["number1:int","number2:int"];
proxies.CalcService.AddInteger.rtype = ["AddIntegerResult:int"];

Caching

The proxy implementation also offers a client-side caching feature. An approach that leads to less traffic on the net because repeating the same calls can be prevented.

The HTTP caching features, instrumented by using HTTP headers, do not help in these situations because the request is not an HTTP-GET request and there is always a payload in the HTTP body. Caching must therefore be realized by some scripting on the client.

The caching feature in the JavaScript web service proxy implementation can be enabled by calling the method proxies.EnableCache and passing the function that should further use caching. There is a button in the CalcFactorsAJAX.htm sample that shows how to enable this:

proxies.EnableCache(proxies.CalcService.CalcPrimeFactors)

By calling this method, a JavaScript object is added that stores all the results and is used to prevent a call to the server if an entry for the parameter already exists inside this object. This is not a perfect solution, but it works only under the following circumstances:

  • The parameter must be a string or number that can be used for indexing the properties of a JavaScript object.
  • The cache doesn't clear itself. It can be cleared by calling EnableCache once again.
  • Only methods with a single parameter are supported.

Reference

This is the map of the objects and properties that are used for the proxy functions to work:

Property Usage
proxies.service.url URL of the WebServices.
proxies.service.ns Namespace of the WebServices.
proxies.service.function() Calling a server-side method.
proxies.service.function.fname Name of the method.
proxies.service.function.action SOAP action of the method, used in the HTTP header.
proxies.service.function.params Array with the names and types of the parameters.
proxies.service.function.func Function for receiving the result.
proxies.service.function.onException Function to handle an exception.
proxies.service.function.corefunc Debugging helper function.
proxies.service.function.service A link back to the service object.
proxies.EnableCache(func) The method for enabling the caching feature.

Supported data types

With version 2.0 there is now more support for different data types.

Simple data types

Till now only those methods were supported that were converting the parameters and the result values were not necessary. This applies to strings and numbers.

With this version, the data types defined on the server and the WSDL are passed to the client so that the data types can be converted using JavaScript at runtime. In the generated proxy code, the listing of the names of the parameters is now extended by an optional specification of the data type. Without these the values are treated as strings.

In the HTML object model, the JavaScript data types are not well supported. The value that is displayed inside an HTML input field is always a string, even if it contains only digits. So, when calling the proxy functions, all the parameters are also accepted as JavaScript strings and converted (if possible) to the right types.

XML data

Passing XML documents was implemented to make it possible to pass complex data. In the supported browser clients, the XMLDocument object from Microsoft or Firefox, and on the server the .NET XmlDocument class can be used.

A method has to be is declared in C# like this:

[WebMethod()]
public XmlDocument Calc(XmlDocument xDoc) {
 ...
 return (xDoc);
} // Calc

The proxy functions also accept the XML document as a string type. In this case, the contents of the passed string is passed directly to the server and it must for this reason contain a valid XML document without the declarations and without any "XML processing instructions" like <? ... ?>.

With this data type it is possible to pass complex data directly to the server. And there is no need to define a method with many parameters if we use this data type. If the data scheme is extended with new fields, it will not be necessary to give a new signature to the web service.

The disadvantage of this approach is that the content of the XML document cannot be validated by the web service infrastructure because there is no schema for this part of the conversation available.

Data type mappings

XML data types Alias in the proxy attributes JavaScript Data type
string string / null String
int, unsignedInt,
short, unsignedShort,
unsignedLong, slong
int Number (parseInt)
double, float float Number (parseFloat)
dateTime date Date
boolean bool Boolean
System.Xml.XmlDocument x In Mozilla / Firefox:
XMLDocument
In Internet Explorer:
ActiveXObject("Microsoft.XMLDOM")
ActiveXObject("MSXML2.DOMDocument")

The implementation of the call

The transmission of the SOAP/XML messages can be implemented using the appropriate XMLHTTP object that is available in many state-of-the-art browsers today. This implementation was (until now) tested with Internet Explorer and Firefox:

///<summary>
///Get a browser specific implementation of the 
///XMLHTTP object.
///</summary>
function getXMLHTTP() {
  var obj = null;

  try {
    obj = new ActiveXObject("Msxml2.XMLHTTP");
  } catch (e) { }

  if (obj == null) {
    try {
      obj = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (e) { }
  } // if
  
  if ((obj == null) && 
            (typeof XMLHttpRequest != "undefined"))
    obj = new XMLHttpRequest();
  return(obj);
} // getXMLHTTP

This object is implemented in different technologies, depending on the available technologies in the browsers. It was first developed by Microsoft in the Internet Explorer as an ActiveX control and the Mozilla developers re-implemented it by providing the same methods and properties. A call can be done by using the following sequence of methods:

x.open("POST", p.service.url, true); // async call 
x.setRequestHeader("SOAPAction", p.action);
x.setRequestHeader("Content-Type", 
                   "text/xml; charset=utf-8");
// hook up a method for the result processing
x.onreadystatechange = p.corefunc; 
x.send(soap); // send a soap request

More details and some more internal description can be found in the ajax.js include file.

A proxy generator for JavaScript

Retrieving a WSDL description is very easy when implemented in ASP.NET. You navigate to the URL of the web service and use the link that is available on this page. You can also attach a WSDL parameter.

The proxy generator retrieves this XML document by using an HttpWebRequest. By using an XSLT transformation, it is now very simple to implement a WSDL to JavaScript compiler.

The complex part lies in writing the right transformations. Inside the wsdl.xslt file, you can find the templates of the JavaScript code that defines these proxy objects. Instead of generating another XML document this transformation produces plain text that is valid JavaScript code.

The source code of GetJavaScriptProxy.aspx

<%@ Page Language="C#" Debug="true" %>

<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Net" %>
<%@ Import Namespace="System.Xml" %>
<%@ Import Namespace="System.Xml.Xsl" %>

<!-- 
/// 19.07.2005 white space removed
/// 20.07.2005 more datatypes and XML Documents
/// 04.09.2005 XslCompiledTransform
 -->
 
<script runat="server">
  private string FetchWsdl(string url) {
    Uri uri = new Uri(Request.Url, url + "?WSDL");
    HttpWebRequest req = 
                  (HttpWebRequest)WebRequest.Create(uri);
    req.Credentials = CredentialCache.DefaultCredentials;
    // running on the same server !
    // req.Proxy = WebRequest.DefaultWebProxy; 
    req.Timeout = 6 * 1000; // 6 seconds

    WebResponse res = req.GetResponse();
#if DOTNET11
    XmlDocument data = new XmlDocument();
    data.Load(res.GetResponseStream());

    XslTransform xsl = new XslTransform();
    xsl.Load(Server.MapPath("~/ajaxcore/wsdl.xslt"));

    System.IO.StringWriter sOut = 
             new System.IO.StringWriter();
    xsl.Transform(data, null, sOut, null);
#else
    XmlReader data = 
           XmlReader.Create(res.GetResponseStream());

    XslCompiledTransform xsl = new XslCompiledTransform();
    xsl.Load(Server.MapPath("~/ajaxcore/wsdl.xslt"));

    System.IO.StringWriter sOut = 
                             new System.IO.StringWriter();
    xsl.Transform(data, null, sOut);
#endif
    return (sOut.ToString());
  } // FetchWsdl
</script>

<%
  string asText = Request.QueryString["html"];

  Response.Clear();
  if (asText != null) {
    Response.ContentType = "text/html";
    Response.Write("<pre>");
  } else {
    Response.ContentType = "text/text";
  } // if

  string fileName = Request.QueryString["service"];
  if (fileName == null)
    fileName = "CalcService";

  // get good filenames only (local folder)
  if ((fileName.IndexOf('$') >= 0) || (Regex.IsMatch(fileName, 
                           @"\b(COM\d|LPT\d|CON|PRN|AUX|NUL)\b", 
                           RegexOptions.IgnoreCase)))
    throw new ApplicationException("Error in filename.");

  if (! Server.MapPath(fileName).StartsWith(
         Request.PhysicalApplicationPath, 
                    StringComparison.InvariantCultureIgnoreCase))
    throw new ApplicationException("Can show local files only.");

  string ret = FetchWsdl(fileName);
  ret = Regex.Replace(ret, @"\n *", "\n");
  ret = Regex.Replace(ret, @"\r\n *""", "\"");
  ret = Regex.Replace(ret, @"\r\n, *""", ",\"");
  ret = Regex.Replace(ret, @"\r\n\]", "]");
  ret = Regex.Replace(ret, @"\r\n; *", ";");
  Response.Write(ret);
%>

The source code of wsdl.xslt

<?xml version="1.0" ?>
<xsl:stylesheet version='1.0' 
  xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  xmlns:fmt="urn:p2plusfmt-xsltformats" 

  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
  xmlns:s="http://www.w3.org/2001/XMLSchema"
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
  xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/">
  <!-- 
  /// 19.07.2005 optional documentation
  /// 20.07.2005 more datatypes and XML Documents 
  /// 20.07.2005 more datatypes and XML Documents fixed
  -->
  <xsl:strip-space elements="*" />
  <xsl:output method="text" version="4.0" />
  <xsl:param name="alias">
    <xsl:value-of select="wsdl:definitions/wsdl:service/@name" />
  </xsl:param>

  <xsl:template match="/">
    // javascript proxy for webservices
    // by Matthias Hertel
    /*<xsl:value-of select="wsdl:definitions/wsdl:documentation"/>*/
     <xsl:for-each select=
        "/wsdl:definitions/wsdl:service/wsdl:port[soap:address]">
       <xsl:call-template name="soapport" />
     </xsl:for-each>
  </xsl:template>

  <xsl:template name="soapport">
     proxies.<xsl:value-of select="$alias" /> = {
     url: "<xsl:value-of select="soap:address/@location" />",
     ns: "<xsl:value-of 
      select=
        "/wsdl:definitions/wsdl:types/s:schema/@targetNamespace"/>"
     } // proxies.<xsl:value-of select="$alias" />
     <xsl:text>
     </xsl:text>

     <xsl:for-each select="/wsdl:definitions/wsdl:binding[@name = 
                      substring-after(current()/@binding, ':')]">
       <xsl:call-template name="soapbinding11" />
     </xsl:for-each>
  </xsl:template>

  <xsl:template name="soapbinding11">
     <xsl:variable name="portTypeName" 
       select="substring-after(current()/@type, ':')" />
    <xsl:for-each select="wsdl:operation">
       <xsl:variable name="inputMessageName" 
        select="substring-after(/wsdl:definitions/wsdl:portType[@name = 
                $portTypeName]/wsdl:operation[@name = 
                current()/@name]/wsdl:input/@message, ':')" />
       <xsl:variable name="outputMessageName" 
        select="substring-after(/wsdl:definitions/wsdl:portType[@name = 
                $portTypeName]/wsdl:operation[@name = current()/@name]
                /wsdl:output/@message, ':')" />

       <xsl:for-each select="/wsdl:definitions/wsdl:portType[@name = 
                               $portTypeName]/wsdl:operation[@name = 
                               current()/@name]/wsdl:documentation">
        /** <xsl:value-of select="." /> */
       </xsl:for-each>
       proxies.<xsl:value-of 
        select="$alias" />.<xsl:value-of select="@name" /> 
        = function () { return(proxies.callSoap(arguments)); }
       proxies.<xsl:value-of 
        select="$alias" />.<xsl:value-of select="@name" />.fname
        = "<xsl:value-of select="@name" />";
       proxies.<xsl:value-of 
        select="$alias" />.<xsl:value-of select="@name" />.service
        = proxies.<xsl:value-of select="$alias" />;
       proxies.<xsl:value-of 
        select="$alias" />.<xsl:value-of select="@name" />.action
        = "<xsl:value-of select="soap:operation/@soapAction" />";
       proxies.<xsl:value-of 
        select="$alias" />.<xsl:value-of select="@name" />.params
        = [<xsl:for-each select="/wsdl:definitions/wsdl:message[@name 
        = $inputMessageName]">
        <xsl:call-template name="soapMessage" />
      </xsl:for-each>];
      proxies.<xsl:value-of select="$alias" />.
         <xsl:value-of select="@name" />.rtype 
         = [<xsl:for-each 
         select="/wsdl:definitions/wsdl:message[@name = 
                                    $outputMessageName]">
         <xsl:call-template name="soapMessage" />
         </xsl:for-each>];
    </xsl:for-each>
  </xsl:template>

  <xsl:template name="soapMessage">
    <xsl:variable name="inputElementName" 
       select="substring-after(wsdl:part/@element, ':')" />
    <xsl:for-each select="/wsdl:definitions/wsdl:types/s:schema/s:element
                                   [@name=$inputElementName]//s:element">
      <xsl:choose>
        <xsl:when test="@type='s:string'">
          "<xsl:value-of select="@name" />"
        </xsl:when>
        <xsl:when test="@type='s:int' 
                  or @type='s:unsignedInt' or @type='s:short' 
                  or @type='s:unsignedShort' or @type='s:unsignedLong' 
                  or @type='s:long'">
          "<xsl:value-of select="@name" />:int"
        </xsl:when>
        <xsl:when test="@type='s:double' or @type='s:float'">
          "<xsl:value-of select="@name" />:float"
        </xsl:when>
        <xsl:when test="@type='s:dateTime'">
          "<xsl:value-of select="@name" />:date"
        </xsl:when>
        <xsl:when test="./s:complexType/s:sequence/s:any">
          "<xsl:value-of select="@name" />:x"
        </xsl:when>
        <xsl:otherwise>
          "<xsl:value-of select="@name" />"
        </xsl:otherwise>
      </xsl:choose>
      <xsl:if test="position()!=last()">,</xsl:if>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

History

  • 6th July, 2005: First version published.
    • Simple data types without conversion.
  • 7th September, 2005: Second version published.
    • Simple data with conversion.
    • XML data type support.
    • Caching feature added.
  • 16th December, 2005: Broken Links corrected.

The files for implementation and more samples are available in the sample website of my AJAX project.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Matthias Hertel
Architect Deutsche Bank AG
Germany Germany
Member
see http://www.mathertel.de

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
AnswerRe: what about complex data types?memberMatthias Hertel1 Apr '08 - 20:16 
There is *some* support for complex datatypes.
The proxy generator to WebServices is part of the Open Source project http://sourceforge.net/projects/ajaxengine/[^] where a newer version is integrated.
 
You can also find more information in by blog http://ajaxaspects.blogspot.com/[^]
 
Using wsdl directly from *.asmx endpoints of the same website is working.
QuestionIt doesn't work for me on recent browsers "uncaught exception: Permission denied to call method XMLHttpRequest.open"membermatoyemat27 Mar '08 - 5:51 
I thought i've found my solution when i got this article, but then when i tried, it doesn't work for me, the error says "uncaught exception: Permission denied to call method XMLHttpRequest.open"
Everything was tested as shown on the site except that my web service is on a remote machine and is java based rpc/literal.
Any help will be appreciated.
AnswerRe: It doesn't work for me on recent browsers "uncaught exception: Permission denied to call method XMLHttpRequest.open"memberMatthias Hertel27 Mar '08 - 20:43 
That's an intendend behavior of the XMLHttpRequest object: On the client you cannot cross the domain boundaries so you cannot request a ressource from outside of yout web application.
Search for XSS (Cross Side Scripting) and XMLHttpRequest to find more information about it.
This behavior ist good, because otherwiese it can break web appliactions.
My advice is to implement a slim web service on your site and forward all requests to the original side. Then you also have the chance to verify all requests, caching, switch to other services if one is not available etc.
QuestionWill this work with WCF?memberDewey25 Feb '08 - 15:01 
This is a nice solution.
 
Will it work with WCF .svc services?
 
From using another Javascript SOAP Proxy, I found that WCF does some minor things differently, however, we did fix the code.
 
However, I find your solution compelling, but we are moving excusively to WCF based services.
AnswerRe: Will this work with WCF?memberMatthias Hertel15 Jul '08 - 19:25 
The answer is yes.
I had a blog about that lately. See http://ajaxaspects.blogspot.com/2008/07/calling-wcf-and-soap-based-webservices.html[^]
Generalthis is a cool thingmemberfr922013 Feb '08 - 12:31 
very useful indeed, thanks.
Generalxslt compile errorsmemberShawn Smith11 Sep '07 - 4:56 
I just found this and was looking forward to trying it but the xml file had outdated schema links and the xslt won't compile.
 
I managed to handle the xml file(I think) but the xslt is stumping me. (I'm no expert on xslt files, so I could be missing something simple)
 
Any ideas? (Seems to be dying at a point with two entities (seems to me they are unicode for line break and carriage Return) and complains about parsing the entities.
GeneralRe: xslt compile errorsmemberMatthias Hertel12 Sep '07 - 8:59 
The sample project still works (on my machine) and I can't see what's wrong in your case.
Can you send me your sample and tell me more details so I can have a look ?
mathertel at hotmail dot com

 
mathertel at hotmail dot com
GeneralRe: xslt compile errorsmembersandeepguptamca17 Sep '07 - 0:27 
hi...i have one problem i tried to use ajax to call web service but unable to cal...
i have studied lost of article. i could not do.
Plz help me
thanks
QuestionWork with SOAP 1.2?memberyli56 Feb '07 - 5:53 
Hi Matthias,
 
Good work! I am currently using JAX-WS 2.0 that's built upon SOAP 1.2. I am wondering if your technique works with SOAP 1.2? If not, is it easy to extend it so it can be used with SAOP 1.2?
 
Thank you very much!
Yunfeng
Smile | :)
 
YLI5

Generalvery usefulmemberseunghyop back19 Nov '06 - 15:28 
I am considering to write a book about AJAX and
I think it would be good if I introduce this article and sample
to the Korean readers.
 
Do mind if I introduce this article and sample in my Korean book ?
This book will be written in Korean , and will be available only in Korea.
Of course I will specify this orginal URL where the readers can get the code.
AnswerRe: very usefulmemberMatthias Hertel20 Nov '06 - 8:34 
Thanks and Yes, just do it.
QuestionHow to handle multiple return values? [modified]memberRonane14 Jun '06 - 4:57 
Great project,
I'm trying to use this to call a ws function that returns a boolean success value and an error message. Excuse me if this is a newbie question but how can I call the proxy from javascript and access a reference value from the WS function?
 
eg
retval = proxies.Users.DeleteUser(userID, strErrMsg);
 
where strErrMsg is an output parameter of the ws method
Any help appreciated, thanks.
 
-- modified at 3:46 Thursday 15th June, 2006
AnswerRe: How to handle multiple return values?memberMatthias Hertel14 Jun '06 - 23:01 
I do not clearly see what you want to do so here are some "options":
 
WebSevices are not returning references. Calling a SOAP WebService is equivalent of sending and receiving a (one) message.
 
With error messages you can and should use the exception handling mechanisam. In your case if there is an error just throw an exception with the error message. The client will then call the JavaScript method that you can attached to "onException".
 
If you realy want to return multiple values from a webservice then you should use the XML data feature.
Returning complex objects would be another solution but that's not implemented here because JavaScript doesn't support complex type definitions.
QuestionHow to use JavaScriptProxy with non-MS WebServices?memberDHoffer9 Jun '06 - 5:10 
It looks like your examples use MS Web-Services. What if I have a URL of the WSDL from a Java based Web-Service? How can I use this to generate the proxy from this WSDL?
 
-dh
AnswerRe: How to use JavaScriptProxy with non-MS WebServices?memberMatthias Hertel9 Jun '06 - 21:54 
The URL for WebServices with JAVA based servers is a little bit different but the mechanism is the same.
On the sample web site at http://www.mathertel.de/AJAXEngine/ you can find a JAVA based project using AXIS. It also works with BEA WebServices as far as I know.
QuestionRe: How to use JavaScriptProxy with non-MS WebServices?memberSöffsche12 Sep '06 - 23:01 
Hello. I want to make a Proxy to a WebObjects Webservice. Does the AJAX Engine offer this? I can't find the Java based project using AXIS under http://www.matherel.de/AJAXEngine/. Can You help me? Thanks Sophie
AnswerRe: How to use JavaScriptProxy with non-MS WebServices?memberMatthias Hertel23 Sep '06 - 22:33 
The WebObjects generated wsdl might differ a little bit from the axis wsdls.
Just send me a few and I can have a look.
GeneralExample works, but mine does not!memberKilhoffer5 Jun '06 - 19:13 
I created a very simple webservice, but cannot create a proxy for it. The call to GetJavaScriptProxy.aspx simply returns this:
// javascript proxy for webservices
// by Matthias Hertel
/* */
 
What could be going wrong?
 
Anthony S. Kilhoffer
AnswerRe: Example works, but mine does not! [modified]memberMatthias Hertel9 Jun '06 - 21:58 
There seems to be no methods defined in that service.
You can look at the generated WSDL and check why the rules of the xslt file dont't match. If you send me your sample I'll have a look.
GeneralGr8, Gr8, Cool CoolmemberMishra_2427 Apr '06 - 9:33 
Cool | :cool: Suspicious | :suss:
It's gr8 I am using all over the place.
It reduded my time and effort.
 
Thank you so much

 
Shashi
GeneralVery cool!memberspamcatcher66616 Apr '06 - 16:33 
This is a killer concept, and in fact I was just gearing up to write my own 'something like this.' I decided to see if anyone else had already done it, and son of a gun, you have a whole projected developed for it. I was actually myself considering doing an all javascript, no XSLT, implementation, but the benefits to that are only minimal... after all I'd only need a client to something for which I have pre-picked the service. But still for a purely academic project someday I think I'm going to try and do it. Think about it, no server code, just generate html and js files that will both call a data web service and generate a useable if not pretty UI to represent the objects as form fields, the potential uses are limitless. The scriptaculous library combined with something like this could actually deliver a fully featured rich client experience for an application that quite literally materializes out of thin air. Hats off for thinking of it first.
Questionbug?membertcain_sd18 Jan '06 - 13:05 
First, thanks, this looks like the most promising solution to my problem... I've run into many issues with the webservices.htc when trying to consume a gSOAP web service.
 
I tested this, however, against a .Net Web Service and was getting javascript errors (using latest IE 6.0) in the proxies._response function. My WebService method, Initialize, takes one parameter, and returns void. It seems the _response function is not checking for no return params. So when it tries to reference cc.rtype[0] it gives an error: "rtype.0 is null or not an object".
 
I added a check at the beginning of this method that seemed to fix it:
if (cc.rtype.length == 0)
return 0;
 
Is my assumption about this method correct?
AnswerRe: bug?memberMatthias Hertel21 Jan '06 - 2:14 
Yes, that's a bug.
The retrun is too early in the method becaus the proxies.xmlhttp and proxies.current references are not cleared then.
Better:
proxies._response = function () {
  var ret = null;
  var x = proxies.xmlhttp;
  var cc = proxies.current;
  var rtype = null;
  
  if (cc.rtype.length > 0)
    rtype = cc.rtype[0].split(':');
    
  if ((x != null) && (x.readyState == 4)) {
    if (x.status == 200) {
      var xNode = null;
 
      if (rtype != null)
        xNode = x.responseXML.getElementsByTagName(rtype[0])[0];
 
      if (xNode == null) {
        ret = null;
I search my AJAX project and I did not had that case until now. I'll update this here in a few days. Thanks.
GeneralRe: bug?memberTravis Whidden18 May '06 - 19:19 
Did you figure out what caused this yet? I am VERY excited to use this. Just implemented it into a part of my site for testing. I get that same error messasge. I will look to see if its something I can fix... and report back. Thanks so much for this example.
 
Travis Whidden
badassride.com

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

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130523.1 | Last Updated 20 Sep 2005
Article Copyright 2005 by Matthias Hertel
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid