Click here to Skip to main content
15,868,349 members
Articles / Web Development / Node.js

Wcf.js: Call WCF web services from Node.js

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
8 May 2012CPOL3 min read 83K   4   28   5
Call existing web services from within Node apps.

Introduction

Node.js is becoming a great choice for developers in start ups and enterprises. While REST web services are the preferred choice for new node development, there is also a need to call existing web services from within Node apps. When calling WCF web services this is a challenge since WCF supports a lot of standards and protocols which are not easy to generate. Wcf.js is a library for node.js that aims to simplify this scenario. 

Background 

The first question that you may be asking is why do we need a special library at all for calling SOAP web services. After all HTTP is a first class citizen in node.js and we can simply send the SOAP over HTTP to the service. However web services may support standards like Ws-Security or MTOM which node does not support out of the box. Actually this is exactly what another project, ws.js, solves. 

So if we have ws.js why do we also need wcf.js?

The two projects are complementing each other. While wcf.js does not add any new standards implementations on top of ws.js, it mimics the WCF API. This means users can access WCF using its native API and do not need to learn a new paradigm. And all this is done in a pure JavaScript way! 

Using the code 

1. First you must install the Wcf.js module:

npm install wcf.js

2. Now write your code: 

JavaScript
var BasicHttpBinding = require('wcf.js').BasicHttpBinding
  , Proxy = require('wcf.js').Proxy
  , binding = new BasicHttpBinding(
        { SecurityMode: "TransportWithMessageCredential"
        , MessageClientCredentialType: "UserName"
        })
  , proxy = new Proxy(binding, "http://localhost:7171/Service/clearUsername")
  , message =  "<Envelope xmlns='http://schemas.xmlsoap.org/soap/envelope/'>" +
                 "<Header />" +
                   "<Body>" +
                     "<GetData xmlns='http://tempuri.org/'>" +
                       "<value>123</value>" +
                     "</GetData>" +
                    "</Body>" +
               "</Envelope>"
proxy.ClientCredentials.Username.Username = "yaron"
proxy.ClientCredentials.Username.Password = "1234"
proxy.send(message, "http://tempuri.org/IService/GetData", function(response, ctx) {
  console.log(response)
});     

If this code looks familiar then you are right - it is the same as the WCF API. So you can freely create bindings and behaviors the same way you would do that with WCF. The above example initializes a wcf basicHttpBinding in this line: 

JavaScript
binding = new BasicHttpBinding(
        { SecurityMode: "TransportWithMessageCredential"
        , MessageClientCredentialType: "UserName"
        }) 

Then it configures credentails:

JavaScript
proxy.ClientCredentials.Username.Username = "yaron"
proxy.ClientCredentials.Username.Password = "1234" 

and then calls the service:

JavaScript
proxy.send(message, "http://tempuri.org/IService/GetData", function(response, ctx) {
  ...
});       

Exactly as with WCF! 

Custom binding sample  

The same approach can help us build a custom binding: 

JavaScript
var CustomBinding = require('wcf.js').CustomBinding
  , MtomMessageEncodingBindingElement = require('wcf.js').MtomMessageEncodingBindingElement
  , HttpTransportBindingElement = require('wcf.js').HttpTransportBindingElement
  , Proxy = require('wcf.js').Proxy
  , fs = require('fs')
  , binding = new CustomBinding(
        [ new MtomMessageEncodingBindingElement({MessageVersion: "Soap12WSAddressing10"}),
        , new HttpTransportBindingElement()
        ])
  , proxy = new Proxy(binding, "http://localhost:7171/Service/mtom")
  , message = '<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">' +
                '<s:Header />' +
                  '<s:Body>' +
                    '<EchoFiles xmlns="http://tempuri.org/">' +
                      '<value xmlns:a="http://schemas.datacontract.org/2004/07/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">' +
                        '<a:File1 />' +                   
                      '</value>' +
                    '</EchoFiles>' +
                  '</s:Body>' +
              '</s:Envelope>'
proxy.addAttachment("//*[local-name(.)='File1']", "me.jpg");
proxy.send(message, "http://tempuri.org/IService/EchoFiles", function(response, ctx) {
  var file = proxy.getAttachment("//*[local-name(.)='File1']")
  fs.writeFileSync("result.jpg", file)    
}); 

What you should note here is how channels are defined on the custom binding:

JavaScript
binding = new CustomBinding(
      [ new MtomMessageEncodingBindingElement({MessageVersion: "Soap12WSAddressing10"}),
      , new HttpTransportBindingElement()
      ])

You can create your own channels and put them in the pipeline. This specific example uses the mtom channel.  

Why MTOM requires extra work?  

The above example uses the MTOM channel. This is why we are required to do some more work by specifying the base64 element path: 

JavaScript
proxy.addAttachment("//*[local-name(.)='File1']", "me.jpg"); 

We are not required to do this in WCF so why does Wcf.js requires this?

Let's take a look at this soap element: 

XML
<a:File1 />  

If MTOM was not used then this section was filled with the base64 representation of me.jpg:

XML
<a:File1>PS2Kqw23A2A98...</a:File1>

We need to tell the MTOM channel to take this content and put it outside the message as a binary payload. So why WCF does not require us to tell it this information? WCF is a full soap stack which also generates proxies based on WSDL. When WCF generated the File1 parameter it marked it as a candidate for MTOM transformation. So Wcf has this information from the Wsdl. Since Wcf.js is a pure ws-* stack (and not soap stack), it does not have access to the wsdl and we need to supply this information. 

Supported Bindings 

Wcf.js currently supports a subset of:

  • BasicHttpBinding
  • WSHttpBinding
  • CustomBinding

The current subset includes:

  • MTOM / Text encodings
  • WS-Addressing (all versions)
  • Transport Security (SSL)
  • Transport with message credential (Username)  

The future of Ws.js     

Wcf.js is a pure JavaScript implementation of WCF for Node.js.   

Wcf.js is a growing framework. For future versions I plan to add more binding support like net.tcp and proprietary security negotiations in WsHttpBinding. If you have any special request send me an email from my blog. If you want to help feel free to fork Wcf.js on github - that's the fastest way to grow Wcf.js.  

More information 

Check out the project github page 

Check out my blog 

Check out my twitter 

Drop me an email from my blog  

License

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


Written By
Software Developer (Senior)
Israel Israel
Web services interoperability expert.

http://webservices20.blogspot.com/

Comments and Discussions

 
QuestionWcf netpipe endpoint Pin
ashish56321-Jun-17 1:26
ashish56321-Jun-17 1:26 
QuestionSend Data to WCF Method Pin
Member Nitin Patil2-Nov-15 18:06
Member Nitin Patil2-Nov-15 18:06 
Hi,

Thanks for this help. I am trying to call "ABC" method from my WCF service and send data to it. I am getting "Undefine" in response.

Also would like to know where we can specify method name ("ABC" in my case) in node js?

Please help.

Thanks,
Nitin Patil
QuestionIssue faced while consuming WCF webservice using wcf.js module using node.js Pin
amjad syed19-Jul-12 3:28
amjad syed19-Jul-12 3:28 
AnswerRe: Issue faced while consuming WCF webservice using wcf.js module using node.js Pin
Yaron Naveh19-Jul-12 13:36
Yaron Naveh19-Jul-12 13:36 
QuestionVote of 5 Pin
Ganesan Senthilvel8-May-12 10:23
Ganesan Senthilvel8-May-12 10:23 

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

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