Tips and Tricks in a world of Mix

source : http://dotnetbyexample.blogspot.com/2008/02/calling-wcf-service-from-javascript.html

In a previous post I pointed out how to call an ASP.NET ASMX web service from javascript in the browser. Although this still works fine, the world has moved on to .NET 3.5 and WCF services have now replaced ASMX services. Luckily, these are also callable from javascript although the procedure is now a little bit different. In this sample I presume you can use Visual Studio 2008 and know a little about WCF.

1. Create an empty solution, and add a WCF service library to it We’ll call the solution JSONWCFTest, and the library JSONServices.

2. Add a data contract

using System.Collections.Generic;
using System.Runtime.Serialization;

namespace JSONServices
{
    [DataContract]
    public class SampleDataObject
    {
        public SampleDataObject(int NewId, string NewName)
        {
            Id = NewId;
           Name = NewName;
        }
        [DataMember]
        public int Id { get; set; }

        [DataMember]
        public string Name { get; set; }
    }
}

3. Add an implementing class Implement the data contract like this

using System.Collections.Generic;

namespace JSONServices
{
    public class JSONService : IJSONService
    {
        public SampleDataObject GetSingleObject(int id, string name)
        {
            return new SampleDataObject(id, name);
        }

        public ICollection GetMultipleObjects(int number)
        {
            List list = new List();
            for (int i = 0; i < number; i++)
            {
                list.Add(new SampleDataObject(i, "Name" + i));
            }
            return list;
        }
    }
}

4. Add an operation contract Add an interface IJSONService with the following methods

using System.Collections.Generic;
using System.ServiceModel;

namespace JSONServices
{
    [ServiceContract(Namespace="http://DotNetByExample/JSONDemoService")]
    public interface IJSONService
    {
        [OperationContract]
        SampleDataObject GetSingleObject(int id, string name);

        [OperationContract]
        ICollection GetMultipleObjects(int number);
   }
 }

So far, this is very basic WCF stuff. Nothing special here.

5. Add new web application Add a new project of type “ASP.NET Web Application” to the solution. Call it JSONTestApp.

6. Add a SVC file to the web application This part is a bit awkward. Choose “Text File”, and name it “AjaxService.svc”. Then open the file, and enter the following code

<%@ServiceHost
    language="C#"
    debug="true"
    Service="JSONServices.JSONService"
    Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory"
 %>

It may be tempting to add an “Ajax-enabled WCF service” to the project but this creates its own operation contract, and in this example I want to simulate the situation in which I re-use an already existing operation contract implemented in a separate service library.

7. Check the javascript interface Basically, you are done now. Your service is hosted callable from javascript. You can check right-clicking on AjaxService.svc, and you will now see a web page that will say something like “This is a Windows© Communication Foundation service. Metadata publishing for this service is currently disabled.” and a lot things more. You can check the javascript interface by adding “/jsdebug” to the url displayed in your browser, in my case this is “http://localhost:1781/AjaxService.svc/jsdebug&#8221;. This shows the dynamically generated javascript proxy that you can call in your client code:

Type.registerNamespace('dotnetbyexample.JSONDemoService');
dotnetbyexample.JSONDemoService.IJSONService=function() {
dotnetbyexample.JSONDemoService.IJSONService.initializeBase(this);
this._timeout = 0;
this._userContext = null;
this._succeeded = null;
this._failed = null;
}
dotnetbyexample.JSONDemoService.IJSONService.prototype={
_get_path:function() {
 var p = this.get_path();
 if (p) return p;
 else return dotnetbyexample.JSONDemoService.IJSONService._staticInstance.get_path();},
GetSingleObject:function(id,name,succeededCallback, failedCallback, userContext) {
/// <param name="id" type="Number">System.Int32</param>
/// <param name="name" type="String">System.String</param>
/// <param name="succeededCallback" type="Function" optional="true" mayBeNull="true"></param>
/// <param name="failedCallback" type="Function" optional="true" mayBeNull="true"></param>
/// <param name="userContext" optional="true" mayBeNull="true"></param>
return this._invoke(this._get_path(), 'GetSingleObject',false,{id:id,name:name},succeededCallback,failedCallback,userContext); },
GetMultipleObjects:function(number,succeededCallback, failedCallback, userContext) {
/// <param name="number" type="Number">System.Int32</param>
/// <param name="succeededCallback" type="Function" optional="true" mayBeNull="true"></param>
/// <param name="failedCallback" type="Function" optional="true" TomayBeNull="true"></param>
/// <param name="userContext" optional="true" mayBeNull="true"></param>

Note: FireFox displays the javascript directly in the browser; for security reasons, Internet Explorer wants to download it to a file rather than display it, but after saving it and opening it in a text editor you will see the text above. As you can see this contains a lot of plumbing – and this is only the top part – but I emphasized the parts that are interesting right now: the name of the object that you need to call from javascript (dotnetbyexample.JSONDemoService.IJSONService) and the methods, which have – surprise, suprise – exactly the same name as their C# server-side counterparts. From here on, the procedure is pretty much the same as we were used to when calling asmx webservices from javascript:

8. Add an Web Form to the Web Application Call it TestForm1.aspx

9. Add a script manager and a reference Add a script manager to the form, right below the form tag, and make a reference to the AjaxService.svc file:

<form id="form1" runat="server">
<asp:scriptmanager runat="server">
<services>
    <asp:ServiceReference Path="AjaxService.svc" />
</services>
</asp:scriptmanager>

10. Add some user interface elements to call the service Right below the script reference, add the following code:

<div>
     ID<asp:TextBox ID="tbId" runat="server">21</asp:TextBox>  Name<asp:TextBox ID="tbName" runat="server">John Doe</asp:TextBox><br />
     <asp:Button ID="btnSelect" runat="server" Text="SingleSelect"
         UseSubmitBehavior="False"  OnClientClick="CallSingle(); return false;"/>
 </div>
 <div id="result1"></div>

11. Add Javascript code Add some javascript code to call the WCF service and process the results. Place this inside the head-tag, below the title tag:

<script type ="text/javascript">
function CallSingle()
{
    dotnetbyexample.JSONDemoService.IJSONService.GetSingleObject(
          document.getElementById("tbId").value,
          document.getElementById("tbName").value,
          CallBackSingle );
}
function CallBackSingle( WebServiceResult )
{
  resultDiv = document.getElementById("result1");
  resultDiv.innerHTML = "You entered: id = " +
       WebServiceResult.Id + " name = " +
       WebServiceResult.Name;
}
</script>

Notice again that calling a WCF method from javascript works the same as when using asmx services: one extra parameter at the end of the list is required, which is the callback. This is a function that is called upon receiving the result from the server – the server method result is put into the single parameter of the callback.

12. Run the test page Run Test1Form.aspx. You should be able to input and numerical id and a alphanumeric name, which are sent to the server, and returned back to you as and SampleObject.

13. Deploying WCF services in IIS This all works fine when running it in Cassini, but when you want to host it in IIS, you will need to take care two things.

First, you will need to ensure that IIS and WCF are correctly installed and registered. If IIS does not seem to want to cough up your SVC files (you can check that by trying http://<your host here>/<your sitename here>/AjaxService.svc), try running the command ServiceModelReg.exe /i /x from %WINDIR%\Microsoft.NET\Framework\v3.0\Windows Communication Foundation. Restart IIS after running this command. Second, if you created a default ASP.NET 2.0 website, you may run into this error message:

IIS specified authentication schemes 'IntegratedWindowsAuthentication, Anonymous', but the binding only supports specification of exactly one authentication scheme. Valid authentication schemes are Digest, Negotiate, NTLM, Basic, or Anonymous. Change the IIS settings so that only a single authentication scheme is used.

To fix this, right-click the website in your IIS manager and choose “properties”. Then click the “Directory” tab, click the “Edit” button in the “Anonymous access and authentication control” area. You will see that both Anonymous access and Integrated Windows Authentication are selected. Unselect one of them, then restart IIS. After that, the application should work smoothly.

Concluding remarks Calling WCF services from javascript is even simpler than calling asmx services – you don’t even have to mark a service as [ScriptService] anymore, you just put an .svc file into your web site with four lines of code, make a reference to an existing service library and you’re done. The sample described here does not use the IJSONService.GetMultipleObjects method, but you can download a the complete source code which includes a second test page that does. Notice that although GetMultipleObjects returns a ICollection, in javascript this is translated into a simple array. Thus, you can also use data and operation contract that use generic types, as long as the can simply be translated into an array. Oh – and don’t forget to remove “debug=true” from “AjaxService.svc” before publishing it on production. Complete code downloadable here. Author’s note: this article is my most viewed posting by far: half the traffic of my blog goes to this page. Apparently it meets a growing need in knowlegde. Please spread the word, (and the link) and if you find any errors of have any additions, let me know. Compliments are appreciated as well.

Geplaatst door Loc#alJoost op Saturday, February 23, 2008 Labels: Architecture, ASP.NET AJAX, C#, Hosting in IIS, Javascript, JSON, WCF, Web Services

Comments on: "Calling a WCF service from Javascript – very good" (2)

  1. Thanks for finally talking about >Calling a WCF service from Javascript – very good
    Kaidanov Tzvi Gregory Technical Issues & Solutions <Loved it!

  2. You may easily explore diverse range of fan models as per your design and choice requirements.

    S. Depending on the homeowner’s choice, they can either have up lights or down lights in them.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Tag Cloud

%d bloggers like this: