TUTORIAL #2: Using Javascript To Call A WCF Web Service

Sometimes you just need to use Javascript. It’s one of those things that web developers claim to hate, but secretly, I just hated the lack of tools support for it. That seems to be solved, at least for me.

Today I’m going to show you how to call your asynchronous web service from Javascript, and how we can incorporate JS Intellisense to make our job infinitely easier (one line of code, anyone?) The source code is provided at the end, in both C# and VB.NET.

1) Let’s start with a new web application project.

Solution Explorer

2) Next, we’re gonna need a web service to talk to.

image

Now, you may already be saying to yourself, “Jeff, this is all well and good, but I already have WCF services created. We don’t all have the luxury of creating stuff from scratch each time!” I’ve got you covered. There’s actually only one line of code that changes a WCF service into an AJAX-enabled WCF service. And here it is:

[ServiceContract(Namespace = "")]
 //The following line is the one you need!
 [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
 public class JeffsName
 {
  [OperationContract]
  public string GetJeffsName()
  {
   return "Jeff Blankenburg";
  }
 }

One you’ve got your WCF service up and rockin, we need to get it to DO something, right?

3) Getting our method to DO something

For this tutorial, I’m not going spend time talking to a database or anything extravagant. But I want to do more than return a name. I was talking with a friend of mine yesterday about why the nickel seems to be the rarest of coins in your pocket, and that inspired my method for this example.

<LONGSTORY TYPE=”INTERESTING” VALUE=”NOT IMPORTANT TO THE TUTORIAL”>

Dan pinged me over IM to tell me about this guy who had started a game collecting money on the street. He called it the “Change Race.” He wanted to see who could collect $100 faster by ONLY collecting money that was “found.” It didn’t count if you found $5 in an old coat from the previous winter, that was still your money.

Anyway, so Dan, who is known to like to try eccentric things like these, thought he would give it a go. In his coin finding history to this point, he discovered that he was finding significantly fewer nickels than any other coin. Here’s the breakdown:

$0.25 – 7

$0.10 – 16

$0.05 – 6

$0.01 – 63

Yes, there are only 7 quarters, but who drops a quarter and leaves it? I certainly understand those pennies, however. But only 6 nickels? That seems surprising, as I’m calling it, “The Silverier, Fatter Penny.”

So the conversation we had was about WHY there seems to be fewer nickels. We threw around many theories, but ultimately came up with the fact that there are fewer change scenarios where a nickel is necessary. In addition, there’s rarely a time where you are going to get 2 nickels in change, because you’re more likely to get a dime. Anyway, I’d love to see a debate about this in the comments. There’s even a good article someone wrote about “The Mystery of the Vanishing Nickel.”

</LONGSTORY>

So that story led me to think about the 99 change scenarios that are possible when receiving change from a cashier. 1 cent through 99 cents. Zero doesn’t count because you would just get bills (or nothing at all.)

My web service is going to take an integer value and return the fewest number of coins necessary to make that change. If your integer is greater than 99, I just subtract out the dollars until we are left with the change.

Here’s my web service method:

public class ChangeScenario
 {
  [OperationContract]
  public string GetMinimumCoins(int changevalue)
  {
   int quarter = 0;
   int dime = 0;
   int nickel = 0;
   int penny = 0;
   int tempvalue = changevalue;

   while (tempvalue > 0)
   {
    if (tempvalue >= 100)
    {
     tempvalue -= 100;
    }
    else if (tempvalue >= 25)
    {
     tempvalue -= 25;
     quarter += 1;
    }
    else if (tempvalue >= 10)
    {
     tempvalue -= 10;
     dime += 1;
    }
    else if (tempvalue >= 5)
    {
     tempvalue -= 5;
     nickel += 1;
    }
    else if (tempvalue >= 1)
    {
     tempvalue -= 1;
     penny += 1;
    }
   }

   return "You need " + changevalue + " cents in change.<BR/><BR/>You get " + quarter + " quarters, " + dime + " dimes, " + nickel + " nickels, and " + penny + " pennies";
  }

In all, I take an integer parameter, and return a string that represents the fewest coins that will satisfy that change scenario.

4) Making the page aware of the web service

I wish I could say that this was now as easy as writing a line of code in a script block and you’re done. But it’s maybe 5 lines of code more complicated than that. And most of those lines are dedicated to letting the .aspx page know that you want to talk to the web service.

So speaking of that, I will need to add my all-too-familiar-scriptmanager to the page, as well as a reference to the web service we want to use.

<form id="form1" runat="server">
    <asp:ScriptManager runat="server" ID="sm">
        <Services>
            <asp:ServiceReference Path="~/ChangeScenario.svc" />
        </Services>
    </asp:ScriptManager>
    <div id="valuebox">
        <a href="javascript:callWebService();">Click to call web service.</a>
    </div>
</form>

You’ll notice that I also have a DIV tag in there, with an ANCHOR tag calling a Javascript function. Inside this function is where I will call my web service method.

5) Calling the web service from Javascript

Now I have created a Javascript function at the top of my page, and I need to make that call to my web service. The syntax is generally what you would expect to find:

<script language="javascript" type="text/javascript">
    function callWebService()
    {
        ChangeScenario.GetMinimumCoins(86, setText);
    }
 
    function setText(changetext)
    {
        var myElement = document.getElementById('valuebox');
        myElement.innerHTML = changetext;
    }
</script>

The one thing that stuck out to me in all of this was the second parameter in the method call. It’s the name of another Javascript function. This new ability also gives us some new Intellisense.

Javascript Intellisense

The first value is the parameter that the web service method takes. In this case, it’s even expecting an integer. The second is the name of the Javascript function you want to be called upon successful completion of the asynchronous call. The third is another JS function for when the call fails.

So, when we click our button, we call the callWebService() function, passing in an integer value to determine our change.

In turn, it returns our value successfully, and calls the setText() Javascript function with the parameter our method returns.

This function then renders that value as the HTML for the DIV we have on the page.

6) Summary of our adventure

As I demonstrated, in rather verbose fashion, it’s pretty simple to talk to a web service from Javascript directly. Most of your effort will be spent writing a service far more valuable than mine. The nice part is that the asynchronicity of the calls is completely handled for you.

Please let me know if you have any questions…I’d be glad to help you out.

7) Let’s see this code in action!

I have uploaded my sample application for demonstration of this code. It has been slightly modified, so that we call the web service 99 times, once for each “change scenario.” One thing that I have noticed, at least in my environment, is that because we are making asynchronous calls, they don’t always return in the order they were sent. So you’ll see that, even though we are making the calls in the order from 1-99, they don’t necessarily get written to the page in that order. We’re just taking the data as it returns.

demo

8) Source Code Links

Even though I provided my examples above in C#, I have provided source code for both C# and VB implementations of this example. Enjoy!

C#.NET Source Code VB.NET Source Code

kick it on DotNetKicks.com

3 thoughts on “TUTORIAL #2: Using Javascript To Call A WCF Web Service

  1. Actually *technically* I pinged you over IM to ask you what the name of the city was where the rest stop north of Columbus on I-71.PS I found 3 more pennies today (no nickels)

  2. You sir, are a genius.Thanks

  3. I wish I’d seen this about 15 hours ago. Dangit

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