Saturday, September 17, 2011

SharePoint 2010: Access WCF Service with jQuery

In one of my earlier post I described how to develop a custom WCF service. Today I’ll cover how you can invoke the SharePoint WCF Service from jQuery. In my last post I described to develop a SOAP web service but for using WCF service from jQuery I’m going to use REST web service. For the list of service types and factories supported in SharePoint you can visit the link in MSDN. You can download source code from the link given at the end of the post.

Prepare the service to call from jQuery

Consider developing a service as described in my earlier post with the following changes:

  • For  using json I’ve used REST service factory ‘Microsoft.SharePoint.Client.Services.MultipleBaseAddressWebServiceHostFactory’ as shown below. You can use SOAP factory but you then need to parse data in different way.
    <%@ ServiceHost Language="C#" Debug="true"
    Service="AccessSPServiceFromJQuery.MyService, $SharePoint.Project.AssemblyFullName$"
    CodeBehind="MyService.svc.cs"
    Factory="Microsoft.SharePoint.Client.Services.MultipleBaseAddressWebServiceHostFactory, Microsoft.SharePoint.Client.ServerRuntime, Version=14.0.0.0,
    Culture=neutral, PublicKeyToken=71e9bce111e9429c"
    %>


  • Next you need to specify the return type to json in the service interface as shown below. I’ve specified both request and response type to json in WebInvoke attribute:

    [ServiceContract]
    public interface IMyService
    {
    [OperationContract]
    [WebInvoke(Method = "GET", BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
    List<Product> SearchProduct(string productName);


    [OperationContract]
    [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
    bool Save(Product product);
    }

One thing to notice here is that you can’t access the service in browser with mex endpoint. For example if you service is http://myserver/myservice.svc, then the url http://myserver/myservice.svc/mex will not work for service created with MultipleBaseAddressWebServiceHostFactory.
 

Call Service with jQuery

The next step is to call the service with jQuery. The url of the service to be used in jQuery will be service url and method name. For example if you service url is ‘/_vti_bin/AccessSPServiceFromJQuery/MyService.svc’ and the method name you want to invoke is ‘Search’ then the full url will be ‘/_vti_bin/AccessSPServiceFromJQuery/MyService.svc/Search’. As shown in the code below, you can invoke the service Search by passing the parameter in data field of ajax call of jquery

function getProductFromService(searchText) {
try {
$.ajax({
type: "GET",
url: '/_vti_bin/AccessSPServiceFromJQuery/MyService.svc/SearchProduct',
contentType: "application/json; charset=utf-8",
data: { "productName": searchText },
dataType: 'json',
success: function (msg) {
WCFServiceGetSucceeded(msg);
},
error: WCFServiceGetFailed
});
}
catch (e) {

alert('error invoking service.get()' + e);
}
}
function WCFServiceGetSucceeded(result) {
alert('success');
}
function WCFServiceGetFailed(error) {
alert('Service Failed.');
}

Download and use code

I’ve uploaded the code for this post in my skydrive. You can download the code from the link below. To use the code please ensure you have internet connection as I’ve used jqery from Microsoft CDN. The search functionality get all products matching name. You can try to search just by typing a single character. You can debug and test the code. In save I’ve just shown you can pass value from browser to service using POST method.

13 comments:

  1. Would it possible to show an example posting back to the WCF with data?

    ReplyDelete
  2. The IMyService.Save post the product object back to the WCF service.

    ReplyDelete
  3. http://sharepoint.stackexchange.com/questions/25222/posting-json-to-a-rest-wcf-endpoint-in-sharepoint-using-cksdev is based on your question. Do you think you would be able to reply?

    ReplyDelete
  4. For my POST wcf endpoint the WebMessageBodyStyle needed to be WrappedRequest

    EG:
    [OperationContract]
    [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest,
    RequestFormat = WebMessageFormat.Json,
    ResponseFormat = WebMessageFormat.Json)]

    ReplyDelete
  5. I get an "401 Unauthorized" on response to the jQuery ajax request.
    I've some code with elevated priviledges, maybe it's causing the issue?
    I've debugged the whole service's method and didn't throw any exception, but in the end, the client gets this Unauthorized response (as seen in Firebug).

    But if I change the method to not do anything and just return an empty List (that's what the method returns) it works perfect.

    Any ideas?

    ReplyDelete
  6. @Emzero, can you check sharepoint logs in 14 hive for more details on unauthorized error?

    ReplyDelete
  7. I getting the same unauthorize error.

    ReplyDelete
  8. @EaglesEye, Please check in the webservice which user you are getting by using SPContext.Current.Web.CurrentUser and if the user has proper permission

    ReplyDelete
  9. Sohel Rana: Once again, excellent article! I think jQuery and WCF Rest are a wonderful combination.

    ReplyDelete
  10. Thanks John for the complement. Web is now becoming more like client side scripting with new sharepoint app model, single page web applications etc.

    ReplyDelete
  11. useful article. Do you think using jQuery and WCF Service is better than Client Object Model?

    ReplyDelete
  12. Client object model is out of the box but has limitations of what you can do with it. On the other hand when you have your own wcf service you can do all your customization with jQuery and WCF. So the basic approach should be if you can do your work with Client Object Model, you should use it, either go for jQuery/WCF

    ReplyDelete
  13. Hi Sohel, very nice post.

    Unfortunately its not working for me.

    When I try to access the service through URL, it give me an error saying "endpoint not found".

    Any help would be appreciated.

    Thanks

    ReplyDelete