Am I running in DesignMode?

Posted 2003-09-30 10:20 PM in ASP.NET.

Well, crap.  It's 10:10pm.  I'm at work.  I missed the Portland [.NET] Bloggers Dinner.  It was one of those coding things...just one more class...then I'll get validation working...then I'll add configurability...you know.  Poop.

But, I did learn something interesting that wasn't obvious to yours truly.  I have a class heirarchy for my ASP.NET pages so the developers that use my infrastructure to build bankings sites have a few things always available to them.  The pages derive from blah.blah.blah.SharedBasePage (ya, I know it's a lame name) which derives from LocalizedPage.  It happens to be a heritage that spans 3 related assemblies.  They all used to be in the same Web Project, but I started pushing them up in my recent mad refactoring. 

Now, at SOME point along the line, I lost Forms Design Time support in VS.NET.  I started getting this doozy: "The designer could not be shown for this file because none of the classes within it can be designed."

This perplexed me, but really, I don't care since I'm all about HTML and asp:this and asp:that.  But, my users/developers will care, so it was eating at me.  The problem was, I couldn't remember when I broke it.

Yada yada yada, it turns out I had a line like this in a constructor up the chain:

resmgr = ((System.Resources.ResourceManager)HttpContext.Current.Application[Constants.RESOURCESTRINGS]);

And when VS.NET switches into Design Mode, it actually INSTANTIATES the page class.  (Read that again if you didn't get it, I didn't.) 

So, of course at Design Time, the HttpContext.Current is null.  So, that line now looks like this:

if (HttpContext.Current != null)
   
resmgr = ((System.Resources.ResourceManager)HttpContext.Current.Application[Constants.RESOURCESTRINGS]);
else
      System.Diagnostics.Trace.WriteLine("Note: We are NOT running with valid HttpContext. We are probably in the IDE.  Or, something is wrong with the flux capacitor.");

So, magically, all my Design Time support is back, and I'm actually using it.  Maybe I wasn't such an HTML bad-ass after all.



Two cool things this weekend....

One, saw The Rundown which is probably the most all around fun I've had at a movie in years.  Probably since the Matrix (the first one).  I'm a bit of a gourmand when it comes to cinema, and certainly there have been lots of great movies in the last few years, but name one that you walked out of saying "That was so fun!"  I recommend it highly.

Two, I hooked up all my emails (and my family's) with the SpamSoap service and I'm LOVING it.  It's and interesting hack.  There appear to be a range of anti-spam solutions for the Home or Home-Office out there that fall into some basic categories, and those categories are organized by "tier". 

  • Client - catch it as it shows up with SpamBayes, SpamNet, OfficeMavin, etc.  Also, Outlook 2003 has quite good Junk Mail filtering built in, and allows you to whitelist at the client side.
  • Server - actively run a spam filter on your server (if you control your mail server) and while you still have to download the spam (so the spam actually uses YOUR bandwidth) it can be caught before you or your users download it.
  • Server with Human Interaction - I almost decided on a solution like SpamArrest.  Basically, if someone emails you, the get an immediate bounceback email that tells them that you hate spam, and if they are really a human, would they please enter in the words that appear in this obfuscated image to prove it.  If they are a human, their email gets delivered and they are added automatically to your whitelist. 
  • MX Record - Since I don't control my mail server (ORSCWeb does) and I don't want to, I wanted a server-side solution that was in the "chain" of email processing, but not email client-specific. So I modified the MX record to point to the SpamSoap service (they offer a 30 day trial).  My DNS's MX record usually points to my mail server.  Now it points to SpamSoap, who receives my email for me, scans it, and redirects spam to a special "spambox" while real email moves along unmolested.  Here's an interesting article about "Fighting Spam with DNS."

It actually worked so well in the first few hours that I thought my mail was broken.  I had never hit "Send/Receive" and NOT received SOMETHING.  Here I was hitting F5 wondering if I'd messed it up.  Then, a legitimate email showed up.  Boom.  Very nice.  Since I turned it on Weds, I've NOT downloaded over 1500 spams. 

It's a shame that a service like this is almost required (for your sanity) but it's also a joy when it works so smoothly.



It's 12:18am and I'm hopped up on at least 96 ounces of Diet Pepsi and vibrating with the excitement that you only get after a 15-hour-marathon-coding-just-one-more-method session.  Having a blast, or hooked on crack?  You decide.

Here's what I'm hip deep in and did today:

  • Cookieless Forms Authentication - You may have noticed that FormsAuthentication still makes Cookies even when SessionState is set to Cookieless=true.  No longer, for me at least.
  • ASP.NET Internationalization - I completely refactored LocalizedPage with input from Chris Kinsman, Chris Brooks, Bradley McLain and Alex Ginos.  Thanks guys! 
  • With inspiration from Clemens, I'm all over SOA and trying to reconcile those things about OOP that don't jive in a SOA world. 
  • XmlSerialization - I am consistantly imressed with how slick XmlSerialization is in .NET for a "1.0" attempt. 
  • Log4net - Very sweet.  I'm glad I took the time to set it up.  I encapsulated it and will be writing some Corillian-specific Appenders, but it got me 90% of the way there.  It's the cat's pajamas.
  • ObjectBinding - Binding objects to ASP.NET DataGrids is a hassle, but if you put the effort into it by making Strongly Typed Collections (Thanks QuickCode.NET!) and including public properties for those things you wish to bind, it DOES make life easier for the UI Programmers.  Also, I've decided I really prefer dealing with strongly typed objects instead of DataSets (strongly typed or otherwise).
  • XSD.exe - is nice, but just not smart enough.  For a fairly complex Xml InfoSet I still have to put about 15-30 minutes of just typing to get the autogenerated .CS files to include property getters for DataBinding, better XmlElement andn Variable naming choices and the whole [XmlIgnore] strongly-typed-collection-with-parallel-array trick.  It's time to move this crap to a code generator.  I'd like to either:
    • Find a smarter XSD.exe
    • Write an uber-xslt that takes XSDs and gen the code
    • Perhaps CodeSmith?
    • Geez, I can't wait until Templates.  Oy.

What current code generator is the best for taking XML input and making code? Comments please...



Google plus MapPoint = GooPoint? Mapgle?

Posted 2003-09-25 07:54 AM in Musings.

Well, this is an interesting development at Google Labs.

http://labs.google.com/location?q=professional+developers+conference&geo_near=los+angeles%2C+ca&Search=Google+Search

I was wondering when this was going to happen.  I'll need to use it a few times to see if it's as useful as it sounds, but it's surely a good example of why Google is (and will continue to be?) on top.



I'm ready for a change.  I'm ready to be impressed.  If you know me, I'm all about Microsoft.  I dig them, their tech, especially their people.  While I've worked in Java on Solaris talking to Mainframes, I really cut my teeth on writing thunking code during the 16-bit/32-bit transition.  I know I'm not an "old timer."  I've never seen a punch card. (Although I've read Cryptonomicon. ;) )  I'm Generation X or Y, not Generation U or V.

I'm from a middle place.  I'm younger than some, but older than others.  I've coded on TRS-80s, TI99/4a, C64 and Apple.  I've used 8" floppies.  I've lived in DOS from >= version 3.  I've run NeXT, Amiga, GEOS, CP/M, OS/2, Desqview, Windows 3.0, 3.1, 3.11.  I've run SnowballChicago, Nashville and Memphis, worked in Daytona and Cario.  I love Whistler, look forward to Longhorn and really don't understand how Blackcomb fits in.  I scored 60.85% on the geek test.  No doubt, you and I are alike.

I was on AOL 1.0, Compuserve, GEnie, Prodigy, all from DOS.  I've surfed with Lynx, read mail with pine.  I ran Mosaic, I now run Firebird. I ran vi, emacs, pico, PaperClip, WordStar, WP5.1, and Office 2003 Beta

I had 8k of RAM and now I have 1.5 gigs of RAM.  I had no hard drive, then a Winchester Hard Drive, now I have 425+ Gigabytes at my desk.  I had a keyboard, then a mouse, then a mouse with two buttons, now a wireless mouse and keyboard with 5 buttons and a scrolly-thing.

I remember Shift-F7 would print in Wordperfect, I'm not sure why I haven't overwritten that mental cluster with more useful information.  Certainly I've at least marked the braincell for deletion with the first character as E5h or something.  Now I have a GUI, which brings me the the point of this rant.  I certainly haven't seen it all, but darnit I've seen some of it.

I admit it, while I'm privvy to many a Microsoft Pre-Alpha, I have not seen anything of Lornhorn's "real" UI, nor what I'm really interested in - Avalon

If you do one thing before you go to PDC - look at the demos of Mac OS X's Panther.  What I want is for Avalon to blow this away.  I want to be impressed.  I want a WHOLE new world.  I want to see some Microsoft UI Research and Usability to really come to a dramatic fruition.  I know Avalon is a next-gen graphics subsystem, but I want to see what totally new UI paradigms (read: moving past Windowing and the Start Menu) can be built on it.  I want to make my 256 meg Video Card dual-head Video Card WORK.

I'm coming to PDC thoroughly hoping and expecting to be impressed with the promise of the future.  Am I impatiently expecting a revolution in UI, while Avalon may be a just stepping stone on the way to...?

Will I be disappointed? 



There's nothing quite like the smell of a fresh Windows box.  After that first reboot, seeing that clean, smooth desktop brings a tear to my one good eye.  Everything is possible with a fresh Windows box.  Everything runs faster with a fresh Windows box.

Then I plug into the network and I'm immediately attacked by Popup Ads, Gator (evil), DoS attacks, Messenger Service Popups, HTTP requests for /system32/cmd.exe and clever neighbors trying to print to my printer. 

How should we protect our fresh Windows boxes, these new fawns, just before we hurl them into the abyss?

Well, here's the first things I put on ANY Windows box.  This is the "don't leave home without 'em" list.  This is the "You're not seriously going out without your _______" list. 

"Anti"-Things you must install on your fresh Windows box in the 21st century

  1. Firewall
    At a minimum, enable the Windows XP built in firewall.  This will protect you from MSBlast (which I removed off half a dozen relative's computers).  Other folks use Tiny Personal Firewall, and others, but if you're serious (and you love your family) just buy ZoneAlarm Pro.
  2. Anti-Virus
    In the old days, (last year) you could be clever and avoid viruses.  Don't open anything, don't talk to anyone.  But now, with attachments being sent to my Mom with names like babypics.jpg.exe, I just can't trust her to be THAT clever.  Heck, I don't know if I am that clever.  I use either Panda, ETrust, or Norton...but my preference is Norton.
  3. Anti-Spyware
    The #1 least understood problem on PCs today, IMHO, is spyware/malware/scumware.  A friend of mine visited recently from Malaysia and brought his laptop.  He's a technical guy, and a developer, but he was complaining of weird popups and odd behavior in his browser during development.  We ran Ad-Aware and counted up 357 different components of spyware.  He had at least 20 different evil (but not viruses!) bits on his box, including CometCursor, Gator, SafeCast, Hotbar, and a particuarly evil bit of spyware that actually chained and appeared in the TCP/IP Properties and literally sniffed traffic at the protocol level.  I install Ad-Aware and run it on Startup.
  4. Anti-Spam
    Everyone has their favorite, but I recommend SpamNet, it's like Napster for getting rid of Spam.  When you block a spam message with SpamNet you are "voting" for that message as Spam.  The more people vote, the more accurate SpamNet gets.  It's at least 99% with VERY few false positives, since actual humans are involved.  On the server-side for a Spam solution, I'm going to check out SPAMSoap.  I'll just change the MX record on my mail server, and mail will route through SPAMSoap first, then to me.  It appears to be a nice, cheap way for me to protect all my hanselman.com users.

If you're not running these particular tools, make sure you are at least running something to address these issues.  And seriously, run Ad-Aware if you haven't.  You'll be surprised.



Holy Crap, 70-300

Posted 2003-09-22 01:20 PM in Programming.

I woke up today and checked my Outlook Calendar first thing, like I do every morning, just to make sure I wasn't missing any 8 am meetings, and dammit if I didn't completely forget that like 6 months ago I scheduled a MCSD.NET test for Exam 70-300: Analyzing .NET Requirements.  Original MCSDs were given a free coupon for the new 70-300 but only if they took it by September 30th.  I got the coupon, cheapskate that I am, and immediately schedule the exam WAY out in September (today) figuring, "Hey, I've got months to worry about this."

This is the test with all the "new" kinds of questions.  It's got a chunk of multiple choice questions, but as soon as you get comfortable, you're faced with some weird E-R diagram with an interface that's straight out of Windows for Workgroups.  It's the Year-of-Our-Lord-Two-Thousand-and-Three and I'm taking this brand new test on 16-bit Windows.  I swear it was the same computer running the SAME software at the same testing center that certified me on WfW in 1993.

But, long story short, I passed it in about 40 minutes and made it back in time for lunch.  Now I can go back to my personal hypocrisy of bad-mouthing certifications.



The replacement TechEd bag just arrived...

Posted 2003-09-22 01:08 PM in TechEd | Speaking | PDC.

A very suspiciously-shaped package from a random distribution-warehouse-sounding address just arrived - what's inside?  Well, none other than a Replacement Backpack from TechEd U.S.  You might rememember that at TechEd by the end of the week many folk's bag's inner linings had ripped and at the end of the week there was an announcement that the bags would be replaced.  I still use my bag (I just hang on to a bag until the next conference, then I use that bag...wonder what we're getting at PDC?) and it's ripped all over.  At a recent garage sale I sold about a dozen bags for about $5 each, some going as far back as a SiteBuilders conference in the mid-90's...re-selling conference bags to the general public could become a lucrative side business for me.  I should probably read the bag's EULA, though. ;)

Anyway, I'm not sure what critical structural reinforcement or steel beams have been added to this new bag; it looks just about the same to me.  Either way, kudos for MSFT for making good on their promise.



This speaks to me, not only as a reformed Java person, but also as the owner of a Toyota Prius and a Honda Civic Hybrid...

"Our students this semester in 6.171, Software Engineering for Internet Applications have divided themselves into roughly three groups.  One third has chosen to use Microsoft .NET, building pages in C#/ASP.NET connecting to SQL Server.  One third has chosen to use scripting languages such as PHP connecting to PostgreSQL and sometimes Oracle.  The final third, which seems to be struggling the most, is using Java Server Pages (JSP) with Oracle on Linux.  JSP is fantastically simpler than "J2EE", which is the recommended-by-Sun way of building applications, but still it seems to be too complex for seniors and graduate students in the MIT computer science program, despite the fact that they all had at least one semester of Java experience in 6.170.

<snip/>But the programmers and managers using Java will feel good about themselves because they are using a tool that, in theory, has a lot of power for handling problems of tremendous complexity.  Just like the suburbanite who drives his SUV to the 7-11 on a paved road but feels good because in theory he could climb a 45-degree dirt slope." [Phillip Greenspun's Blog]



For those of us who live in Portland, Neal Stephenson, author of Cryptonomicon, Diamond Age, and more importantly, Snow Crash, is doing a book signing (get that dog-eared copy of Snow Crash signed!)on a press junket around his new book Quicksilver on Wednesday, September 24th.



I presented at ASPLive! and TechEd 2003 on Internationalizing ($g(i18n)) ASP.NET.  I know that the story changes with Whidbey and changes dramatically post-Whidbey, but until then...what are the best practices for ASP.NET 1.1?   DasBlog is a good example, as is (IMHO) the code I showed at the conferences.  Each takes certain approaches for performance vs. ease of i18n vs. avoiding $g(code smell).

Some random thoughts, some questions, some rethorical, some I could use comments/thoughts on:

  • Store a single ResourceMananger in the Application Object and either yank and cast as needed or stick it in some base blass.  [Seems reasonable.  Preferable over instantiating on each page?]
  • Create a base class (LocalizedPage, etc) that introduces an "OnLocalize" method and event, and performance most of your i18n there. [Good, but usually only an 80% solution.  Does let you bypass localization for the default language, though, and that's a BIG performance gain.]
  • For DataGrids, piggyback on DataBinding and do your i18n here [Not bad, easy, tends to spread i18n code out]
  • Localize in the .aspx page with <%#resMan.getString("someresourcename")> [Good, avoid cluttering code behind, also allows for quick changes without recompiles, although forces localization in the default language]

This and other questions burn...time to refactor...Now this looks like an interesting tool that makes ASP.NET localization more like WinForms localization.  I'll check out the trial, but I suspect it will break down when faced with complex ASP.NET DataGrids (definitely non-trivial to localize).



Sorry this isn't a technical post. :) I will continue to make this blog about the "Zen" of Computers, particularly .NET and Web Services...watch for a new look for the site very soon...

That being said, just when I start to feel lousy about being hooked up to an $g(insulin pump) 24 hours a day, I see this picture of the first insulin pump from 1978.  Guess I have little to complain about!



Note to self: Buy diverse dolls

Posted 2003-09-20 12:34 AM in Musings.

This is quite a clever idea.  I grew up with action figures and such of all colors, but this is a good reminder to me that when we do have kids (who will be diverse in their own right) to make sure their dolls and toys represent the real world, and the complete spectrum of diversity.  I was very fortunate growing up in a largely non-white neighborhood to get to attend many churches, synagogues, and mosques.

 



Well, last night's ephipany was right-on.  I finished DasBlogRadioCommentImport and ran it last night, importing hundreds of reader comments and successfully integrating them into each related dasBlog entry.  Let me know if you want the code via email.  When I get access, I'll post it on the GotDotNet workspace.

All in all, the Radio "conversion" was a big stick of butter. Here's the goodness:

  • Taking Clemen's lead, I modified my Radio template to include JavaScript and META refresh tags.  Some Details here.
  • dasBlog handles these redirects with a regular expression based $g(Url Rewriting) Module that is pure genius.  I added a series of expressions that didn't exist in order to handle Radio Categories and Radio Stories.
  • I imported all the Radio content with the included DasBlogRadioImporter.  Good.
  • Then I wrote DasBlogRadioCommentImport.  Better.

All in all, for existing Radio Userland users, dasBlog offers a fantastic migration story.  All my existing Google Radio links work.



I was sitting here doing some writing for work and out of nowhere came a flash, and I knew exactly how I could write a small command line util to import over a year of reader comments from Radio Userland into my new dasBlog setup. Coming soon, and Peter Provost shall be my first tester! ;)



For Windows XP: http://support.microsoft.com/?kbid=314056

To view the list of services that are running in Svchost:

  1. Click Start on the Windows taskbar, and then click Run.
  2. In the Open box, type CMD, and then press ENTER.
  3. Type Tasklist /SVC, and then press ENTER.

 For Windows 2000: http://support.microsoft.com/default.aspx?scid=kb;EN-US;250320

 To view the list of services that are running in Svchost:

  1. From the Windows 2000 installation CD's Support\Tools folder, Extract the Tlist.exe utility from the Support.cab file.
  2. On the Start menu, click Run, and then type cmd.
  3. Change folder to the location from which you extracted the Tlist.exe utility.
  4. Type tlist -s.



Everyone seems to be all into Myers-Briggs again. I've been the same personality type the last 3 or 4 times (over the last 20 years) I've taken this test. I will admin though, it's truly scary to read about yourself...



EnableVisualStyles strikes again...

Posted 2003-09-18 09:46 AM in Web Services | XML | Bugs.

My friend Jeff Berkowitz got nailed by the EnableVisualStyles bug in WinForms 1.1 that causes a weird SEHException when calling ShowDialog().  Jeff and his team really push WinForms to the limit and he finds some crazy stuff, including a scary Resource Naming problem in VS.NET 2003.

CLRSpy, Jeff Key, and Adam Nathan to the rescue though.  Although Jeff had debugged the problem and figured it out himself, CLRSpy would see the as an error probe and break on it.

Adam suggests three possible workarounds:

  1. Disable the PInvoke Calling Convention Mismatch probe, or
  2. Uncheck "Break on Error Messages" in CLR SPY so you can ignore this message and not provoke the crash, or
  3. Use an XML manifest to enable XP themes, rather than using the EnableVisualStyles API.

Of course, using the manifest is the preferred method methinks.



I gotta say, I'm really impressed with DasBlog.  Particularly the upgrade/moveover from Radio Userland.  It's really nice.  It's been a crazy week:

  • My email at hanselman.com was down since I left for ASPLive!  I wasn't even aware until I got back.  This includes all my relatives mail (really, who among us ISN'T the IT director for the entire family?)
  • I switched all my domains over to ORCSWeb.com.  Damn they are cool.  Their support is totally TOP NOTCH. 

At Stephen Forte's (and others) urging, I moved from Radio to DasBlog (no doubt there will be some cleanup and misc goo, but still).  It will be nice to be able to post from anywhere - not just my laptop!

  • I moved all my Radio articles into DasBlog with the importer tool...very slick.  Dump the resulting XML into the Content folder and you're in.
  • I added (thanks Clemens!) this META tag to Radio and re-rendered all the pages on my site for the last year.  This will redirect all visitors to the new site.  There is also some associated javascript that will bring their original referrer (Google, etc) along for the ride.
    • <meta http-equiv="REFRESH" content="2; URL=http://www.hanselman.com/blog/fromradio.ashx?external_referrer=&url=<%radio.weblog.getUrl()+path%>">
  • I imported my blogroll from NewsGator.  Had a little trouble with case-sensitivity re: xmlurl and xmlUrl.  Some manual editing did the trick; no need for XSLT (yet).
  • I modified the blogrolling display code to trim long titles and append "..."
  • DasBlog doesn't handle the concept of "Stories" from Radio, which are basically really long posts that get their own non-dated link.  Clemens suggested that I come up with a plan and add it to the GotDotNet workspace for DasBlog, but I don't have the time this instant.  Instead, I did this clever thing:
    • Added this URL rewrite info to the web.config:
      <add matchExpression="(?&lt;basedir&gt;.*?)/fromradio\.ashx\?external_referrer=(?&lt;ext&gt;.*)&amp;url=http\://radio\.weblogs\.com/0106747/stories/(?&lt;year&gt;\d+)/(?&lt;month&gt;\d+)/(?&lt;day&gt;\d+)/(?&lt;page&gt;.*)" mapTo="{basedir}/default_nocache.aspx?external_referrer={ext}&amp;test={page}" />
    • I couldn't find the xml versions of the stories (anyone?)...so I copied the rendered stories tree from Radio into blog/content/radioStories/.  Basically, if someone visits a story on my current Radio site, they'll be redirected to the same rendered (static) story inside DasBlog.



The Utilities Continue...

Posted 2003-09-17 06:35 PM in Web Services | ASP.NET.

The response to the Ultimate .NET Utils list has been overwhelming...over 10,000 hits over the last week!  Now DotNetBoy weighs in with his own list of utilities.  A lot of great stuff here, including several nice command line utils I haven't seen like:

  • AFind - command line util for listing files based on Last Accessed Time
  • Nupp.exe - a "Stack" for mapping drives (Push/Pop)
  • Sanur.exe - lets you pipe the password into RunAs, making RunAs scriptable



Seems like a lot of my posts lately have started with something like "Here's a weird IE bug" or "Here's something odd in .NET" but...

Here's a weird IE thing.  We do a lot of Check Imaging and Statement stuff here, so if someone wants to go online and get an image of a check, they can.  We often use Web Services to talk to a Check Imaging Server.  Most often we retrieve PNG, JPEG, or GIF.  Sometimes, however, the client wants an Adobe Acrobat PDF. 

We'll make the SOAP call, get a PDF then stream it directly to the user (You don't want to save these kinds of things, for security purposes). 

Enter bug/feature Q293792.  Not a lot seems to have been written about this, and not a lot of people seem to care, but apparently when opening a full ActiveX embedding window (to host Acrobat, etc) IE makes either THREE or TWO requests for the content.  This is apparently "by design" as URLMON and MSHTML have trouble communicating.  So, MSHTML sends a request to "sniff" for the MIME type to figure out what app to load. 

Other than being a bandwidth hog, this wouldn't be a big deal - except, when the generation/retrieval of a PDF is an expensive operation involving a WS call to the back end. (Wow, a production Web Service! Madness! Heresy! ;) )

What's interesting is that IE changes the UserAgent HTTP Header to "contype" during the probe, obstensibly so we can simple return the MIME/type and not the actual data.

So, we need to handle that...something like (in classic ASP "psuedo-code"):

  If Instr(1, UserAgent, "contype") > 0 Then
   'Just send the mime/type
   Response.ContentType = "application/pdf"
   Response.End
  End If

So, that's not too bad.  But, even the "Fixed" versions of IE still send TWO requests.  So, we want to detect the second request and not return the whole thing again. 

Here's the other ODD point.  For reasons unknown to me, IE doesn't include the Accept-Language header when making this second call, so, we have them use what has already been sent by saying "Not-Modifed":

  Dim Language
  Language = Request.ServerVariables("HTTP_ACCEPT_LANGUAGE")
  If Language = "" then
   Response.Clear
   Response.ContentType = "application/pdf"
   Response.AddHeader "Last-modified", "Mon, 01 Sep 1997 01:03:33 GMT"
   Response.Status = "304 Not Modified"
   Response.End
  End If

Ah, the fun of supporting older versions of IE.  I think we need an updated IE Roadmap. 

The future of browsing, dear readers, is up in the air, IMHO.



Switching [all] Providers...

Posted 2003-09-16 03:21 AM in DasBlog | Diabetes.

Well, my Hanselman.com email (as well as for all my Hanselman relatives) has been down with DNS and dumb problems since Friday, so it's official.  I'm switching.  I'm switching to ORCSWeb.  I'll move all my domains there, including www.hanselman.com, www.diabeticbooks.com, www.glucopilot.com and www.computerzen.com.  Expect some weird DNS and silliness over the next few days, possibly this week.  I'm a huge believer in the permalink, so if I do it right, everything will work as before. 

After the dust has settled, I'll likely move from Radio to DasBlog.



Linux/J2EE causes colon cancer?

Posted 2003-09-12 03:13 PM in Musings.

Wow...good thing I'm covered! ;)

A Forrester research project, funded by Microsoft inc., has determined that developing software using a Linux/J2EE development environment increases a developer's risk of dying from colon cancer by up to 40% over the risk when developing with Microsoft's .Net technology.



Rory asks, Why do I code?

Posted 2003-09-11 10:33 AM in Web Services.

Why do I code?  Because I can't cook, or change my own oil, or mow lawns.  Because I lettered in drama in High School but I never got discovered walking an L.A. mall.  Because I never made any money doing standup.  Because, God help me, if I wasn't coding the only think I'd be good at would be selling cars.  (I'm REALLY good at selling cars.  Seriously.)

For real, I code because I like solving problems that are decidedly solvable.  I mean, I hear the problem, I think for a moment, I figure it's "possible" and then I try to figure how to solve it in a way that feels good.  Because I dig physics.  Because the end of the Carl Sagan's "Contact" was UNSPEAKABLY cool.  I code because of that feeling I've gotten 5 or 6 times when I just NAILED a problem and (while alone) raised my arms high in victory the same way that rapid sports fans do.  Except I look at them with a worried disdain when they do it, but secretly I wish I felt like that more often.

I code because coding, at its best, is art and literature and math and physics all at the same time.



I'm sitting on a plane from St. Louis to Orlando on the way to VSLive/ASPLive.  I was thinking about who I'm going to see at the conference.  I figure that my buddy Chris Kinsman will be there and possibly acquaintances of mine such as Keith Pleas.  Why just acquaintance?  I've had the pleasure to email Keith four or five times and I've met him four or five times, but when I see him I still lead with, "Keith! Scott Hanselman, how are you doing?" just in case Keith doesn't remember me, and this way he doesn't have to waste CPU cycles looking my face up.  I do the same thing with other acquaintances and "colleagues" like Chris Sells and Don Box and [Insert name here], et. al..  They are colleagues as I see them a few (sometimes several times) a year on campus or at conferences.  I say hi, but don't expect them to know my wife's name, since when you're holding all the WS-*.* specs in your head, sometimes you can't remember lots of trivial social details. 

So I got to thinking about the difference between "friend" and "colleague/acquaintance."  I have some remote friends, Patrick Hynds for example, who I chat with a few times a week and who could TOTALLY crash at our place on a moments notice.  We've shared (soft) drinks many times and have stories going back years.   But, I've only seen Patrick at conferences and on campus also.  Hell, I started to realize that I see Don Box more than I see my uncles (I see them on the 4th of July and at Christmas) and Don remembers my name better than my cousins! 

Therefore, I conclude that either:

A. I'm not nearly close enough to my family and need to spend more time with them instead of at conferences

or

2. Patrick, Keith, Don, ClemensChris, Chris, Sam and MANY others that I see several times a year are my REAL family and will not be surprised when I show up on their door wondering if I can sleep on their couch.

 Anyone else have this problem, or just me?



It came in the mail today...

Posted 2003-09-10 01:49 PM in Musings.

It came in the mail today, and it's about time.  What's next?



So, two people commented (one email, one blog comment) with some confusion over the 11/9.  Here's the explanation:

It was an internationalization joke (and a good one I thought) When we say 9/11 (formatted mmddyy) most people in the STATES assume we mean September 11.  In the last two years the word 'nineeleven' means more than just a date.  But it's use and newly attached deep meaning underscores how alone we are as a nation (not just politically) in things like date formatting and the measuring systems.   The rest of the planet uses ddmmyy, so they would say "11/9". 

The joke is, when we say "oh, ya, 9/11 was a horrible day," a non-american might say, "November 9th? What happened?"  Of course, nothing happened on 11/9, we just assume that 9/11 or 4/3 or 8/12 means the same thing to us as it does to them...

P.S. There was a local news report a while back that the local news had pulled off the AP NewsWire.  Some fellow came in on a Tourist Visa and transferred to a Student Visa.  At some point, he was arrested for some thing or the other and the local news lady, thinking this fellow had gotten away with some clever chicanery commented slyly that his identity was called into question when the news station "discovered" that his drivers license said he was born on 4/3 but his birth certificate listed his DOB as 3/4.  Oh, those wacky terrorists trying to pull one over on us.  If I had a nickel for every time an international friend reversed a date on a form...



Tomorrow, I'm leaving for Orlando to speak at ASPLive on Internationalization.  I'll be flying exactly two years (to the minute) from September 11.  Needless to say, the wife's justifiably not happy about it and I have mixed feelings. 

My boss says that even flying on September 11th is safer than driving any day.  I'm not sure about that, but I'll definitely be expecting some extra security.  It's always a challenge to get my Insulin Pump through.

If you're in Orlando at VSLive, please do stop by my Friday afternoon session called "It's the WORLDWIDE Web."  I'll be showing some cool stuff in ASP.NET like a banking site in English, Chinese, Malay, Spanish and Arabic.  We'll talk all about System.Globalization and dig into the issues around Dates, Currency, Culture and Right to Left languages.  It's a very interesting topic.  I may try to greet the crowd in at least 10 languages. :)

Remember, when we talk about what happened on 9/11, most people in the world wonder what happened on November 9th...



Well, that was a nice little spike of traffic.  A few random thoughts:

  • Thanks to everyone for comments and author corrections for the tools on my List o' Tools. 
  • Too bad Radio doesn't appear to support Trackback/Pingback from 'Stories' or I'd know who's linking to me. 
  • I'll continue to update the tools list as I add more.  I'll also try to categorize it one day. 
  • Note that I only keep favorite tools - no cruft, no crap.  This isn't a list of "all tools" or "favorite tools" but rather "things that make my life better"
  • Some folks commented that it was mostly Windows and .NET stuff.  True, true.  That's where I live now, but some tools/utils I didn't include were Grep for Windows and Cygwin and Visual Studio Power Toys, etc, as I didn't think they qualified as simple little utils, although maybe they do.
  • I didn't include a utilities that are internal (either Corillian-internal or Microsoft-internal) although I wish I could.  There's some amazing stuff out there.
  • Now only if my list could get Scobleized by Robert's 18 readers...
  • As I sit here and look at my Start Menu, that fills my 1600x1200 screen and runs off the right edge, I see at least 40 other great utils that AREN'T in C:/UTILS that I missed.  I'll add them one day.



Roy Osherove suggested that I post a list of the contents of my C:/UTILS folder.  Everyone collects utilities, and most folks have a list of a few that they feel are indispensable.  Here's mine.  Each has a distinct purpose, and I probably touch each at least a few times a week.  For me, util means utilitarian and it means don't clutter my tray.  If it saves me time, and seamlessly integrates with my life, it's the bomb.

Here are most of the contents of my C:/UTILS folder. These are all well loved and used.  I wouldn't recommend them if I didn't use them constantly. Perhaps Roy didn't realize what he was asking for.

One day I'll categorize them (if someone cares) but until the, here's "Scott Hanselman's Ultimate Developer and Power Users Tools List" for your approval.



iPods are God's Gift

Posted 2003-09-08 10:55 AM in Web Services | Tools.

Oh yes, the iPod is the shiznit.  I had a Rio 500 for a number of years with 128 megs of ram and got my iPod about 6 months ago. 

I do recommend, however, immediately jettisoning the crap MusicMatch software and using these tools:

  • EphPod for the quick and dirty work: Add a song, edit IP3 tags, adding Outlook Calendar appointments, vCard Contacts, text files, etc.
  • MoodLogic and DeviceLink are the best thing to happen to MP3s since Napster.  Of course, I don't share music anymore, but I do rip the hell out of my 500+ CD collection.  MoodLogic is worth the money just for it's song identification capabilities.  It fixed the file names on at LEAST 1000 of my songs, including what # it is on the CD, who the artist is, etc.  Plus, it creates "Mood Mixes" in the iPod automatically.  Coincidentally, the core of it's iPod compatibility is...EphPod.
  • Then, just for kicks, use Muse.NET to listen to your 20 gigs of music, legally, from work with .NET and Web Services.  There are lots of sample applications (many in .NET) to exploit their API, and exploit the programmaticalshipfulness of your music.

Now, if I had only waited, I could have had a 20 gig iPod for the same price...



The Microsoft Roadmap Decoded

Posted 2003-09-08 09:53 AM in Web Services.

Just when I'm asked to start thinking about Technology Roadmaps, I find this great dissection of the Microsoft Technology Roadmap.  Some highlights:

Disappearing Code Names (Gone, But Not Forgotten)

Product Name/ "Code Name" Additional Info. Projected Ship Date
"Shorthorn" (33) Stopgap release of Windows client 2003
.Net My Services/ "Hailstorm" MS thought to be building many of these into future Windows editions 2004
"BizOffice" combo BizTalk-Office application for B2B 2003 (?)



It's happy utility day!

Posted 2003-09-08 08:52 AM in Web Services | TechEd | Speaking | Bugs.

Finally got around to installing my new shiny version of SoapScope, the little sniffer that could.  I showed an early beta at TechEd 2003 in Dallas, but now it's released!  It's wicked cheap, and when you're doing Web Services development in a workgroup situation, especially when the interface is in flux and the folks on the other side are in another time zone, it's slick. 

It stores all the traffic in a built-in database and others can view and debug the service as it moves through time using a web interface served by it's internal (Apache) web server.  It sniffs traffic via a packet capture OR as a proxy.

Two new features that I'm really digging are the WSDL Analyzer that checks for validity and compilance, and the Diff-er, that gives a sweet view of what's been changing from call to call, version to version.



DeveloperPlayground

Posted 2003-09-08 08:04 AM in Web Services | Tools.

My buddy Jonas Blunck, hero of the people and maker of ComTrace and IEHttpHeaders has done it again (along with Kim Gräsman) with DeveloperPlayground.  At first it looks like Process Explorer from SysInternals, but it includes such cleverness as:

  • Shows run-time DLL dependencies for running processes
  • Hooks any process, and tracing single calls to external DLLs
  • Integrates with favorite tools such as Google, OleView, Depends and the Explorer
  • DeveloperPlayground now lives happily in the hallowed halls of my C:/UTILS folder with the best of them.  Great job guys, keep it up!  I think be using and suggesting this util in my C# Class this fall.



    Technical Debt

    Posted 2003-09-08 07:15 AM in Web Services.

    A nice clean way to describe the ramifications of the decisions we have to make every day.  Also, a way to describe to our bosses (in term$ they understand) why doing something quick-and-dirty may bite us in the ass.

    "Technical Debt is a wonderful metaphor developed by Ward Cunningham to help us think about this problem. In this metaphor, doing things the quick and dirty way sets us up with a technical debt, which is similar to a financial debt. Like a financial debt, the technical debt incurs interest payments, which come in the form of the extra effort that we have to do in future development because of the quick and dirty design choice. We can choose to continue paying the interest, or we can pay down the principal by refactoring the quick and dirty design into the better design. Although it costs to pay down the principal, we gain by reduced interest payments in the future" [Martin's Bliki]



    The Zen of .NET: Vacation Continues

    Posted 2003-09-06 09:22 AM in Web Services | TechEd | Speaking | Africa.

    Still on vacation...it's my first one in I don't know how long and I am ALL kinds of jet-lagged.  I just don't know what time it is.  When we went to Zimbabwe (+10 hours) I had no jet-lag, but Malaysia (+15) is messing me up.

    Anyway, turns out that the Zen of .NET presentation at TechEd Malaysia did all right.  Apparently there was a short write-up in the Malaysian newspaper "The Star" on The Zen of .NET.  I don't remember saying some of the quotes, but it's still nice to see that the talk resonated with folks.

    Back to work, and too blogging on Monday.  I've got a particularly interesting Web Services and WSE 2.0 multi-protocol problem I've got to share.



    .NET Code and Intellectual Property

    Posted 2003-09-02 01:37 PM in Web Services | Tools.

    Here's an interesting idea via Bill Wagner - a code copyright watermarker...it creates an obfuscated function that contains your copyright notice.  Clever...of course when you look at the generated code, you can see it isn't required and it's easily removed.



    PDC - The Blogging Begins...

    Posted 2003-09-02 01:21 PM in Web Services | TechEd | Speaking | PDC.

    Kevin Schuler's PDCBloggers.net is up and it looks like it's going to be HUGE - much bigger than TechEdBloggers.  Already the list of blogging Attendees is 46 and growing! 



    I reported in August of the Tragedy Of The Missing TechEd DEV389 Session on the Conference DVDs. Fortunately, my Malaysian buddy Fun Jim Lim pointed out that my session is available online!  Glory of glories.  Now the 3 people who've shown up here via Google looking for it will actually find something!

    TechEd 2003's DEV389: Learning to Love WSDL is here: http://microsoft.sitestream.com/DEV/DEV389_files/default.htm



    My blogging buddy Jeff Key (maker of the increasingly useful NetPing) has posted yet another snazzy util, a Code Snippet Compiler.  As .NET folks, we all find ourselves creating junk Console applications with a Console.WriteLine just to test a snippet of code!  His utility sits in the tray and is always ready when you want to whip out a quick line or two. Very cool.



    My buddy Garrick just got a LifeScan UltraSmart meter and here's his detailed review:

    I finally an UltraSmart meter (just before they started to give them away). I intended to get one sooner, but they were not available in mmol/L format, which is what I use here in the great white north.  I started using it August 1, and there is now about 230 data points in it now.

    Most of what there is to mention about it has already been said, so I apologize if I repeat much.   I do have an AccuSoft Advantage Complete (also called a Manager) from several years ago, that does much of the same sort of graphing, though far less sophisticatedly. I had high hopes for the Complete initially, but I ceased using it because of the lack of precision and accuracy of the tests.  The Ultrasmart uses the same sensing system as the Ultra, so I assume it will have the same precision,  but also with an 8% low bias in the normal to high range.  [This helps to show better data than we really get, which makes us feel good.  I always add 8% to any reading I get that is not too low, and to my averages.] Unfortunate, considering it doesn't need to be inaccurate.

    The Ultrasmart is larger than the regular Ultra, as is the carrying case, therefore it is more cumbersome to carry around, so I likely won't use it as a portable meter.  It does use easily available triple A batteries, not as cheap as double A, but far cheaper than button cells would be in a meter like this.

    It looks nice, and can be easily confused for a PDA by strangers... as long as they don't see the blood spilling (:c>).

    Every 25 tests, it asks for confirmation of the test strip code.  This is inconvenient and a possible waste of a strip if you apply the blood sample without noticing that it hasn't become ready yet.  I have wasted 3 so far. Lifescan has made a couple of extra bucks for J & J.

    3000 test memory.  This is very practical for myself.  I don't download my regular Ultra meters, which have only a 150 test memory, to the Onetouch computer program regularly enough, so I have several large gaps in the stats.  Since this will be my most commonly used meter, there should be less gaps.  (I have 8 or 9 Ultras, altogether)

    To turn the light on or off, hold the OK button down for at least 1.3 seconds.   Note that you can turn the meter on with the light, and also go straight to the Fastfacts menu, by holding the OK button.

    The Ultrasmart is as easy to use as it possibly can be.  Very intuitive, even without the instruction book.  The Fastfacts button is my favourite.  It accesses graphs and averages, amongst other ways to observe the data.  The Graph of all results (push Fastfacts, select Glucose Analysis, push OK, push OK for Graph of All Results, push OK one last time or wait until the meter goes there on it's own) can only cover 3 days on the display screen, so it can be moved using the arrow keys, one data point at a time.  By holding an arrow key for long enough, you can get a 'flowing graph' that moves at about 8 data points per second.  Also, each individual point can be selected (push OK for the one that is flashing...hard to see especially without the light on) to view the 'comments' that were added to it... not something I will be doing.  The Graph by Time of Day works similarly, but can only include data points from one of the seven time zones (before and after each of three meals and one for night time).  You choose which one.  After you have seen one, you can use the back button to go back and choose another.

    Average of All Results is also easily available.  (push Fastfacts, select Glucose Analysis, push OK, select Average of All Results, push OK)  The display shows the averages for the last 7, 14,30, 60, and 90 days all on one screen.  Quite useful for quickly spotting trends over the last 3 months, though not as inclusive as the 'flowing graph'.  Average by time of Day gives the you the averages for the seven time zones on one screen.  First, you have to choose how many days you want the averages to cover.  You have a choice of 7, 14, 30, 60, or 90 days.

    One thing it lacks is the standard deviation (SD) of the data.  I consider the two most important numbers to be the BG average, but also the SD.  The SD tells me how tightly controlled I have been.  [It is available on the computer program though, however less convenient.]  SD isn't perfect of course.  The main problem would be having a lot of hypoglycemia.  Since hypoglycemia is not far from perfect, (compared to hyperglycemia),  having a lot of it would still show the SD to be quite low, and the average BG would also look very good, but I certainly wouldn't be feeling my best.

    It does have hypo information, which is useful, especially considering that hypo level is customisable, as is the 'acceptable' bg range, both before and after meals.  For the post meal data to be reasonably accurate, you would have to eat at regular times.  I just use the same range for all times anyway so that is not a problem for me.  [My target is 4.7 (85), or my target range being 4 to 7 (72 to 125), which is the range for which if all is stable, I generally take no corrective action]

    As usual with all things techy, there is more here than I care to use.  While I do agree that the exercise, health, meds/insulin, and food data buttons are useful for many diabetics, I find I can remember these things easily enough now (except for my medical records which are stored on good old paper), that I haven't any real use for  their accompanying programs.  As well, the calculations and protocols I've developed for myself are much more sophisticated than the Ultrasmart allows for.  [For instance, my insulin protocols for backpacking took me 3 days of hiking at various distances and elevation gains.  The result is a schedule that reduces my basal and bolus dosages, and also the lead time on the boluses, based on distance traveled and how many thousands of feet of elevation gain I have done and/or will do  ...BTW, it seems incredible to consume 700 grams of carbs in a day, and only need a total of 15 units of insulin, including the basal.]

    The food data inputs capability may be suitable for type 2s, but are far too primitive for accurate enough calculating for tightly controlled type 1s, not to mention cumbersome.  I would however, highly recommend the food and exercise functions to new type 1s or type 1s just starting to use a basal/bolus routine.... partly because the meter provides some degree of fun.

    One thing I consider lacking, is the choice of viewing the averages back farther than 90 days. Though 90 days nicely covers  HbA1c, with 3000 tests stored, it easily could go back 8 months or even years, depending on the frequency of one's tests.  From my own bg computer programs, I do know that December, July and August are my worst months. However, making use of that much data would presume this meter survives as my favourite for long enough.  In the present climate of ongoing improvements that are happening to meters recently, it may not. 

    Garrick Neal



    Rapid Fire Blogging

    Posted 2003-09-02 12:27 PM in Web Services.

    Well, we're back from Malaysia, and I'm officially on my first vacation in recent memory.  I've had a couple of bloggable things on my mind, but I've been limited by time and internet access.

    I arrived home and checked my hanselman.com email from my home machine.  (I'd been checking my email remotely with OddPost, which is only the greatest remote email client since, well, ever.)   I use POP3, as I don't trust my server enough to use IMAP, and I leave the mail on the server and retrieve it from three or four different locations and client.  We were gone for 10 days, and as I hit Send/Receive I notice the status bar informing me that I have 1784 emails.  Seems a smidge much for only 10 days.  Of this mails about 1600 were spam and the remaining ~180 were legitimate emails that I'll need to deal with. 

    That's it.  It's whitelisting time.  I refuse to deal with this much spam.  For the last few months I've been using Spamnet, but I can't justify paying $1.99 a month to prevent email I didn't ask for!  So, I will now use the Junk Mail features in Outlook 2003 to automatically JUNK all email until I've added emails to a local whitelist.

    Next step is to look into a server-based whitelisting system for all my hanselman.com email account users and family members.  Anyone have any suggestions?




    Contact

    Sponsors

    Hosting By

    Am I running in DesignMode?
    Two good things this weekend...movies and spam
    A great day/night of coding...best one in years
    Google plus MapPoint = GooPoint? Mapgle?
    PDC. I'm ready for a revolution. Impress me. Blow me away.
    "Anti"-Things you must install on your fresh Windows box
    Holy Crap, 70-300
    The replacement TechEd bag just arrived...
    Java is the SUV of Programming Languages or Phillip Greenspun is a stud
    Neal Stephenson in Portland doing a book signing for Quicksilver
    Internationalization/Globalization and ASP.NET Brainstorming at 1:05am
    Technology and the first insulin pump...
    Note to self: Buy diverse dolls
    Bring all my Radio UserLand comments over to dasBlog
    Importing existing Radio Comments into dasBlog
    How to find out what's running inside that out-of-control Services.exe or Svchost.exe
    Personality Types - ENFJ - Like this surprises anyone who knows me?
    EnableVisualStyles strikes again...
    Moving from Radio to DasBlog, DNS, Redirects, Permalinks and Radio "Stories"...
    The Utilities Continue...
    Internet Explorer and the Magic of Microsoft KB Article Q293792
    Switching [all] Providers...
    Linux/J2EE causes colon cancer?
    Rory asks, Why do I code?
    Acquaintances, Buddies, Colleagues, Friends, Family, and Cousins
    It came in the mail today...
    The tragedy of November 9th
    ASPLive! and flying on 9/11
    Things that make my life better...thanks for sharing
    Scott Hanselman's Ultimate Developer and Power Users Tools List v1
    iPods are God's Gift
    The Microsoft Roadmap Decoded
    It's happy utility day!
    DeveloperPlayground
    Technical Debt
    The Zen of .NET: Vacation Continues
    .NET Code and Intellectual Property
    PDC - The Blogging Begins...
    TechEd 2003 - DEV389 - Learning to love WSDL has been saved!
    Yet another useful Utility - Snippet Compiler
    My Buddy Garrick Just Got A LifeScan UltraSmart Meter And Heres His Detailed Review BLOCKQUOTE Dirltr StyleMARGINR
    Rapid Fire Blogging

    Hot Topics

    Tags

    Calendar

    <February 2010>
    SunMonTueWedThuFriSat
    31123456
    78910111213
    14151617181920
    21222324252627
    28123456
    78910111213

    Archives

    February, 2010 (8)
    January, 2010 (13)
    December, 2009 (13)
    November, 2009 (7)
    October, 2009 (19)
    September, 2009 (11)
    August, 2009 (12)
    July, 2009 (21)
    June, 2009 (26)
    May, 2009 (16)
    April, 2009 (13)
    March, 2009 (17)
    February, 2009 (17)
    January, 2009 (18)
    December, 2008 (32)
    November, 2008 (17)
    October, 2008 (22)
    September, 2008 (16)
    August, 2008 (14)
    July, 2008 (25)
    June, 2008 (19)
    May, 2008 (17)
    April, 2008 (17)
    March, 2008 (26)
    February, 2008 (21)
    January, 2008 (28)
    December, 2007 (19)
    November, 2007 (17)
    October, 2007 (31)
    September, 2007 (39)
    August, 2007 (37)
    July, 2007 (43)
    June, 2007 (37)
    May, 2007 (32)
    April, 2007 (38)
    March, 2007 (29)
    February, 2007 (46)
    January, 2007 (31)
    December, 2006 (27)
    November, 2006 (31)
    October, 2006 (32)
    September, 2006 (39)
    August, 2006 (34)
    July, 2006 (40)
    June, 2006 (18)
    May, 2006 (31)
    April, 2006 (34)
    March, 2006 (30)
    February, 2006 (38)
    January, 2006 (44)
    December, 2005 (19)
    November, 2005 (34)
    October, 2005 (24)
    September, 2005 (37)
    August, 2005 (20)
    July, 2005 (24)
    June, 2005 (33)
    May, 2005 (16)
    April, 2005 (22)
    March, 2005 (34)
    February, 2005 (15)
    January, 2005 (37)
    December, 2004 (28)
    November, 2004 (30)
    October, 2004 (34)
    September, 2004 (22)
    August, 2004 (34)
    July, 2004 (18)
    June, 2004 (64)
    May, 2004 (49)
    April, 2004 (21)
    March, 2004 (29)
    February, 2004 (29)
    January, 2004 (36)
    December, 2003 (25)
    November, 2003 (24)
    October, 2003 (59)
    September, 2003 (42)
    August, 2003 (24)
    July, 2003 (44)
    June, 2003 (29)
    May, 2003 (21)
    April, 2003 (30)
    March, 2003 (27)
    February, 2003 (47)
    January, 2003 (50)
    December, 2002 (31)
    November, 2002 (38)
    October, 2002 (44)
    September, 2002 (15)
    May, 2002 (2)
    April, 2002 (4)

    Google Ads