<%@ Page MasterPageFile="~/Blankenthoughts.master" Title="Blankenthoughts" %>

Wednesday, September 03, 2008

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

Labels: , , , ,

posted by Jeff Blankenburg, 4:11 PM | link | 2 comments |

Tuesday, September 18, 2007


In case you're terribly interested in where I'll be over the next month, here's the short list (I'm sure this will be added to).

September 24 - Halo 3 Pre-Launch Party in Detroit, MI
September 25 - Halo 3 Launch Party in Columbus, OH
September 26 - Halo 3 Launch Party in Cincinnati, OH
September 27 - Columbus .NET Developer's Group Meeting
October 8 - ReMix07 Boston
October 9 - ReMix07 Boston
October 11 - Nashville .NET User's Group
October 12 - DevLink
October 13 - DevLink
October 15 - The Night of AJAX in Cleveland, OH (at the Microsoft office)
October 20 - Day of .NET in Ann Arbor, MI

26 days, 7 cities. Not bad. Where should I go next? Anyone have some great events coming up that I'm not aware of?

Also, in case you're curious, the Night of AJAX is a public event in Cleveland. We are going to be welcoming Jay Kimble of Codebetter.com fame and AJAX guru from Florida. It is planned to be a two hour event in which Jay will present an Intro to AJAX followed up with AJAX best practices and a discussion of Javascript Alternatives (eg. Script#/Silverlight). Please plan to check it out. Be sure to check back for more information as it becomes available. Please leave a comment or email me if you'd like more information. Special thanks to Dave Balzer for getting this great idea put together.

Labels: , , , , ,

posted by Jeff Blankenburg, 9:02 PM | link | 0 comments |

Tuesday, May 01, 2007

You're presenting at Mix. You've got an intriguing title and abstract:

High Speed Development with the AJAX Control Toolkit

You're ten minutes late. Very professional. Helps your credibility.

Labels: ,

posted by Jeff Blankenburg, 1:02 PM | link | 1 comments |

Monday, April 30, 2007

So it's been hyped for the past few weeks that we were going to see many new things announced by Microsoft this morning. The hype didn't keep up with reality.

It was WAY better than sold.

THe biggest highlight of this conference is the combination of Silverlight with the .NET framework.

We can actually write C# code to function like you would normally expect Javascript to do.

We can create vector based animations to run in a cross-browser, cross platform environment, with all of the instructions stored in XAML.

Designers can completely control the look and actions of these elements in a graphical interface, but that design is then translated down to XAML, which can be edited, updated, etc as a file on the server. This allows the designer to control the looks, and the developer to control the functionality.

Two demos during the keynote were flooring, however.

First, the CEO from a company named Metaliq demoed a new AJAX/Silverlight/.NET application they call Top Banana. It is basically a content editing application, all within a browser. The URL is http://silverlight.metaliq.com/topbanana
It appears they have taken their demo down, but as soon as I can get access to it again. I will post it. It was truly unbelieveable.

The other struck close to home. I'm a huge baseball fan. Mondo big. And having grown up in Cleveland, I've been forced to suffer with the Indians my entire life. THe C-something-something from MLB.oom was here demoing their new MLB.TV application. It acted as I expected. Showed every possible statistic available in an interface that also shows the live games streamed over the internet. All great, all what I would expect. It include a feature that allowed you to add your favorite players (think fantasy baseball) and it would alert you every time your player did something in any of the games. It would also serve up the specific video clip of that notable performance. (On a sidenote, thsi guy said that they generate 10 DVDs worth of data with every pitch of every game. That seems like a little bit. :))

Anyways, even the fantasy player list wasn't the coolest part of this demo. Oh no. He then pulled out his cell phone, and showed us a Silverlight application running there. It showed stats, game scores, even live score updates, and runners on base. Think about the graphics that show up during a TV broadcast. Minus the actual game video. Well, with Silverlight, it appears they are going to be successful in streaming actually live video to your phone, and remember that fantasy player list, statistics, and video feeds? That was all demonstrated as well.

Man, this has been amazing thus far. Thanks again to Quick Solutions for sending me here.

Labels: , , , ,

posted by Jeff Blankenburg, 6:34 PM | link | 1 comments |
January 2006
February 2006
March 2006
April 2006
May 2006
June 2006
July 2006
November 2006
December 2006
January 2007
February 2007
April 2007
May 2007
June 2007
July 2007
August 2007
September 2007
October 2007
November 2007
December 2007
January 2008
February 2008
March 2008
April 2008
May 2008
June 2008
July 2008
August 2008
September 2008
Credit or Debit?
Reformatting my blog...
TUTORIAL: Using Javascript To Call A WCF Web Servi...
DevLink '08 in pictures...
.NET Rocks at DevLink!
Consuming Web Services In Silverlight
Obscure Knowledge: The Levenshtein Distance
Codestock 2008 - Photos In Review
Streaming Live From Codestock!
NBC Olympics - In Silverlight 2!