Udostępnij za pośrednictwem


WCF, ASP.NET AJAX, and JavaScript Proxies

I spent this weekend tinkering around with the JSON messaging capabilities of WCF new in the .NET Framework 3.5 (Orcas). The object model is changing substantially between Beta1 and Beta2, and I think the changes make for an easier to use system.

To better understand the JSON messaging features of WCF, check out some of the general requirements they were built to:

1) Config-free deployment for JSON endpoints

2) ASP.NET AJAX developer experience consistent with ASMX endpoints

3) Give service developers the same WCF developer experience as WCF v1

I am sure there were more, but these were the big ones related to developer experience.

Now, lets look at some code. A good place to start is the contract.

The Service Contract

 [ServiceContract]
public interface IWCFAjaxService {
    [OperationContract]
    [WebInvoke(Method = "POST", UriTemplate = "ShowServerDate")]
    String ShowServerDate();
}

The only thing that is different in this contract from a WCF contract from WCF v1 is the presence of the WebInvoke attribute. Simply put (almost pun intended), this attribute indicates that the operation will be accessible via the HTTP verb indicated by the Method instance property. In this case, the HTTP verb is POST.

The Service Type

This is pretty straightforward, so I'll just show it for completeness:

 public class WCFAjaxService : IWCFAjaxService {
    public string ShowServerDate()    {
        return DateTime.Now.ToString();
    }
}

The SVC file

SVC files are an activation target for WCF services hosted in IIS. Since this example is showing a web page that calls a WCF service, IIS is the natural host. The svc file is simple:

 <%@ ServiceHost Language="C#" Debug="true" Service="WCFAjaxService" Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory" %>

Notice the presence of the Factory part of the directive. This indicates that the ServiceHostFactory to be used is the WebScriptServiceHostFactory. This is a new type that ships with .NET Framework 3.5. It creates a ServiceHost that has the right endpoint (behaviors, binding, etc) that will work for AJAX integration.

The ASPX file

  1 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
 2 
 3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 
 4                     Transitional//EN" 
 5                     "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 6 <html xmlns="https://www.w3.org/1999/xhtml">
 7 <head id="Head1" runat="server">
 8     <title>WCF Ajax Demo</title>
 9 
10     <script type="text/javascript">
11     
12       function GetServerTime(){
13         var proxy = new tempuri.org.IWCFAjaxService();
14         proxy.ShowServerDate(OnSucceeded, null, null);
15       }
16   
17       function OnSucceeded(result)
18       {
19         var RsltElem = document.getElementById("Results");
20         RsltElem.innerHTML = result;
21       }
22     
23     </script>
24 
25 </head>
26 <body>
27     <form id="form1" runat="server">
28     <div>
29         <asp:ScriptManager ID="scriptManager" runat="server">
30             <Services>
31                 <asp:ServiceReference Path="~/Service.svc" />
32             </Services>
33         </asp:ScriptManager>
34         <h2>
35             Server Time</h2>
36         <p>
37             Calling a service that returns the current server time.</p>
38         <input id="DateButton" type="button" value="GetTime" 
39                    onclick="GetServerTime()" />
40     </div>
41     <div>
42         <br />
43         <span id="Results"></span>
44     </div>
45     </form>
46 </body>
47 </html>
48 

The important parts of this code snippet are lines 29-33 (ScriptManager) and lines 12-15 (proxy call). In you are new to AJAX development, I encourage you to visit https://www.asp.net for more info.

The ScriptManager is the main integration point for web services and ASP.NET AJAX. Adding a Service node in the Services collection will create a JavaScript proxy, and you can all that JavaScript proxy from other functions in your page.

See the JavaScript Proxy

When I first tackled this, I could not get the proxy to generate, and I could not seem to find out the name of the proxy. The trick is to navigate to the svc url, then add a JS to the URL.

If your starting URL is https://localhost/WCFAjaxService/Service.svc, then the JavaScript proxy URL is https://localhost/WCFAjaxService/Service.svc/js. When you download that file, you'll see that the name of the proxy follows the naming convention of your service contract's XML namespace (hence tempuri.org in lines 12-15)

 The complete sample is below.

WCFAjaxDemo.zip

Comments

  • Anonymous
    August 06, 2007
    I've had some success generating the JavaScript proxy, but it seems to only work once - every successive call to the /jsdebug url returns a Fault, and also seems to ignore the service configuration (where I have IncludeExceptionDetailInFaults turned on). Is this related to the fact that only POST requests are available?

  • Anonymous
    September 04, 2007
    In my previous post, I showed how to use the DataContractSerializer with the classes generated by the

  • Anonymous
    October 25, 2007
    There is a bug in the genereated proxy. If you specify your own name space in the service contract the generated proxy lower case the service class (or interface) name.

  • Anonymous
    October 31, 2007
    While you can easily use XML web services in your Silverlight applications, working with WCF is much

  • Anonymous
    May 31, 2008
    How can I authenticate user when service use webhttpbinding?

  • Anonymous
    February 19, 2009
    how to create a proxy class in json