Geeks With Blogs
The Code To Nowhere
| Home |

Jquery auto-complete, WCF Services and cross domain nightmares

Gone are the days of using the Ajax toolkit, it’s far too bloated and can be very difficult to debug if anything goes wrong. So like many other developers I have made the conscious effort in swapping my attention to jQuery instead.

I have recently been working on a project where I needed to implement a simple auto complete dropdown, so instead of reaching for the auto-complete extender from the Ajax toolkit I decided instead to use the jQuery UI Autocomplete, as surely this will be just as quick to implement. How wrong I was. So to save anyone else the pain here is my quick and easy steps to ensure jQuery happiness!

Configuring the WCF Service

The auto completer defaults to HTTP GET requests (I think there is a way to change this to POST behaviour) so we must let our WCF Service method know about this. I added the UriTemplate attribute to help me expose my service as a RESTful service and as I was requesting and returning a JSON object I also added the RequestFormat and ResponseFormat attributes. From the auto completer I want the text the user has typed in and the max number of items to return so I have added a couple of parameters to my method.

        [OperationContract]
        [WebInvoke(Method = "GET",
                   RequestFormat = WebMessageFormat.Json,
                   ResponseFormat = WebMessageFormat.Json,
                   UriTemplate = "GetBooks?name={name}&itemsReturned={itemsReturned}",
                   BodyStyle = WebMessageBodyStyle.WrappedRequest)]
        IList<Book> GetBooks (string name, string itemsReturned);

So far so very much like every other example on the web. However as I was implementing a cross domain call I needed more!! This is where JSONP comes to the rescue.

Headache over, surely the WCF Service will be easy enough to configure to work with JSONP. Wrong. At this point I had already re-installed the AJAX toolkit and was ready to go back to it with open arms, however, as Marlboro will confirm I`m not a quitter.

Configuring the WCF Service to allow JSONP

Easiest place to start is with Microsofts WCF Samples. Once you have downloaded these you need to browse to the JSONP project in particular. This resides in WCFWFCardSpace\WCF\Extensibility\Ajax\JSONP\CS. From here add the following files to your project:

  •   JSONPBehavior.cs
  •  JSONPBindingElement.cs
  • JSONPBindingExtension.cs
  • JSONPEncoderFactory.cs

These extra files, amongst other things allow us to add our JSONP behaviour to our WCF Method.

        [OperationContract]
        [WebInvoke(Method = "GET",
                   RequestFormat = WebMessageFormat.Json,
                   ResponseFormat = WebMessageFormat.Json,
                   UriTemplate = "GetBooks?name={name}&itemsReturned={itemsReturned}",
                  BodyStyle = WebMessageBodyStyle.WrappedRequest)

 

          [JSONPBehavior(callback = "myCallbackMethod")]
        IList<Book> GetBooks(string bookName, string itemsReturned);

The callback=”myCallbackMethod” parameter is basically what gets specified in the request URI as a query string parameter. This will specify what callback method will be used to return the JSON on the client side.

Now WCF Services are not quite Plug And Play. The amount of configuration options available to the developer seems endless. So where do we start.  First of all we need to tell WCF about our new JSONP configuration. To do this we create a new extension point in our service model and reference the JsonpBindingExtension.cs file we copied earlier. We also need a custom binding which uses our new binding element. Finally we reference a behaviour which enables webHttpBindings for our WCF Service.

<system.serviceModel>
         <extensions>
      <bindingElementExtensions>
              <add name="jsonpMessageEncoding"
 type="Services.Extensions.JsonpBindingExtension, Services,Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
         </bindingElementExtensions>
</extensions>
 <bindings>
               <customBinding>
                      <binding name="jsonpBinding" >
                            <jsonpMessageEncoding />
                            <httpTransport manualAddressing="true"/>
                      </binding>
               </customBinding>         
  </bindings>
<behaviors>
   <endpointBehaviors>
    <behavior name="Services.AspNetAjaxBehavior">
        <webHttp />
    </behavior>
   </endpointBehaviors>
          </behaviors>
      <service name="Services.BookService">
 <endpoint address="" behaviorConfiguration="Services.AspNetAjaxBehavior"
        binding="customBinding"  bindingConfiguration="jsonpBinding"  contract="Services.Interfaces.IBookService" />
      </service>
  </services>
</system.serviceModel>

Consuming the Service

You can see from the example below we are passing the myCallbackMethod query string parameter (that we referenced earlier in our WCF Method) with an annoymous function which will handle our returning JSONP. I am also using jQuerys $.map function to translate all the items in the array.

   $("#book").autocomplete({
        source: function (request, response) {
            var dataString = "Name=" + request.term + "&&itemsReturned=" + 10;
            var url = “http://Svr2/Services/BookService.svc/GetBooks?" + dataString;
            $.getJSON(url + "&myCallbackMethod=?", function (data) {
                response($.map(data, function (item) {
                    return {
                        label: item.Name,
                        value: item.Nam
                    }
                }));
            });
        },
        minLength: 2
   });

There was probably a quicker and easier way of implementing this functionality; however it eluded me at the time. Since implementing this solution I also think .Net4 WCF Services have built in support for JSONP. That could have probably saved me from almost throwing my monitor out of the window on numerous occasions.

Posted on Thursday, June 2, 2011 11:20 PM | Back to top


Comments on this post: Jquery auto-complete, WCF Services and cross domain nightmares

No comments posted yet.
Your comment:
 (will show your gravatar)


Copyright © TheCodeToNowhere | Powered by: GeeksWithBlogs.net