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

Thursday, September 11, 2008

Have you been to the gas pump lately? Have you been as perplexed as I am by the question you first get asked at the display?

CREDIT or DEBIT?

The reason this bothers me is because I thought they were supposed to be the same thing. I mean, I know that my debit card is tied to my checking account, and my credit card is tied to a bill I receive each month, but what difference does that make to the machine that is processing my card? Here's my decision tree each time I fill up my car:

If I'm using my DEBIT card,
     If I press the DEBIT button, I have to enter my PIN. Then it works.
     If I press the CREDIT button, it just works. No extra step. No extra cost.
If I'm using my CREDIT card,
     If I press the DEBIT button, it's not going to work. Because it's not a debit card.
     If I press the CREDIT button, it just works. No extra step. No extra cost.

So why, then, is there a choice for me? I'm not invested whatsoever in the outcome of this transaction, other than the total cost of the gasoline. My guess is that there's probably a different cost structure for each transaction for the gas station. Let's guess $1.50 per CREDIT transaction, and only $1.00 per DEBIT transaction. I have no real idea what the costs are, only that they are probably different.

So then why does the station offer a choice? Well, much like building an HTML and a Flash version of a site, you're never sure that people will have a credit OR a DEBIT card. So you need to provide options for both.

But what still bothers me about that is this: If you were just to process all of the transactions as credit, you'd take an entire confusing step away from your users. So my question to all of you is this: Why do we get this silly choice?

If I have to answer a silly question, why not make it something useful for me? Often times when I am traveling, I know I'm going to get gas AND run inside for something to eat/drink. But many pumps require me to swipe my card before I can pump gas. So my choices are:

1) Go inside first, then do the gas.

2) Pump gas in one transaction, pay for snacks with another.

3) Skip the Red Bull and give my heart a rest.

I'm not really a fan of any of those. Why not give me a prompt similar to:

Getting snacks? Just tell the cashier your pump number and we'll add it to your puchase! (You're on pump #3).

It cuts down on the number of costly transactions for the gas station, and simplifies my life. Win-win! (By the way, for each transaction that uses this methodology, I will expect $0.25 from the gas station that stole my idea.) :)

Labels: , ,

posted by Jeff Blankenburg, 1:53 PM | link | 9 comments |

Monday, September 08, 2008

I've got an overall plan that I'm not fully ready to expose just yet, but for the time being, you're going to see some dramatic changes to the face of jeffblankenburg.com. It will still be my blog, but the content surrounding my posts needs a major overhaul.

It started with the new navigation last night. But I promise there is more coming. Stay tuned over the next few days.
posted by Jeff Blankenburg, 11:14 AM | link | 0 comments |

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 |

Monday, September 01, 2008



I created a quick mashup in Popfly using my Flickr account. Enjoy!

(I highly recommend the full screen option. These pictures are BIG.)

Labels: , , ,

posted by Jeff Blankenburg, 6:06 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!