Calling your WCF web service from an ASP.NET AJAX page

Published Tue, May 22 2007 15:44

The 3.5 beta version of the .NET platform lets us use JSON as the serialization format used by a web service call. The best of all is that this means that we can now call a web service from an ASP.NET AJAX page.

To do this, you need to add some entries to your configuration file (on the server side). Getting a proxy on the client side is a simple as adding a service reference through the ScriptManager control. Lets start by seeing the service code (which was generated by adding a new WCF service to an AJAX futures enabled web site):

[ServiceContract()]
public interface ITest
{
    [OperationContract]
    string MyOperation1(string myValue);
}

public class Test : ITest
{
    public string MyOperation1(string myValue)
    {
       return "Hello: " + myValue;
     }
}

The svc file looks like this:

<%@ ServiceHost Language="C#" Debug="true" Service="Test"
              CodeBehind="~/App_Code/Test.cs" %>

Now you need to add an endpoint that is able to understand JSON. In my case, I wanted to expose a mex endpoint too, so I ended up with the following definitions for my web service:

<services>
  <service name="Test" behaviorConfiguration="metadataSupport">
         <endpoint binding="webHttpBinding"
                    behaviorConfiguration="jsonBehavior"
                    contract="ITest"
                    bindingConfiguration="jsonBinding"/>
          <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
   </service>
</services>

As you can see, i'm using  a WebHttpBinding and I'm saying that there's a new jsonBinding element which configures the traditional webHttpBinding that is introduced by default by the WCF framework. In this case, we're just setting the message encoding to JSON:

<bindings>
  <webHttpBinding>
        <binding name="jsonBinding" messageEncoding="Json"/>
  </webHttpBinding>
</bindings>

We also need to add a new behavior that looks like this:

<behaviors>
  <serviceBehaviors>
     <behavior name="metadataSupport">
         <serviceMetadata httpGetEnabled="true" httpGetUrl=""/>
     </behavior>
   </serviceBehaviors>
   <endpointBehaviors>
        <behavior name="jsonBehavior">
           <enableWebScript />
        </behavior>
   </endpointBehaviors>
</behaviors>

And that's it! the only thing you need to do to call this WCF service from your AJAX ASP.NET page is add a reference to the web service:

<asp:ScriptManager ID="ScriptManager1" runat="server">
  <Services>
     <asp:ServiceReference Path="Test.svc" />
  </Services>
</asp:ScriptManager>

Doing this ends up inserting the following js code in your page:

Type.registerNamespace('tempuri.org');
ITest=function() {
ITest.initializeBase(this);
this._timeout = 0;
this._userContext = null;
this._succeeded = null;
this._failed = null;
}
ITest.prototype={
MyOperation1:function(myValue,succeededCallback, failedCallback, userContext) {
return this._invoke(ITest.get_path(), 'MyOperation1',false,{myValue:myValue},succeededCallback,failedCallback,userContext); }}
ITest.registerClass('ITest',Sys.Net.WebServiceProxy);
ITest._staticInstance = new ITest();
ITest.set_path = function(value) { ITest._staticInstance._path = value; }
ITest.get_path = function() { return ITest._staticInstance._path; }
ITest.set_timeout = function(value) { ITest._staticInstance._timeout = value; }
ITest.get_timeout = function() { return ITest._staticInstance._timeout; }
ITest.set_defaultUserContext = function(value) { ITest._staticInstance._userContext = value; }
ITest.get_defaultUserContext = function() { return ITest._staticInstance._userContext; }
ITest.set_defaultSucceededCallback = function(value) { ITest._staticInstance._succeeded = value; }
ITest.get_defaultSucceededCallback = function() { return ITest._staticInstance._succeeded; }
ITest.set_defaultFailedCallback = function(value) { ITest._staticInstance._failed = value; }
ITest.get_defaultFailedCallback = function() { return ITest._staticInstance._failed; }
ITest.set_path("/AJAXFuturesEnabledWebSite2/Test.svc");
ITest.MyOperation1= function(myValue,onSuccess,onFailed,userContext) {ITest._staticInstance.MyOperation1(myValue,onSuccess,onFailed,userContext); }

which really looks similar to waht you get when you add JSON support to an ASMX web service.

Filed under: ,

Comments

# Jeff Deville said on Thursday, May 24, 2007 11:24 PM

I was wondering if you could tell me what path to use if I'm hosting the service in an outside application, like a windows service, or console app.  There's no .svc file in this instance, but I thought that putting in the service's address would work.  When I do, I get: "The server method '[METHOD_NAME]' failed with the following error:... HTTP Error 404..."

Any suggestions?  Thank you.

# Luis Abreu said on Friday, May 25, 2007 3:17 AM

hello jeff.

i believe that the same restrictions you had for asmx web services still hold true, ie, you can't make xdomains calls. if i recall correctly, this happens because, by default, browsers won't let you use the xmlhttprequest object to perform xdomain calls.

to solve this, normally we just create a local web service which works as a proxy for the remote service:

dotnetslackers.com/.../MashitUpwithASPNETAJAX.aspx

# Jeff Deville said on Saturday, May 26, 2007 12:06 PM

Good to know, thanks Luis.

# Gustavo Frederico said on Friday, July 20, 2007 10:28 AM

Saudações,

Eu segui os passos acima e tudo correu bem. Você teria algum exemplo de como usar o serviço afinal? Vejo o código JavaScript gerado, mas não estou certo sobre como utilizá-lo.

obrigado - Gustavo

# luisabreu said on Friday, July 20, 2007 12:31 PM

Claro, sem problema. quando quiseres chamar o servico numa pagina js, basta fazeres algo do genero:

ITest.MyOperation1( "Luis", succeddedCallback);

function succeededCallback(res){

  //res tem o objecto retornado do servidor

}

# luisabreu said on Friday, July 20, 2007 12:31 PM

Claro, sem problema. quando quiseres chamar o servico numa pagina js, basta fazeres algo do genero:

ITest.MyOperation1( "Luis", succeddedCallback);

function succeededCallback(res){

  //res tem o objecto retornado do servidor

}

# xx said on Saturday, September 29, 2007 12:29 PM

I get the following error Unrecognized attribute 'messageEncoding'

# Suneel said on Monday, July 21, 2008 2:58 AM

I am also getting the same error  Unrecognized attribute 'messageEncoding'. Any update on this.

# 8 good WCF Links « dotnet etc. said on Tuesday, February 10, 2009 9:50 AM

Pingback from  8 good WCF Links « dotnet etc.

# 8 good WCF Links « dotnet etc. said on Tuesday, February 10, 2009 9:52 AM

Pingback from  8 good WCF Links « dotnet etc.

# 8 good WCF Links « dotnet etc. said on Tuesday, February 10, 2009 9:59 AM

Pingback from  8 good WCF Links « dotnet etc.

# 8 good WCF Links « dotnet etc. said on Tuesday, February 10, 2009 9:59 AM

Pingback from  8 good WCF Links « dotnet etc.

# 8 good WCF Links « dotnet etc. said on Tuesday, February 10, 2009 10:01 AM

Pingback from  8 good WCF Links « dotnet etc.

Leave a Comment

(required) 
(required) 
(optional)
(required) 
If you can't read this number refresh your screen
Enter the numbers above:  

Search

This Blog

Tags

Community

Archives

Syndication

Email Notifications

News




  • View Luis Abreu's profile on LinkedIn


    Follow me at Twitter

    My books

    Silverlight 4.0: Curso Completo

    ASP.NET 4.0: Curso Completo

    Portuguese LINQ book cover

    Portuguese ASP.NET 3.5 book cover

    Portuguese ASP.NET AJAX book cover

    Portuguese ASP.NET AJAX book cover