Life, Surf, Code and everything in between

Twitter this, Twitter that...



So I recently started using Twitter (I'm RickStrahl in case you want to follow me). Late I know - Twitter's been around forever, but when I first heard and thought about Twitter the first thing that popped into my mind was "So what?". The concept of getting blasted with small disconnected messages detailing the minutiae of life of other people didn't sound terribly appealing to me. I'm still not sure that after the initial fad drops off whether that isn't what we all will be left with, but in the meantime I'm finding Twitter interesting to play and experiment with and maybe more importantly - finding it to be useful and helpful in a few situations.

The best description of what Twitter is and why it might be interesting beyond the initial impression of - "Why should I care what YOU do? Let's talk about me, damn it!" is this video:

http://www.commoncraft.com/Twitter

which puts Twitter into a non-geek, every day context, which is what it takes to 'sell' the idea of Twitter I think beyond the initial So what?  reaction.

The thing that finally made me try out Twitter and get (somewhat) hooked was a couple of weeks back at DevConnections when seemingly everybody around me was using Twitter to communicate. While at the conference with a bunch of other folks around physically, it's a great tool to get people together to do something, or have a general pow pow to find out what you might want to do with others. It's a great way to get motivated and keep up in an environment where the people twittering are actually around you. At the conference there were many moments where Twitter brought people together.

I figured once I get back home I'd probably be done with Twitter. But to my surprise I've been keeping up with it. There are a few folks I keep in contact with through Twitter now and a lot of the professionally related content has actually brought me some valuable links and other items of interest that I would otherwise probably wouldn't have found. Since I'm a single developer shop and live in sort of a bubble on a far away island (or a small town on the mainland when I'm back there) Twitter is  providing a little more sense of being a part of greater community to me.

Twitter is also a great way to throw out ideas and get feedback - quickly. In this context Twitter feels more like a micro blog with instant feedback. I've had several instances where I posted a request on some development issue I was stuck on and was inundated with a few suggestions that actually helped solve my problem in a few minutes. It's a great community tool at least for those that have a fair amount of followers.  Of course there is a key requirement for that aspect - you actually have to have people in your twitter follower's list that can potentially help you out or even care enough to follow your tweets.

Twitter fits a weird niche between IM and chat and blogs, but the nice thing about it is that its as interactive as you want it to be. Most other forms of communication require either two-way connections (ie. both sides need to commit to talking) or they are delayed communication (blogs with comments or message boards). Twitter is more like a public bulletin board where you subscribe to who you want to listen to and can blast out to whoever bothers to listen to you. In a way it's similar to blogging except that it's much shorter and way more abstract. Perfect for those with limited attention spans and wanting to perpetuate ADD <g>.

Surprisingly that works fairly well. The thing that's maybe enticing about Twitter is precisely that it's impersonal - the poster doesn't explicitly referencing a single person or even group usually. It frequently results in stream of consciousness messages that are out of context and can be intriguing or often spark interesting ideas in a way that no other medium really does.

And while there is a lot of stuff like - at the bus stop - waiting for the bus type messages, cooking dinner, heading to the john etc., once you've used Twitter for more than a few days you probably realize that that sort of thing is tedious - not just for others to read, but even for yourself to post. Instead I find myself spewing out occasional frustrations with what I'm working on, interesting finds I find while browsing around or reading something or some other quote of the day type thing that comes to mind at the moment. I see the same sort of thing from most other folks that I follow as well and as a Twitter consumer that's what I suspect most people are looking for. Not all of it is interesting of course, but there are frequent little gems in posts that make it worthwhile to glance at the tweet list from time to time.

What's not to like?

The problem with tools like this is that you just seem like a freaking ultra geek. Get out the thick glasses and pocket protectors and start poking away at your mobile phone everywhere you go <g>. I'd really hate to be one of those goobers constantly thumbing my cell phone everywhere I go (although it seems that's already happening anyway with CrackBerry email). Worse yet those folks that are doing while in the middle of something and then go - "Hang on while I Twitter". There's such a thing as too much information too... One thing that stuck out to me is we were at a dinner in Orlando with 8 speakers in the room and everybody was poking their phone every 10 minutes checking and entering new tweets. There's something rather lame about that, but yet it's also strangely addictive.

The other issues is that it's also somewhat difficult to have a 'real' conversation. Twitter really is the tool for the decimated attention span as you have to squeeze any thought or reaction into 140 characters (SMS size which is deliberate so you can use Twitter over SMS). This means lots of truncation and maybe even more so a lot of banal and disconnected content that has its head cut off and is then posted. It's also difficult to reply if a response requires more detail. Scattering content over multiple tweets is considered bad form for a reason: it's hard to read and follow in a reader.

Another problem seems to be the Twitter site itself. Twitter seems to be down an awful lot with messages sent simply failing or refreshes locking up. The timeout on the site is also pretty long so that requests can often hang for along time before failing. Not sure why, but logins especially seem to fail frequently and only several retries eventually allow access. Again this is most annoying when you're on your phone or other device when your connection is slow.

Twitter is also an exhibitionist's dream. Folks who love to show off what they're doing and let the world know get to blabber on all the time about minute details of - everything. At first I really was almost revulsed by this idea but in a lot of ways it's actually interesting once you start hitting the right people to follow on Twitter. Once you do, there can be some value to seeing what other like minded people are doing and how they are going through their daily routine along with the occasional inspirational gem.

There's a trade off I suppose between wasting time and getting something useful back. Which end you come out to depends on your particular usage scenario.

Tools

I've tried a bunch of Twitter clients and the one that works best for me seems to be twhirl. It's an open source client that looks nice and has a UI that's nice and usable. It's an Adobe Air app, which is an interesting choice, so it's fairly big, but it's a nice and clean app and it has just the right feature set IMHO. There are a number of other clients available including a few .NET clients although they are still pretty rough. The most interesting in that batch is probably Witty, which is a WPF Twitter client. It works well, but for some odd reason on my machine it doesn't show images <shrug>. It's also Open Source and provides Twitter API code which may be a good starting point if you want to use the Twitter API in your own applications.

Another interesting one: TwitterFox which is a small FireFox plugin that sits in your FF statusbar and gives easy access to tweets.

I also use Twinkle on my iPhone. Twinkle is a native iPhone app and it's much faster than the Web clients and looks a lot nicer too, but you need a jailbroken iPhone and use the Installer in order to install it. 

Stick with it?

I'm not sure whether Twitter will last with me. For the moment it's interesting and it's been helpful, but it also turns out to be a big time sink and a distraction. I already have enough trouble staying focused on work when I'm not under deadline, so Twitter is yet another distraction although in the grand scheme of things it maybe a helpful and productive distraction. Also, since I'm traveling in Switzerland and Europe most of this summer it's actually been a good tool to find a few folks here to ping on all things touristy.  I've turned on a few friends here and now I have a few local folks who can answer my touristy questions for decent restaurants in the neighborhood while I have to fend for myself in the evenings in Geneva <g>. A few good recommendations account for very little sleep in the last week... call that another plus point for Twitter <g>.

I think the one thing that is still missing with Twitter is location awareness. Being able to tell which of your twitter contacts are around you when you're away certainly would provide a lot of extra value. The iPhone Twinkle app tries to do something like this although it doesn't filter the list by contacts and just gives you everybody. BrightKite is another tool that also tries to match location awareness with Twitter, but it's a bit of a manual process at this time. Ultimately universal GPS tracking capabilities are what's needed to make this really work well and well that's a double-sided sword which brings up many 'Enemy of the State' connotations that feel a bit scary, especially if you voluntarily publish yourself (I guess the gov't already has the capability to track us pretty much completely as long as we carry our devices on us).

Anyway, I'd be curious to hear other people's experiences on their continued Twitter usage and 'alternate' use cases that keeps them using at beyond the initial "This is interesting" factor. Let's hear it...



Amazon Kindle on the Road



Wireless Access

So I broke down and got myself an Amazon Kindle Reader last week before I left for an extended trip to Europe. I've been reluctant to spend this kind of money ($399) on an electronic reader, but since I'll be spending a good deal of time on the road this year in Europe I thought it'd be a good idea to stock up on reading material before I hit the road and not have to deal with keeping stacks of paper books with me.

I read a lot of books - fiction, non-fiction and technical - and other than the technical books I really have no need for physical books on a shelf somewhere. In fact, more often than not, once or twice a year I dump all of my books on our local used book store and get nothing back from the original value anyway other than bestowing a bargain (or curse) on somebody else on my bad taste in books.

After using Kindle for the last week and a half extensively I can safely say that I'm happy with this purchase. The reading experience of the device is great and it works well in all of my reading scenarios. Since I've bought it I've probably put 15 hours of reading in and I have run the battery down to about half. That is though with the wireless off since I'm in Europe now where the Whispernet feature that connects the Kindle to the Internet and provides the instant online buying and downloading of books, doesn't work. Here I can still get books but I have to download to my machine and then sync to the device.

I did use the wireless feature though before I split and downloaded about 10 books. I was surprised to see that book downloads are pretty darn fast with most books completely downloaded after a few minutes. In fact, I was at Powell's at the Portland airport browsing around, found a couple of more books, dug out the Kindle and by the time I walked out had the books already downloaded. Kind of a bummer for Powells though (but then they're way overpriced anyway <g>).

From a feature perspective I love the device for the thing it was designed for reading and readability. Tonight, I missed a late bus today here in Geneva and was stuck at a bus stop for a half an hour in low light. Even though the device isn't backlit I was comfortably reading my book by the street light half a block down. The half an hour flew by and I almost missed my bus not paying attention. <g>

Although the device won't win any awards for product design it's functional and the screen just works great. I was reading for most of my 9 hour trans atlantic flight and there's none of the eye fatigue that comes when reading content on a laptop screen.  I read frequently in bed before going to sleep (if for nothing else than to get my mind of code before going to sleep) and while eating. Eating is probably the 'oddest' place for reading in general and Kindle actually works better than trying to get a book spine to behave. There's the issue of green spinach stains though... Hmmm...

You can search and bookmark easily and even annotate. There's internet access to WikiPidia and a few other select sites, but don't expect to get free WiFi out of the Amazon paid connection. Part of the high price is probably meant to defer Amazon's wireless bill for Whispernet that runs over Sprint's high speed cell network and allows for book browsing and the limited focused research Internet access.

Selection

Book selection is good but certainly not all inclusive. I was looking for some fairly new Sci Fi books, and found they weren't available while last releases by the same authors and publishers were. Seems odd - I suspect publishing to Kindle goes by the paper back rule - once paperback comes out it can also go to Kindle. Opportunity missed if books can sold electronically at near hardcover prices until then <shrug>

But most fiction and non-fiction books I was looking for were available with Kindle.

The technical book selection for Kindle is  pretty sparse though - it looks like only some of the big publishers like Sams, Addison Wesley etc. are putting out Kindle editions at the moment. But some of the more prominent 'design', 'architecture', patterns etc. books can be found for Kindle, which is actually a good fit. I picked up a new copy of Pragmatic Programmer which I'd been meaning to get anyway, but was bummed to find that Code Complete and Design Patterns (which are good to have around) weren't available. OTOH, I'm not sure how well I'd like to have highly technical books in this electronic format - I still prefer a physical book for reference books believe it or not (if for nothing else that they are separate from the computer screen which is already massively overloaded with simultaneously running applications). Actually I'm just checking back and see that a few of the big hits are available. I guess I wouldn't mind having a portable copy of Stephen Walther's ASP.NET 3.5 book or Adam Nathan's WPF book with me at all times and those can actually be had for Kindle, but looking at some of the samples of Stephen's book it's not as user friendly as I would hope. Code listings split badly and in the case of Adam's WPF book you lose all the color and good flow that that book sports. This one page electronic format is just not a good match for books that contain lots of code I think. I still prefer a printed book for real reference work I guess (yes even over purely online content which is always so damn scattered).

But for pure printed text - the reader works as well as a printed book.

Talk of the Town - whatever!

While I was flying the Kindle also got a lot more attention than I liked - people would walk by the aisle and stop and  constantly ask what it is, how it works etc. After a while I got tired of that shit and put on my headphones and appeared to be really immersed in my reading. Can I never get any piece and quiet? The book reader also came up in a few conversations I've had here and several very unlikely folks got really excited about the device and its possibilities including one real grouch <g>. People who read a lot are immediately taken by the idea of having much of their reading material at their finger tips.

The device is not pretty, it has hard edges and the buttons for pages while adequate are too big and to easily clicked or bumped resulting in double page turns. But it's quick to get used to. Overall I'd say the device is practical, but certainly not flashy both in external design or the screen UI. That's probably a good thing - it helps  from getting too distracted and keeps me focused on its primary task: reading a goddamn book instead of playing video games.

Remember it's an Amazon Sales Machine

So the Kindle is a good deal for me - I have one thin device I can carry around with me and carry many books which is great for travel. But it's expensive. If it wasn't for my extended absence I probably wouldn't have bought this thing. $400 is not cheap for what amounts to a big Amazon sales tool. The device is locked to Amazon, so everything you get for it has to be bought through Amazon. This means no used books discounts or even buying books from other sellers at Amazon. And even though there's no physical product prices are only slightly less than full shipped books. Given that Amazon ships most physical for free (if you're willing to wait a little) it's kind of a bummer that there's not more of a discount for Kindle purchases either. Kindle is clearly targeting the geek and well to do set with this device. Surely both publishers and Amazon are laughing all the way to the bank for each Kindle book sold.

Maybe someday there will be an open and actually widely used e-book format that doesn't suck and has enough support from publishers, but at this time the Amazon Kindle seems to have that market cornered. While other solutions exist they are either infringing copyright laws or are relying on minimal support from a few independent publishers here or there. Things in this space will likely change in the future - Amazon has proven that people are willing to pay for the hardware to get electronic book content, but it's hard to say which way this will go.

Still I'm happy with the device if for nothing else than having one thing to schlep around instead of a 5 books as I often did  when gone for longer stretches of time...



ASP.NET Connections Slides and Samples Posted



I've posted my session slides and samples from my ASP.NET Connections sessions last week in Orlando. I did three sessions at the conference and you can check out the slides and samples here. All three sessions had extensive samples (and I didn't even get to them all) so if you attended my sessions be sure to take a look at the samples as there's lots of extra stuff that didn't get covered in sessions.

The files posted here are more current than the original code and slides provided at the conference and the immediate updates I posted. I spent a little more time cleaning up a few dependencies, hopefully making it a little easier to get the samples running. Please be sure to read the _readme.htm files (or the Configuration links on the default page) in each of the projects, as they include important information about set up to run the samples and setting up the databases.

Here are the links and summaries of each of the sessions:

Ajax Alternatives: Using jQuery with ASP.NET

This was by far the most fun session for me, partly because I've been working with jQuery so much in recent months, but also because it was a really interactive session. I started this session with a basic ASP.NET page and went through the motions of adding jQuery functionality to the page. In 10 minutes of hands on building up of the page I went through a wide cross section of jQuery from selector syntax to document manipulation, to special effects, using plug-ins and  creating an plugin. From there the session has samples that demonstrate basic Page based AJAX operation - Ajax without any sort of framework on the backend, followed by examples and some generic helper code that lets you use WCF 3.5's Ajax support with jQuery. Samples include demonstrations of HTML loading, using server based HTML templating (ie. poor man's UpdatePanel like behavior) and raw data results with JSON. The WCF examples provide mroe data driven examples which demonstrates the same examples, but using purely client side manipulation of the DOM with data from the server. The two examples use a stock quote server and portfolio display that is rendered and updated client side including a nice interactive display. I also showed a cool photo album application that shows off a few useful plug ins including sortables and an inplace editing component I created for doing real time and in place  data updates using the DOM as the data storage mechanism. Finally there is an example of a jQuery component (jquery.ui's DatePicker control) wrapped as an ASP.NET control for easier usage in the ASP.NET environment.

The photo album application is running on my site here:

http://www.west-wind.com/rick/photoalbum/

and a demo that allows access to the admin functions the demonstrate the more interesting features can be accessed at this particular URL:

http://www.west-wind.com/rick/photoalbum/demoMaui2006/Default.aspx

(this demo likely will get trashed by vandals since it allows user input and I'll probably pull it after a few days or so, so check it out now while it's there)

You can download this session from:

http://www.west-wind.com/files/conferences/jquery.zip

 

WCF 3.5 JSON and REST Services

This session's focus is on the new WCF 3.5 HTTP features that provide support for REST principles and AJAX support. WCF 3.5's AJAX support has been made nearly as easy and comprehensive as ASMX functionality and there are many options of how data can be accessed over HTTP now with official protocol support for the webHttpBinding. This session starts of with examples of pure REST URLS and demonstrates features like URL templating, different response formats (wrapped, bare, XML, Json) as well as the various different options for serving in this fashion. THere are also examples of serving up raw data such as images or HTML content out of the REST based API. The remainder of the session focuses on AJAX functionality and explores different ways that WCF services can be called. There's a comprehensive Stock Service example that shows simple stock quote retrieval, a more complex portfolio manager and streaming stock history graphs to the browsers. Examples are provided for using Microsoft ASP.NET Ajax as a client as well as jQuery as a client in order to avoid loading of Microsoft Client Libraries.

You can download this session from:

http://www.west-wind.com/files/conferences/wcfRest.zip

 

Building a LINQ to SQL Business Layer for ASP.NET Applications

Focus of this session is on a LINQ to SQL Business object framework that wraps LINQ to SQLs data access model. LINQ to SQL - although completely object based, is still little more than a sophisticated data access layer and so a business object layer is still needed to abstract business logic and provide common functionality that every business related entity requires. THe business layer provides a few high level abstractions to the CRUD layer as well as a host of low level features that allow better control for low level data access in case LINQ to SQL queries are ill suited for queries and operations that cannot be performed with LINQ to SQL at all. This session includes a simple but comprehensive Time and Billing example application that demonstrates many aspects of working with LINQ to SQL using this business layer.

This is an update to previous versions of the LINQ to SQL Business layer I've put out. Enhancements in this version include removal of the requirement for tables to have timestamp fields, several enhancements to dynamic expression usage internally and a few small bug fixes.

You can download this session from:

http://www.west-wind.com/files/conferences/LinqtoSqlBusiness.zip

 

Hope you find some of this stuff useful.



Reusing old Laptop SATA Drives via USB



As I'm about to head off to the airport for an extended 3 month travel gig in Europe, I'm doing my last minute backups to DVD and hard backups onto my desktop backup drive.

I am rummaging through all of my stuff in my travel bag and  I just remembered that I always carry a spare SATA drive with me - just in case something blows up so I at least don't have to run to the store to get a new drive (and yes this always seems to happen at the most inopportune time for me!). This is an old drive, bought to test some OS or VS beta long ago. The data on the drive is pretty stale (just checked it's from early 2007 - pre Vista even) so the content is not important.

But I figured I can put that drive to use as a backup device. So I got out my trusty SATA to USB interface cables and did a fairly full back up right onto this spare drive. USB to SATA cables are readily available these days and the make it easy to reuse an old drive.

There are tons of cables available that do this but I use this one and it works well for me with or without power:

SataDrive

There are a variety of these cable adapters available and you might want to read reviews on all of them to find the right one. The CoolMax I have seems to have a few bad reviews at Amazon, but it's been working fine for me for a few years with several drives I've attached to it, although I have a much older version of it and one that came with an optional power adapter. One thing to look for is a package that also includes  a power adapter.  In the past I've had problems with only the USB cable powering even the laptop drive. For desktop drives the power is definitely needed in most cases (depending on the power output of the USB bus). The cable above fits SATA, and standard IDE drives which is a bonus if you need to work on an old drive. On my current machine the power adapter is not necessary with the laptop drive attached which is nice - only need the one small USB cable with the adapter at the end.

Beyond travel these converters are useful if you run into problems with a drive. I've used this to pull data of several other people's drives once it's come out of their machines where the drives wouldn't work usually due to some boot corruption.

For me and for travel what's nice about this setup is - especially if it works without power as it does on my laptop - that you can get faster and smaller raw drives than the typical pocket USB drives you buy. Pocket usb drives tend to be slower 5400rpm drives while most of us have 7200rpm drives in our machines. This certainly makes some performance difference especially for doing backups. And because it's a raw drive you can plug it into your machine should the primary drive take a dump so it is real spare.

I probably wouldn't recommend this approach for a second dedicated drive that you use all the time because a raw drive is - well - a raw drive sitting on your desk <g>. But for an occasional backup device,when already carrying around a spare hard disk, this great. 1 small cable to carry in addition to the drive is a small price to pay.



jQuery.ui Sortable



Sorting of a list of items is a common task in any user interface. Personally I've been wanting to add sorting to a number of applications for ages, and some time ago I started down the path of building something of my own to handle this task on the client side with JavaScript. Ok, I failed - I got most of it almost working but there were always  a few things that just didn't work quite right. I've also tried a few other components that do sorting and most are quirky or don't work well cross browser.

[updated 4.28.2008 - added code to show how to notify server of sort updates]

jQuery's Sortable is a cool client side jQuery plugin that is part of the jQuery.ui plug in library that works well, looks very nice and is fairly self contained (2 scripts beyond jQuery). It lets  lets you create sortable unordered/ordered lists or a plain group of contained DIV tags.

It's extremely easy to use in client code by simply pointing at the list and a few options to make the list sortable. Items can be dragged around and sorted and the items appear transparent when dragging (by default). It's also fairly customizable to let you control how sorting works and how the items are represented while dragging.

One place I used Sortable is in my photo album where I allow client side sorting of the images that are displayed. In my app the administrator can rearrange images in real time, make changes to captions and then when done save them back via an Ajax callback to the ASP.NET server app.

Here's what sorting operations look like (the real deal is a lot smoother - this is captured as an animated gif with CamTasia):

Sortable

Items slide around as they are sorted and use a nice sliding into place effect when dragging is complete, or slide back into their original position if moved out of the main area. The plug in also handles scrolling the browser when bumping up against edges. The really cool thing about Sortable though is how easy it is to use: It's an extender, so all you do is point it at the result of a jQuery selector that is a list and add a few simple and optional settings and that's it.

To use Sortables you'll need jQuery plus a few of the jQuery.ui scripts:

<script src="/photoalbum/scripts/jquery.js" type="text/javascript"></script>
<script src="/photoalbum/scripts/ui.base.js" type="text/javascript"></script>
<script src="/photoalbum/scripts/ui.sortable.js" type="text/javascript"></script>

All the code required to make the above list sortable is:

$("#ulThumbnailList").sortable(
    {  opacity: 0.7, 
       revert: true, 
       scroll: true , 
       handle: $(".imagecontainer").add(".imagecontainer a img") 
    });  

The settings parameter object is optional but allows configuration of the behavior for the sorting/dragging operation. Here I optionally apply opacity, and tell the sort to revert to original position on aborting and scrolling the browser window when bumping against the edges. In addition, I supply a selector to use as a drag handle - the item is dragged by grabbing the image container which is a DIV that wraps the image. The above control supports in-place text editing and selecting the entire control makes it hard to get the text editing to 'take' because the control will try to drag fairly quickly.

Notice the handle selector: You can apply a selector for the area that acts as the drag handle - ie. where the user can drag the item. Here I want it to be a DIV tag that wraps the image. Note that I also select the image itself - the drag handle is very explicit about which element is used so I make sure that both the container and the contained image can initiate drag operations. (this is a change from the previous rev I'd worked with).

Keep in mind that Sortable doesn't work with tables, but HTML lists or a set of Div tags, so if you need a table like layout you need to think of other ways to arrange the layout. You can use a Repeater or ListView in ASP.NET to create this sort of layout easily. The above HTML uses contained plain old <li> tags with a fixed width and float:left to provide the 'column' based layout of the photos.

The trickier part - for the photo list above at least though - is getting the CSS right.  The above is rendered as an unordered list with float:left items which gives the effect of a table. Note that Sortable can sort elements in this way and does the right thing when sliding elements out of the way as the dragged item moves through the table - it's a very cool visual as well as practical effect.

The unordered list HTML above is rendered like this:

<ul id='ulThumbnailList'>
    <li id='f0db40f3' class='photolistitem'>
    <div class='imagecontainer'>
    <a href="javascript:ShowImagePopup('f0db40f3');">
        <img src='tb_sweatshop.jpg' class='thumbnailimage' id='f0db40f3Img' title='sweatshop.jpg' />
    </a>
    </div>
    <div id='f0db40f3Notes'>Team programming
    </div> <div class='deletethumbnail'>X</div>
    </li>
 
    <li id='64ac6f8c' class='photolistitem'>
    <div class='imagecontainer'>
    <a href="javascript:ShowImagePopup('64ac6f8c');">
        <img src='tb_whalewhispers.jpg' class='thumbnailimage' id='64ac6f8cImg' title='whalewhispers.jpg' />
    </a>
    </div>
    <div id='64ac6f8cNotes'>Can you hear me now? Really now?
    </div> <div class='deletethumbnail'>X</div>
    </li>
    ...
</ul>

with the photolistitem CSS class defined like this:

.photolistitem
{
    position: relative;
    display: block;
    float: left;    
    list-style-type: none;
    height: 220px;    
    width: 170px;    
    padding: 10px;
    border: solid 1px khaki;
    margin: 12px;
    background: steelblue;
    text-align: center;
}

Note the float:left and the fixed width and height which is a requirement if you want to use the unordered list as a table like display. Items need to be the same size or else the items ends up not aligning properly...

With this layout in place all that needs to happen is to apply the .Sortable() call against the top level <ul> tag and the plug in does the rest, nice UI effects and all.

Saving Sorted Data

Because Sortable is a client side component sort changes are not automatically visible on the server. This means you'll need to somehow let the server know of the sort order update and push the data to the server via an AJAX callback. In the example above I'm using jQuery to reselect all the sorted items (.photolistitem class) and then reading the content from the controls into an array of objects that contains the Id (a hash) and the caption. The array is then sent back to the server via an AJAX callback.

Here's what the JavaScript code for the save operation looks like:

function SavePhotos()
{
    var items = $(".photolistitem");
    var photos = [];
 
    for(var x=0; x<items.length; x++)
    {
        var photo = {}
        photo.id = items[x].id;                
        photo.notes = textFromHtml( $(items[x]).find("div[id$=Notes]").html(),true);                
        photos.push(photo);
    }
 
    var photoList = {};
    photoList.Photos = photos;
    photoList.Title = $("#lblTitle").text();    
    photoList.Description = textFromHtml( $("#lblDescription").html(),true);
 
    // *** Page JSON wrapper    
    httpJson("SaveList",photoList,
            function(result) { showMessage("Changes have been saved...",msgTimeout); },
            pageError);
 
    return photos;
}

On the server side a CallbackMethod (part of West Wind Ajax Toolkit, but you can point this at WCF REST or ASMX Ajax service) the data gets picked up like this:

[CallbackMethod]
public string SaveList(PhotoList photoList)
{
    // *** Write out sort order in increments of 10
    // *** Highest sort order goes to the top
    int sortCount = 10 * this.Album.Photos.Count;
 
    Album.AlbumName = photoList.Title.Trim();
    Album.AlbumDescription = photoList.Description.Trim();
 
    foreach (PhotoListItem changedPhoto in photoList.Photos)
    {
        Photo photo = Album.Photos.GetPhotoByHashCode(changedPhoto.Id);
        if (photo == null)
            continue;
 
        photo.Notes = changedPhoto.Notes.Trim(' ','\r','\n');
        photo.Updated = DateTime.Now;
        photo.SortOrder = sortCount;
 
        sortCount -= 10;
    }
 
    // *** Re-sort the list to update the actual object layout
    this.Album.Sort();
 
    // *** Save the album to disk 
    this.Album.SaveAlbum(this.ConfigFile);
 
    return "Ok";
}

The process is pretty straight forward. If your lists are large and push back lots of data you'd probably also implement some sort of IsDirty flag that determines whether an item has changed so only those items changed are sent to the server. However for sorting you definitely have to send all the items/ids so the server can properly reassemble the items and sort accordingly. It isn't automatic, but it ain't rocket science either.

jQuery UI - Wait for Version 1.5 or use the 1.5 Beta 2 now

When jQuery.ui 1.0 was first released I was pretty excited to see that there'd be a somewhat uniform UI library built ontop of jQuery. Unfortunately Version 1.0 was a really bad release with many of the components not even working out of the box. There were lots of issues with rendering and most of the components worked haphazardly with no consistency between the various control APIs. Most of the controls are based on third party plug-ins that have been drafted into the jQuery.ui API and in version 1.0 that really showed by way of the differing API interfaces.

Version 1.5 - which is not released yet, but available in beta form - fixes these issues with a complete overhaul of the jQuery.ui API. I've used quite a few of the 1.5b components and had no major problems. Many of the controls also have had a big face lift with much nicer UI and effects applied. Using the beta however requires that you also use an interim version of jQuery (1.2.4a). Prior to this release I'd been pulling jQuery out of the SVN repository, patching it together from the base source files, but with the beta 2 release there's now a synched version of jQuery included. If you want to use the beta you need to use this version or a newer one out of the SVN repository.

The current release of jQuery.ui and jQuery work well, but if you're squeamish about beta releases you might want to wait a bit for release.

Online Sample:

http://www.west-wind.com/rick/photoalbum/demoMaui2006/Default.aspx

Click on the Configuration link for the admin portion that includes the sortable code and component.



Customized Loading... Images



Just ran into a cool site that provides a variety of images that show busy status, which is more and more common for Ajax applications. The app lives here:

 http://www.ajaxload.info/

This isn't the first site that collects these various Loading... style images, but what nice about this one is that you can dynamically build the images by specifying colors and background colors and transparency which means you can create images that look good on any kind of background without color bleeding. It looks like this tool rebuilds the images entirely so transparent images look clean no matter what content you stick it ontop of.

Very cool idea. I've already used a few of these to retrofit existing animated gifs and ended up with smaller gifs to boot.

Bookmarked!



Variable Scoping in Anonymous Delegates in C#



Every once in a while when I write code that deals with Anonymous Delegates, I still kinda freak out when it comes to the behavior of closures and the variable scoping that goes along with it. For example, the following code uses a List<T>.Find() Predicate to search for items in the list and requires that a dynamic value is compared to:

public void AddScript(ScriptItem script)
{
    ScriptItem match = null;
 
    // *** Grab just the path
    if (!string.IsNullOrEmpty(script.Src))
    {
        script.FileId = Path.GetFileName(script.Src).ToLower();
 
        match = this.InternalScripts.Find(
            delegate(ScriptItem item)
            {
               ScriptRenderModes mode = this.RenderMode;  // demonstrate this pointer
               return (item.FileId == script.FileId);
            });
    }
 
    if (match == null)                
        this.InternalScripts.Add(script);
    else
        match = script;
} 

The Predicate<T> signature requires a boolean return value and an input parameter of any type (the <T>). The input parameter will be the item iterated over and is of the same time as the list. But the question then becomes: How do you compare that object against a dynamic value?

The freaky thing is the script variable in the AddScript function. It's passed in as a parameter to the outer function so it's effectively a local variable, but yet it is fully visible in the anonymous delegate's own private body. The delegate is in effect just another function, but what's different here is that the anonymous delegate inherits the variable scope of the containing method that is calling it.

To contrast if I were to call an explicit method to handle the Find filter:

match = this.InternalScripts.Find(Exists(script2));

and then create a method that matches this signature I can't access the script variable so this fails to compile:

bool Exists(ScriptItem script2)
{
    return (script2.FileId == script.FileId);   // FAILS obviously due to scoping
}

because script isn't available.

Behind the scenes the C# compiler creates a dynamic delegate class that includes fields for each of the local variables that need to be in scope, so when script  is referenced in the delegate's body it's really referencing the equivalent of this.script. The compiler fixes up the code so that the script property is set when before the method call is made so the delegate code 'appears' to be referencing a variable. If the this pointer is referenced in the delegate code, the compiler also creates a field that holds a reference to the calling class and then fixes up any calls to this to this member instead.

Here's what the compiler generated class looks like:

[CompilerGenerated]
private sealed class <>c__DisplayClass2
{
    // Fields
    public wwScriptContainer <>4__this;
    public ScriptItem script;
 
    // Methods
    public <>c__DisplayClass2();
    public bool <AddScript>b__0(ScriptItem item);
}

and the actual delegate method on the class:

public bool <AddScript>b__0(ScriptItem item)
{
    ScriptRenderModes mode = this.<>4__this.RenderMode;  
    return (this.script.Src == item.Src);
}

Notice that the this pointer is actually referencing a property that has the parent class assigned to it. It's all compiler sugar as well as Visual Studio's Intellisense that gives you the impression that you are in fact inside of closure method. Incidentally one thing that DOESN'T work is checking the this. pointer in the debugger while you are in the delegate code. This cannot be accessed in the debugger inside of the delegate code which would presumably cause some confusion of whether this should point at the delegate (and reveal the compiler magic) or the calling container's class.

Regardless of sleight of hand, the concept of closures is very cool and highly useful. I use it all the time in JavaScript, but damn, it still feels unnatural to me in C#. There's some debate over whether C# anonymous delegates are true lexical closures (take a look at this post and especially the comments), but for most situations that require variable scoping to be passed down to delegates for all intents and purpose the behavior is like that of a typical closure that inherits the calling context's variable scope.

This concept of anonymous delegates and closure scoping is EXACTLY what makes Lambda Expressions work in C# 3.0. Lambdas are just glorified Anonymous Delegates. In fact, the Find() predicate above can also be expressed as a Lambda expression:

match = this.InternalScripts.Find( item => item.FileId == script.FileId );

It's funny sometimes how you end up using some functionality without really understanding what goes on underneath the covers and one day you're using something completely unrelated (in this case JavaScript closures) that make everything click and fall into place. A little spelunking with Reflector later and you feel a heck of a lot more comfortable with several language features...



Visual Studio's JavaScript Editor Really needs a Function/Class Viewer!



During the last week of talking to quite a few Web developers at DevConnections who are doing JavaScript development and during my jQuery and WCF REST talks, a recurring question kept popping up. Why isn't there some way to get a list of functions in the Visual Studio JavaScript editor like in the other languages?

This is a fairly vital feature of a code editor, especially once you start writing a lot more client centric applications that have a fair bit of callback code that is maintained on the client. In fact, the question came up because I was scrolling rapidly over large amounts of code in several demos - or using trusty old CTRL-F - to jump to a given function in the code. In a demo that's annoying as heck, but it's also a problem during day to day development when you're working with more than a few JavaScript functions in a source .js file; client side code accumulates fast, even if you do little more than handle a few client side callbacks.

C# and VB both have class and member drop downs at the top of the code editor:

CSharpFunctionDropDown

There are also document outlines for the HTML and CSS editors, class editors for C# and VB,  but unfortunately there's nothing along these lines available in the Visual Studio JavaScript editor.

I've begged for this feature for a while and it's always been declined as a low priority issue, which I find surprising because to me at least it's pretty high on the productivity list.

I realize that JavaScript parsing and displaying reliable class information is a pretty difficult process. JavaScript's Function based Closure/Class model makes it pretty difficult to figure out exactly what constitutes a function and what constitutes a class. The same issue also applies to the JavaScript Intellisense in Visual Studio which - although pretty good - also misses quite a few scenarios for finding embedded functions and classes and so often provides incomplete information.

There are alternatives though. I've been using Aptana off and on and it does support function and class outlining:

Aptana

As nice as the class view is in Aptana, it's also not perfect. It too misses things. For example, pointing Aptana at the jQuery library also doesn't capture most of the jQuery wrapped set handling functions. As a developer who lives most of the day in Visual Studio I also find the way that Intellisense and the editor in general behaves is a little foreign and I would much prefer to work in VS than another huge external environment.

Still when I'm working on large libraries like the code above or on complex pages that have more than 10 functions on them I tend to switch to using Aptana, simply because I do a lot of jumping back and forth that is much easier to do in this environment than Visual Studio.

So, am I the only one who doesn't see this as a low priority scenario for JavaScript support in Visual Studio? Seems to me this is a vital feature that is incredibly useful for anything but simple JavaScript development.

What do you think?



jQuery AJAX calls to a WCF REST Service



Since I've posted a few jQuery posts recently I've gotten a bunch of feedback to have more content on using jQuery in Ajax scenarios and showing some examples on how to use jQuery to cut out ASP.NET Ajax. In this post I'll show how you can use jQuery to call a WCF REST service without requiring the ASP.NET AJAX ScriptManager and the client scripts that it loads by default. Note although I haven't tried it recently the same approach should also work with ASMX style services.

WCF 3.5 includes REST functionality and one of the features of the new WCF webHttp binding is to return results in a variety of ways that are URL accessible. WCF has always supported plain URL HTTP access, but it's not been real formal and had somewhat limited functionality as parameters had to be encodable as query string parameters. With the webHttp binding there's now an official WCF protocol geared towards providing ASP.NET AJAX JSON compatibility (using WebScript behavior) as well of a slightly cleaner raw JSON implementation (basic webHttp binding).

You can return XML (default), JSON or raw data from WCF REST services. Regardless of content type, natively WCF always wants to return content in a 'wrapped' format which means that both inbound parameters and outbound results are wrapped into an object.

Let's take a look at the message format for a  REST JSON service method.

[ServiceContract(Name="StockService",Namespace="JsonStockService")]    
public interface IJsonStockService
{
    [OperationContract]          
    [WebInvoke(Method="POST",
               BodyStyle=WebMessageBodyStyle.Wrapped,
               ResponseFormat=WebMessageFormat.Json
    )]
    StockQuote GetStockQuote(string symbol);

..

The input message on the wire looks like this:

{"symbol":"MSFT"}

The response looks like this:

{"GetStockQuoteResult":
        {"Company":"MICROSOFT CP",
        "LastPrice":30.00,
        "LastQuoteTime":
        "\/Date(1208559600000-0700)\/",
        "LastQuoteTimeString":"Apr 18, 4:00PM",
        "NetChange":0.78,
        "OpenPrice":29.99,
        "Symbol":"MSFT"}
}

Notice that in both cases an object is used. For the inbound data all parameters are wrapped into an object and rather than just passing the value, the name of the parameter becomes a property in the JSON object map that gets sent to the server. This is actually quite useful - if you're just sending a raw JSON structure you could only pass a single parameter to the server - and that option is also available via the Web BodyStyle=WebMessageBodyStyle.Bare option on the service method.

The outbound result set is also wrapped into an object which is a lot less useful. This is a hold over from WCF which wraps all responses into a message result object, which usually makes sense in order to support multiple result values (ie. out parameters etc.). In a Web scenario however this doesn't really buy you much. Nevertheless if you want to pass multiple parameters to the server you have to use this wrapped format along with the result value.

Calling with jQuery

If you're using jQuery and you'd like to call a WCF REST service it's actually quite easy either with bare or wrapped messages. Bare messages are easier to work with since they skip the wrapping shown above, but as I mentioned you're limited to a single input parameter. So if your service has any complexity you'll likely want to use wrapped messages.

You can opt to either call services using the ASP.NET Ajax logic (WebScriptService behavior) or using the raw service functionality which is shown above.

To call these methods with jQuery is fairly straight forward in concept - jQuery includes both low level and highlevel methods that can call a URL and return JSON data. The two methods available are $.getJSON() which automatically parses result JSON data and $.ajax(), which is a lower level function that has many options for making remote calls and returning data.

getJSON() is useful for simple scenarios where the server returns JSON, but it doesn't allow you to pass JSON data TO the server. The only way to send data to the server with getJSON is via query string or POST data that is sent as standard POST key/value pairs. In all but the simplest scenarios getJSON() is not all that useful.

The lower level $.ajax method is more flexible, but even so it still lacks the capability to pass JSON data TO the server. So little extra work and some external JSON support is required to create JSON output on the client as well as dealing with Microsoft Ajax's date formatting.

Personally I prefer to use a wrapper method for making JSON calls to the server to encapsulate this functionality. Note although this method seems somewhat lengthy it deals with a few important issues that you need to take care of when calling WCF REST Services:

// *** Service Calling Proxy Class
function serviceProxy(serviceUrl)
{
    var _I = this;
    this.serviceUrl = serviceUrl;
 
    // *** Call a wrapped object
    this.invoke = function(method,data,callback,error,bare)
    {
        // *** Convert input data into JSON - REQUIRES Json2.js
        var json = JSON2.stringify(data); 
 
        // *** The service endpoint URL        
        var url = _I.serviceUrl + method;
 
        $.ajax( { 
                    url: url,
                    data: json,
                    type: "POST",
                    processData: false,
                    contentType: "application/json",
                    timeout: 10000,
                    dataType: "text"// not "json" we'll parse
                    success: 
                    function(res) 
                    {                                    
                        if (!callback) return;
 
                        // *** Use json library so we can fix up MS AJAX dates
                        var result = JSON2.parse(res);
 
                        // *** Bare message IS result
                        if (bare)
                        { callback(result); return; }
 
                        // *** Wrapped message contains top level object node
                        // *** strip it off
                        for(var property in result)
                        {
                            callback( result[property] );
                            break;
                        }                    
                    },
                    error:  function(xhr) {
                        if (!error) return;
                        if (xhr.responseText)
                        {
                            var err = JSON2.parse(xhr.responseText);
                            if (err)
                                error(err); 
                            else    
                                error( { Message: "Unknown server error." })
                        }
                        return;
                    }
                });   
    }
}
// *** Create a static instance
var Proxy = new serviceProxy("JsonStockService.svc/");

WCF services are called by their URL plus the methodname appended in the URL's extra path, so here:

JsonStockService.svc/GetStockQuote

is the URI that determines the service and method that is to be called on it.

The code above uses the core jQuery $.ajax() function which is the 'low level' mechanism for specifying various options. Above I'm telling it to accept raw string input (in JSON format), convert the response from JSON into an object by evaling the result, as well as specifying the content type and timeout. Finally a callback handler and error callback are specified.

Note that I override the success handler here to factor out the wrapped response object so that the value received in the callback handler is really only the result and not the wrapped result object. More on this in a second.

The call for the above StockQuote(symbol) call looks like this (including some app specific code that uses the result data):

var symbol = $("#txtSymbol").val();            
Proxy.invoke("GetStockQuote",{ symbol: symbol },
    function (result)
    {   
        //var result = serviceResponse.GetStockQuoteResult;
 
        $("#StockName").text( result.Company + " (" + result.Symbol + ")" ) ;
        $("#LastPrice").text(result.LastPrice.toFixed(2));
        $("#OpenPrice").text(result.OpenPrice.toFixed(2));
        $("#QuoteTime").text(result.LastQuoteTimeString); 
        $("#NetChange").text(result.NetChange.toFixed(2));   
 
        // *** if hidden make visible
        var sr = $("#divStockQuoteResult:hidden").slideDown("slow");
 
        // *** Also graph it
        var stocks = [];
        stocks.push(result.Symbol);
        var url = GetStockGraphUrl(stocks,result.Company,350,150,2);                
        $("#imgStockQuoteGraph").attr("src",url);
    },
    onPageError);

Parameters are passed in as { parm1: "value1", parm2: 120.00 } etc. - you do have to know the parameter names as parameters are matched by name not position.

The result is returned to the inline callback function in the code above and that code assigns the StockQuote data into the document. Notice that the result returned to the callback function is actually NOT a wrapped object. The top level object has been stripped off  so the wrapper is not there anymore.

If you look at the the ajaxJSON function, you can see that it  looks for the first result property in the actual object that WCF returns and uses IT to call the callback function instead - so it's indirect routing. This saves you from the one line of code commented out above and having to know exactly what that Result message name is ( WCF uses <methodName>Result). Not that one line of code would kill you, but it's definitely cleaner and more portable.

The same approach should also work with ASMX style services BTW which uses the same messaging format.

JSON encoding

Note that the ajaxJSON function requires JSON encoding. jQuery doesn't have any native JSON encoding functionality (which seems a big omission, but was probably done to preserve the small footprint). However there are a number of JSON implementations available. Above I'm using the JSON2.js file from Douglas Crockford to serialize the parameter object map into JSON.

There's another wrinkle though: Date formatting. Take another look at the stock quote returned from WCF:

{"GetStockQuoteResult":
        {"Company":"MICROSOFT CP",
        "LastPrice":30.00,
        "LastQuoteTime":
        "\/Date(1208559600000-0700)\/",
        "LastQuoteTimeString":"Apr 18, 4:00PM",
        "NetChange":0.78,
        "OpenPrice":29.99,
        "Symbol":"MSFT"}
}

There's no JavaScript date literal and Microsoft engineered a custom date format that is essentially a marked up string. The format is a string that's encoded and contains the standard new Date(milliseconds since 1970) value. But the actual type of the date value in JSON is a string. If you use standard JSON converters the value will be returned as a string exactly as you see it above. I've talked about the date issues, and hacking existing JSON implementations before. I've modified Crockford's JSON2.JS to support the Microsoft date format so it properly encodes in and outbound data. You can download the hacked JSON2_MsDates.zip if you're interested. You can look at the code to see the modifications that were required, which essentially amounts to pre filtering parsed data before evaling on the .toJSON end and dropping the Data format that Date.prototype.toJSON() produces and instead creating a string in the required format above when doing object encoding.

Bare Messages

If you want a cleaner message format and you're content with single parameter inputs to functions then the WebMessageBodyStyle.Bare can work for you. Bare gives you a single JSON parameter you can pass that is automatically mapped to the first and only parameter of a method. You can't use Bare with any service methods (other than GET input) that include more than one parameter - the service will throw an exception when you access any method (beware: it's a RUNTIME error!).

Bare messages are easier to work with but they are limited because of the single parameter. You can use a single parameter on the server and make that input a complex type like an array to simulate multiple parameters. Using input objects or arrays can work for this. While this works realize that WCF requires an exact type match so any input 'wrapper' types you create yourself have to be mappable to a .NET type.

My first instinct with WCF's web bindings was always to use Bare, but ultimately the wrapped format provides more flexibility even if it is a little uglier on the wire. For AJAX services wrapped seems to make more sense.

Ideally, I would have preferred even more control - wrapped input messages and bare output messages, but I guess you can't have everything <g>...

Other Input Alternatives

Passing JSON messages is one thing you can do - the other option is to pass raw POST variables, which is something that can be done natively with jQuery without requiring a JSON encoder. Basically jQuery allows you to specify data as an object map, and it can turn the object into regular encoded POST parameters.

[OperationContract]          
[WebInvoke(Method="POST",
           BodyStyle=WebMessageBodyStyle.Bare,
           ResponseFormat=WebMessageFormat.Json
 )]
StockQuote GetStockQuote(string symbol);

You'd also need to mark your class:

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class JsonStockService : StockServiceBase

and enable ASP.NET compatibility in web.config (see my WCF REST Configuration Post for details)

If you prefer the simplified logic and you can use POST input data (which works well if you rather post back to a handler or the same ASPX page) you can get away with the following:

function ajaxJsonPost(method,data,callback,error)
{
    var url = "JsonStockService.svc/" + method;
    $.ajax( { 
                url: url,
                data: data,
                type: "POST",
                processData: true,
                contentType: "application/json",
                timeout: 10000,
                dataType: "json",
                success: callback,
                error: error
            });   
}

When you send data like this you can actually change the message format to Bare and get just a raw object response. jQuery can either except a raw POST string for the data parameter or an object whose properties and values are turned into POST key value pairs.

If you want to use POST behavior with WCF though,  you need to enable ASPNET Compatibility on the REST service - otherwise the HttpContext.Current.Request is not available since WCF REST by default is trying to be host agnostic.  For more information on how to configure WCF REST services check my previous post on WCF REST configuration last week.

This format might be preferrable if you are indeed building a public API that will be externally accessed. Raw POST data interchange is more common for many Ajax libraries, and also lends it self to straight HTTP clients that don't have JSON encoding features built in. For public APIs this makes plenty of sense. Remember that if you care about date formatting you may want to add the explicit JSON2 parsing code into the success callback (I left this out here for simplicities sake).

Error Handling

One more issue you'll want to be very careful of with WCF REST Services when you're using non-WebScriptService (ASP.NET AJAX style) behavior: When an error occurs WCF unfortunately throws an HTML error page rather than a JSON or XML fault message. That's a big problem if you want to return meaningful error messages to your client application - the only way to retrieve the error is by parsing the messy and very bulky HTML document returned.I've tried finding some way to get the REST services to throw a full JSON based error message and I haven't found a way to do this. JSON error messages seem to only work when you're using WebScriptService which is the full ASP.NET AJAX emulation. Under WebScriptService behavior the message returns the standard Exception like structure that includes a .Message and .StackTrace property that lets you echo back errors more easily.

In the end this means that even if you are using a non-MS Ajax client it might be the best solution to use the ASP.NET AJAX style WebHttp binding, simply because it provides the behavior that you most commonly require. There's nothing lost by doing so. You don't incur any client ASP.NET AJAX client requirements, but you do get the wrapped format input and exceptions properly wrapped on errors, plus this format is easier to implement because it doesn't require any special attributes on each individual operation/method as it's a fixed format. On the downside  you do lose the ability to use UrlTemplates which might be useful in some situations, but it's probably not a common scenario that you need this for pure AJAX services.



LINQPad as a Code Snippet Execution Engine



If you haven't checked out LINQPad before it's probably high time. LINQPad is a cool little utility that was mainly created to allow you to test LINQ expressions and see them produce a result and output the results in a nice easy to visualize format. It's great for running LINQ Queries without having to fire up Visual Studio.

LINQPad does a great job at LINQ execution and visualization, but it has a lot more uses than just a LINQ query tool. It's basically a snippet editor that allows you to save snippets and more importantly, execute just about any code that you can write as an expression or single function block . You can execute both Expressions which is a single command that returns a result or a single block of commands or a Statement which is a block of commands in a single execution block (essentially what would amount to a method body).

It's awesome if you just want to very quickly verify how some .NET function or expression  works without having to write a test, console output routine or change your code and run it with the debugger.

For example, just a minute ago I was having some issues with a Path.Combine() in an application where the two path components passed in would be a path and filename, except that the filename could also have a leading slash and it was returning what I thought are unexpected results. Here's what this looks like in LINQ Pad after I needed to do some quick experiments with various different combinations of files and paths:

 LinqPadExecute

You can see the unfortunate result in the first result line in the Results panel which produces \test.tmp instead of the expected combined path. Actually the behavior is correct - the combination of the two paths sees no common path to combine so it just uses the latter part. Still I expected the function to assume I wanted to combine two paths regardless of the leading slash. <shrug>

Anyway, using LINQPad it was a piece of cake to paste the line and execute it without even touching the code I was working on in Visual Studio. LINQPad uses a .Dump() extension method on object to display the content of just about any structure to text output. It'll dump simple values with .ToString() and complex structures in an easy to visual tabular display. For example, above I added an anonymous type to the result which is shown in the table in the results pane above.

The cool thing is that it works with any code. There's even an Advanced option on the Query menu that allows you to import assembly references and namespaces so you can test your own assemblies.

Of course LINQPad - as the name implies - also works with LINQ queries and does a wonderful job of displaying LINQ and LINQ to SQL results:

LinqPadSqlResult

Output can be displayed both as a result table view, the raw SQL (from .ToString()) and a useful code conversion from the LINQ Expression syntax to LINQ command syntax using command chaining of the various LINQ extensions methods.

There's no installation - it's a single self contained EXE you can copy anywhere assuming you have .NET 3.5 installed.

If you haven't looked at LINQPad before - even if you're not using LINQ yet, be sure to check it out...This is one of those useful tools you just should always have around and "linqed" to a hotkey, in VS or as I do with SlickRun. It's a great way to quickly check out many things .NET.



Byte Order Marks and XmlDocument Streaming to HTTP



Argh. I just got bit again by Byte Order marks that get sent out over HTTP when using ASP.NET. Basically the problem is that .NET's default XmlTextWriter encoding uses UTF-8 and the default Encoding includes generation of a BOM as part of the output. If that output gets sent to the Response output the BOM gets sent along with it which is definitely what you want.

In case you don't know what a BOM is - it's the the preamble that gets attached to the beginning of the document to identify its Encoding. There are different preambles for different Encodings. It's meant for files stored on disk so that when a file is opened there's a quick way for an editor to detect the encoding for the file. If you look at a UTF-8 document with a hex editor (or any editor that doesn't apply any encoding) you'd see:

<?xml version="1.0" encoding="utf-8"?>

If you use UTF8Encoding in .NET it defaults to generate this BOM prefix by default. Most XML objects in .NET too use XmlTextWriter for streaming output to, and they too defaults to UTF8Encoding. So if you stream XML to disk you'll get the right result which is what you want.

However, if you're streaming the XML to some other direct output  source such as Http from ASP.NET you definitely don't want the BOM in front - it in fact makes the XML document invalid. I just had some code that does the post the content of an XmlDocument to an Http server. The following code incorrectly streams  and ends up sending a BOM to the server:

public string PostDocument(string url, XmlDocument doc)
    {
 
        // *** Output from Http request will be stored here and returned
        string result = null;
 
        MemoryStream ms = new MemoryStream(1024);
 
           XmlTextWriter writer = new XmlTextWriter(ms);
        
            doc.Save(ms);
 
            // *** Rewind the stream
            ms.Position = 0;
 
            // *** Http Wrapper Component            
            wwHttp http = new wwHttp();
 
            // *** Pre-create request object so we can set properties on it
            http.CreateWebRequestObject(url);
 
            // *** Content will be XML
            http.ContentType = "text/xml; charset=utf-8";
 
            // *** Pick up the client Http headers that we need to add to the request
            Dictionary<string, string> headers = GetCreditDecisionHttpHeaders(doc);
 
            // *** Add all Http headers to the request
            foreach (KeyValuePair<string, string> kv in headers)
            {
                http.WebRequest.Headers.Add(kv.Key, kv.Value);
            }
 
            // *** apply the POST data from stream
            http.SetPostStream(ms);
 
            // *** And send the request
            result = http.GetUrl(url);
 
        
        // *** Return the string result (should be OK)
        return result;
    }

In this code I have an XML document that is previously created and stream it out to a stream. The stream is then used as input POST data for an HTTP request that posts the XML document to a service. The http object here is a small wrapper around HttpWebRequest and essentially it assigns the stream into the RequestStream which then posts the data to the server.

This code as shown above will generate a BOM and so will be effectively invalid... The reason for this is that doc.Save(ms) will stream out using the default XmlTextWriter that XmlDocument uses and so it includes the BOM based on the default UTF8Encoding.

The way to fix this is to use an explicit XmlTextWriter as an intermediary for streaming:

public string PostCreditDecision(string url, XmlDocument doc)
 {
 
    // *** Output from Http request will be stored here and returned
    string result = null;
 
    MemoryStream ms = new MemoryStream(1024);
 
    using (XmlTextWriter writer = new XmlTextWriter(ms, new UTF8Encoding(false)))
    {
        doc.Save(writer);
 
        // writer.Close();                
 
        // *** Rewind the stream
        ms.Position = 0;
 
        // *** Http Wrapper Component            
        wwHttp http = new wwHttp();
 
 
        // *** Pre-create request object so we can set properties on it
        http.CreateWebRequestObject(url);
 
        // *** Content will be XML
        http.ContentType = "text/xml; charset=utf-8";
 
 
        // *** Pick up the client Http headers that we need to add to the request
        Dictionary<string, string> headers = GetCreditDecisionHttpHeaders(doc);
 
        // *** Add all Http headers to the request
        foreach (KeyValuePair<string, string> kv in headers)
        {
            http.WebRequest.Headers.Add(kv.Key, kv.Value);
        }
 
        // *** apply the POST data from stream
        http.SetPostStream(ms);
 
        // *** And send the request
        result = http.GetUrl(url);
 
    }
    // *** Return the string result (should be OK)
    return result;
 }

Here the explicit XmlTextWriter is created with an explicit UTFEncoding. The key is:

new XmlTextWriter(ms, new UTF8Encoding(false)))

Note the false parameter on UTF8Encoding which turns off the BOM generation.

This is a subtle issue and it's easy to miss or forget about, because the BOM generation is by default and just about all the XML writers in .NET use it. It's also not easy to see the fact that the BOM is there, because if you render the output into a browser it gets stripped out. If you save the output to file too you're not likely to see the BOM even though it's there because when you open the file in a text editor the editor applies the BOM and strips it out. Even .NET's XML objects will skip over the BOM when reading XML. But if you're interfacing with other solutions like Java there will be problems.You'll only see it show in a hex editor or if you do an Http trace.



Dynamic Queries and LINQ Expressions



I'm revisiting some code in my LINQ to SQL business objects layer that I've written about before. The problem I ran into and described was that I had a class with generic business object behavior that needs to look up values based on a database field that wouldn't be known until runtime.

The concrete example I used is a Load(object x) method on the business object, where each instance of the class dynamically picks up the primary key (from the metadata available) and then loads an entity from the database through LINQ.

In application level code you'd just write:

int pk = 10;
CustomerEntity cust = customer.Context.CustomerEntities.SingleOrDefault(cust => cust.Pk == pk);

This is easy and works fine because the cust.Pk field is available at compile time - the compiler knows the type and all's well. But it's not so straight forward if the field is user specified and not available at compile time such as in a generic base class that needs to Load() a single entity.

So if I have a Load method:

public TEntity Load(object Pk)
{            
  Table<TEntity> table =  this.Context.GetTable( typeof(TEntity) ) as Table<TEntity>;
  return table.SingleOrDefault(ent => ??? == Pk);                        
}

how do I get at the dynamic primary key field through LINQ? I know what the field name is but that's string rather than a field instance.

There are a number of approaches:

  • Skip LINQ and go straight to string SQL Queries
  • Use DynamicQuery
  • Use Lambdas instead of fixed parameters
  • Use stored Lambda Expressions

Skip LINQ and use SQL strings with ExecuteQuery<T>

The easiest way - even if very unLINQ like - is to use SQL strings. After all we're talking about SQL here and we've written SQL for aeons, so NOT EVERYTHING has to be running through LINQ, right? In certain controlled circumstances (and also some instances where LINQ just won't work) using string queries is still useful and if you have dynamic expressions often times it's just easier to use a string query than to go through the mental gymnastics of figuring out to run the query using LINQ.

This is actually the route I chose, because in this case - doing a single key look up inside of the controlled business layer - is going to be the most efficient way to retrieve a value. You can do this through LINQ's DataContext.ExecuteQuery method and still get an IQueryable<T> back as a result.

public TEntity Load(object Pk)
{             
  string sql = "select * from " + this.TableInfo.Tablename + " where " + this.TableInfo.PkField + "={0}";
  return this.Context.ExecuteQuery<TEntity>(sql).SingleOrDefault();
}

This is easy and while it bypasses strong typing, this is actually a good solution for controlled queries that are dynamic. And it's more efficient to boot - there's no parsing the query into a SQL string since you get to do it yourself. The cool thing with this method is that it works against any type - entities or otherwise.

This only works with LINQ to SQL (and LINQ to Entities with entity Sql). Won't do you any good for LINQ to Objects.

Dynamic Query

Dynamic query is a sample that ships with Visual Studio (Help | Samples | Local Folder | CSharpSamples | DynamicQuery | DynamicQuery.cs) and it  provides overloads for several of the query operators like .Where that let you use string expressions rather than instance values.

Dynamic query is easy enough to use once you've added the source file to your project and System.Linq.Dynamic to your namespaces:

public TEntity Load(int pk)
{ 
        Table<TEntity> table = this.Context.GetTable(typeof(TEntity)) as Table<TEntity>;
        return table.Where(this.PkField + " == @0", pk).SingleOrDefault(); 
}

Dynamic method is a sample, and looking through the code there's a shitload of code using Reflection and expression parsing that executes to dynamically create these this string into a an expression. It's expensive in terms of CPU cycles expended to get the string into an expression.

Note that dynamic query overloads only the Where clause so the syntax is a little different - SingleOrDefault() isn't updated with the sting expression syntax.

Like the SQL Strings option using DynamicQuery doesn't give you strong typing on the strings obviously. But it does work with all flavors of LINQ so you can use it with LINQ to Objects.

Out of all the options this is the one I like least even though it's easy.

Use Lambdas instead of fixed Parameters

Several people suggested recreating the Load() method to take a Lambda instead as a parameter instead of a single value. This easy to do as well, but the method consumer has to know about Lamdas and maybe spend a few extra seconds thinking about what the Lambda parameters mean.

The implementation of this approach:

public TEntity Load(Func<TEntity,bool> predicate)
{
    Table<TEntity> table =  this.Context.GetTable( typeof(TEntity) ) as Table<TEntity>;
    return table.SingleOrDefault(predicate);
}

The input is passed as a lambda that matches the lamda expression that would be used for the actual call to the filter method - SingleOrDefault() in this case. That's easy enough - for the designer.

But the end user's experience  leaves something to be desired:

CustomerEntity entity = customer.Load( cust => cust.Pk == 3);

If one's comfortable with Lamdas I suppose this isn't terrible, but still writing this a bit more effort than a simple:

CustomerEntity entity = customer.Load(3);

I vastly prefer the latter syntax if for nothing else that everytime I have to write a Lamda I have to think about what the parameter input means.

[04/14/2008 - updated from comments. Thanks to Richard Deeming for catching my oversight and posting a sample. Incorporated here]

But there's a problem with this particular implementation if you use it with LINQ to SQL: The problem is by using a a simple Lambda delegate - rather than an Expression tree - LINQ to SQL will not be able to roll the expression into the final SQL statement but rather retrieve all records and filter on the client. Ooops, not really what we want here.

Rather what's required is that a LINQ Expression Tree gets created for the expression and that this value then gets used in the query. This results in the proper rolling of the expression into the final SQL parsing the LINQ to SQL performs.

Thanks to Richard Deeming for pointing out this issue and posting the Expression syntax. The following code is Richard's taken from the comments below and should be implemented on the business base class. Front end code stays the same as above.

protected Expression<Func<TEntity, object>> pkFieldExpression;
 
protected Expression<Func<TEntity, bool>> FilterByPk(object Pk)
{
    // ent => PkFieldExpression(ent) == Pk          
    ParameterExpression entity = Expression.Parameter(typeof(TEntity), "ent");
    Expression keyValue = Expression.Invoke(this.pkFieldExpression, entity);
    Expression pkValue = Expression.Constant(Pk, keyValue.Type);
    Expression body = Expression.Equal(keyValue, pkValue);
    return Expression.Lambda<Func<TEntity, bool>>(body, entity);
}
 
 
public virtual TEntity Load(object Pk)
{
    Table<TEntity> table = this.Context.GetTable<TEntity>();
    TEntity ent =  table.SingleOrDefault( this.FilterByPk(Pk) );
    this.Entity = ent;
    return ent;
}

This code basically requires that the Lambda is assigned as an Expression which is still assigned as:

protected override void Initialize()
 {
    base.Initialize();
    this.pkFieldExpression = cust => cust.Pk;
 }

But instead of directly executing the expression it's evaluated and returned as a parsed expression that describes the full predicate operation that is required for the filter conditions like Where and Single. The FilterByPk method handles this task and acts as the intermediary. This looks messy but remember in my situation this goes into the base business object and then never used again directly...

In general, using a lambda expression vs. a single value parameter on the load method also changes the behavior of the method - it essentially becomes filter function and no longer is a retrieve by pk function. This may not be desirable in some scenarios, but may actually provide more flexibility in others. Still - for a business level interface I don't think this is appropriate and the simpler syntax of just passing a Pk trumps it easily.

Storing and Reusing a Lambda Expression

Another similar approach that allows for using the simpler Load(x) syntax is: Rather than specifying the Lambda expression every time you call Load, the Lambda is assigned internally once when the object is initialized. This can be internal to the object and set up once initially when the business object is created. The lambda is then stored and rolled out in the Load method as needed.

Here's how this works. First there's a field on the business object base that holds the lambda - call it pkFieldExpression. This is declared in the base business object (wwBusinessObject for me):

protected Func<TEntity, object> pkFieldExpression;

Each concrete implementation instance class then sets pkFieldExpression  as part of its initialization code (say busCustomer):

protected override void  Initialize()
{
    base.Initialize();
 
    // *** Dynamic delegate for getting the Pk field instance
    this.pkFieldExpression = (CustomerEntity ent) => ent.Pk;
}

A Lambda is basically an anonymous delegate and this code creates this delegate with the Entity specific type applied and simply returns the field as a value.

With the expression set the Load method on the base business object can now be rewritten like this:

public TEntity Load(object Pk)
{            
    Table<TEntity> table =  this.Context.GetTable( typeof(TEntity) ) as Table<TEntity>;
    return table.SingleOrDefault(ent => this.pkFieldExpression == Pk);
}

And we're now back to being able to call the Load method with a single object parameter of int, string, guid or whatever else might work. Strong typing still works and we're doing it 'the LINQ way'.  The code is now generic in that that the business object can apply any type for a Pk (string, int, guid for example) and still use the simple Load(pk) syntax.

This latter approach of 'storing Lamdas away' is a good way to fake dynamic execution, but it takes a little getting used to. In fact, I looked cross-eyed at some of the code samples posted on my previous entry and tried to decipher the nested Lambda syntax. Actually what really helped me figure this out in the end was revisiting the Lambda chapter in LINQ in Action and staring at a bunch of different Lambda definitions again for a few minutes. Learning by absorption <g>...

Choices, Choices, Choices

Which choice works best depends on your scenarios. Personally I think I would choose the SQL string method if I do need dynamic SQL execution in generic framework level code which is the most common scenario where dynamic value and field assignments occur. Application level code should much less need to create dynamic expressions.

In addition using the SQL string approach is likely the most efficient since there's no query parsing involved just raw SQL. SQL String parsing though is limited to LINQ to SQL - LINQ to Objects and most other LINQ implementations don't have a way to turn strings into queries directly.

If using higher level code, explicit Lambdas are probably a good choice. In framework code cached Lambdas can provide some sort of dynamism without cluttering up the class's interface with potentially cryptic syntax.

This topic keeps coming up for me. I think this is the third time I've written about this now and something new comes up each time. Now if I can just unpretzel my mind from Lamda nesting sytnax. Sheesh this reminds me off doing pointer math in C <g>...




West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2008