May 2007 Blog Posts

EmbeddedPageHandlerFactory - Binary-Only ASP.NET 1.1

I'm constantly looking for ways to make deployment of ASP.NET applications easier. One of the things that makes it difficult is the ASPX markup files that have to be deployed with the app. Wouldn't it be nice not to have those? Wouldn't it be nice to be able to drop the application .dll into the bin folder, pop in your web.config file, and let 'er rip?

Since I work primarily in ASP.NET 1.1 right now, the solution I came up with is for ASP.NET 1.1. There is a different/better way to do this in ASP.NET 2.0 and I will be writing/posting that as I get time.

UPDATE: The ASP.NET 2.0 version is here - based on System.Web.Hosting.VirtualPathProvider.

The idea: Embed your ASPX files in your ASP.NET application assembly. To deploy the app, drop your .dll in the bin folder and set up your web.config file. At runtime, embedded ASPX pages get extracted to a temporary location and get served up from there. When the app shuts down, the temporary fileset gets cleaned up. Easy deployment, easy upgrades.

The solution: An HttpModule that does exactly that. You set your application web.config file to use the EmbeddedPageHandlerFactory and in your ASP.NET project set your ASPX files from "Content" to "Embedded Resource." At application startup, the module will go through the assemblies you registered as containing pages and extracts the ASPX to a temporary location. A replacement for the standard PageHandlerFactory redirects requests to the temporary location so pages get served up just like usual. When the application shuts down, the temporary files get cleaned up.

Here's a snippet of the relevant bits in web.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section
      name="embeddedPageAssemblies"
      type="System.Configuration.DictionarySectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, Custom=null"
      />
  </configSections>
  <embeddedPageAssemblies>
    <add
      key="Paraesthesia.EmbeddedPageHandlerFactory.Demo"
      value="Paraesthesia.EmbeddedPageHandlerFactory.Demo" />
  </embeddedPageAssemblies>
  <system.web>
    <httpModules>
      <add
        name="EmbeddedPageHandlerFactory"
        type="Paraesthesia.Web.UI.EmbeddedPageHandlerFactory, Paraesthesia.EmbeddedPageHandlerFactory" />
    </httpModules>
    <httpHandlers>
      <add
        verb="*"
        path="*.aspx"
        type="Paraesthesia.Web.UI.EmbeddedPageHandlerFactory, Paraesthesia.EmbeddedPageHandlerFactory" />
    </httpHandlers>
  </system.web>
  </appSettings>
    <add
      key="Paraesthesia.Web.UI.EmbeddedPageHandlerFactory.AllowFileSystemPages"
      value="false" />
  <appSettings>
</configuration>
Key points:
  • The embeddedPageAssemblies section is how you tell the module which assemblies have ASPX in them. The "key" is the name of the assembly; the "value" is the root namespace in the assembly.
  • The httpModules section is where you register the module portion of the solution. This is how the pages get extracted at app startup.
  • The httpHandlers section is where you tell all requests for ASPX files to go through the EmbeddedPageHandlerFactory and get served up from the temporary location.
  • The appSettings has an optional key for AllowFileSystemPages. Setting this to true will allow you to "override" ASPX by putting a file of the same path/name in the ASP.NET application file system. If the file exists in the app, it will be served from there. If not, it falls back to the temporary filesystem.
In your web project, change your ASPX pages in your application to be "Embedded Resource" rather than "Content." Embedded resources get named based on namespace and file path. For example, if you have an assembly called "MyApp.Web" where the default namespace is "MyApp.Web" and you have a file at "~/Admin/Default.aspx" then when it gets embedded as a resource, it'll be called "MyApp.Web.Admin.Default.aspx" - notice the namespace, then the path, then the file, all delimited by periods.

What the module does is look for resources that end with ".aspx" and, if it finds them, removes the namespace from the front (as specified in web.config) and substitutes out / for . to convert back to a path. In this example, "MyApp.Web.Admin.Default.aspx" would become "Admin.Default.aspx" and then "Admin/Default.aspx."

Once the mapping is done, a temporary location is generated and the page is extracted to that location with the full relative path intact. As requests come in, the EmbeddedPageHandlerFactory will look at the request, map it into the temporary location, and serve the temporary file.

Using the appSettings key, you can specify that you'd like to allow pages in the actual ASP.NET filesystem to override the extracted pages. In this case, the actual ASP.NET filesystem would be searched for "Admin/Default.aspx" and if it is found, serve it from there just like a standard ASP.NET application. If it isn't found, then it'll fall back to look in the temporary location.

Caveats:
  • This won't work for sites that rely on file system security. I primarily work with forms authentication, so this isn't a problem for me. It may be for you.
  • This is definitely not the way you'd want to do this for .NET 2.0. This is really meant for .NET 1.1.
  • It only works for ASPX. The ASCX load process is different and doesn't pass through a handler factory like pages. The .NET 2.0 mechanism should work for any files, not just ASPX.
  • This is going to be a one-shot deal. I'm not going to be posting updates or actively supporting it or anything. Take it at your own risk, your mileage may vary, etc.
  • The source bundle includes the source for the EmbeddedPageHandlerFactory as well as a demo web application and unit tests.
  • I wrote the unit tests using TypeMock so you'll need to go get that if you want to build/run the tests.
  • It's totally free and open-source. Do whatcha like.
Download EmbeddedPageHandlerFactory Compiled Assembly
Download EmbeddedPageHandlerFactory Source

Memorial Day 10000

This Memorial Day weekend was very relaxing and one of the nicest weekends I've had in a while.

Saturday Jenn and I ran some errands, mostly on a mission to find the Guitar Hero dual gig bag to store our guitars in. We didn't find it, but had a nice day out and ended up at my parents' place, heading out to see Shrek 3 at the end of the day.

Sunday was chore day, cleaning things up around the house. In the evening we headed over to Jason and Tracy's place where we played four-person Mario Kart until all hours.

Monday was my easy day, though Jenn got a lot of great stuff done that had been needing to get done around the house. I caught up on my comic reading, watched some shows, and generally took it easy. Long about 1:00p I finally hit that point when I had totally decompressed and was stress-free (yeah, it takes about three days to get there) and was suddenly dead tired. The sun was out, the wind was gently blowing, and I could barely keep my eyes open.

That's about the time Jenn wanted to go to the store and ask for my input on which plants would be best to put in containers. Any other day I might have had an opinion, but my brain had just turned off and I could not engage it.

We got home, I had myself a little something caffeinated to wake me up, and I played some Settlers of Catan and Marvel: Ultimate Alliance, finally breaking through the 10,000 Gamerpoint barrier. I admit I stood up and did the happy dance with that.

My brain is once again engaged this morning, I'm sipping some crappy generic French Roast coffee, and I'm ready to face the week, slightly less stressed.

How Do You Tell If Two Objects Can Be Added?

I'm working on a DataGridColumn that can automatically sum up the data in the column and display a total of the data in the footer. This sort of thing comes in handy when displaying tables with account activity or balance data in them and allows you to just put the special column type right into the DataGrid without having to modify your page behavior to do the summation.

So I created my column class have it set up so when the column is databound, each cell in the column will contribute its bound value toward a total. That's where I ran into a snag - since I don't know what object type is being bound to the column, my "total" variable is just an object... and base objects don't support addition.

How do you tell if an object type supports addition?

That's actually something I can't answer. My original thought was that when you override the addition operator, the compiler generates a static "Add" method for your data type. You can see this in Reflector. Here's the System.Decimal class:

System.Decimal supports the Add method.

Notice there's a static method called "Add" that takes in two System.Decimal objects and returns a System.Decimal object. That's what you see when you override the addition operation.

My idea was that I would get the first object being bound to the column, get its type, and see if it had a static method called "Add" that takes in two objects of that type and returns an object of that type. If that method exists, I'll hold a reference to it and invoke it for every subsequent data item being added.

The problem is, this static "Add" method doesn't show up for other base types. For example, there's no "Add" method for System.Int32:

System.Int32 has no Add method.

So that idea won't work.

I talked to Hanselman and Sells and they both thought the "Add" method would be there. No such luck.

Right now I'm working around it by special casing all of the types in mscorlib that I know we use that can be added together... but is there some better way I can, through Reflection, determine if two objects can be added (and then actually perform that addition)?

Horton Wedding

It's been a heck of a busy week, so I haven't had a chance to blog about the wedding I went to this past weekend.

Saturday Jenn and I packed up and headed to Puyallup, WA, to see my cousin Haley get married. The ceremony was at High Cedars Golf Club. It was a nice ceremony, though the minister seemed a little frazzled like he had never performed a marriage ceremony before. Regardless, congratulations to Haley and Adam Horton.

Immediately following the wedding there was a minor incident involving Adam running over Haley's dress with a golf cart and ripping the back on it, but a few safety pins later and Adam's first married-life "I'm sorry," everything was back in order.

The real excitement came when we checked into our hotel up there. We stayed at the Crossland Economy Studios up there because we knew the wedding would go reasonably late and we didn't want to drive the three hours back that night.

When we made the reservation, they offered us our choice of a room with two double beds or a room with two queen beds. A double's a little small, so I picked the room with two queens. When we got there, they told me the hotel was packed, so rather than getting one room with two beds, they had me in two rooms, each with one bed, where each room would only cost me half price. Not needing two beds, I told the clerk I only needed one of the rooms. The cool part - I got to keep the half price. So I stayed there for $35, including tax.

The not so cool part - the bed was a freaking double. Oh, and the mattress was firm, sort of in the sense that a sheet of plywood laying on cement is firm. But, hey, $35, right?

We had a decent drive home the next day (though the trip south on I-5 is one of the most boring drives ever) and spent most of the day Sunday lounging on the couch, exhausted.

eBay Scammer on Judge Judy

I saw this over at BoingBoing. Judge Judy is my hero. I aspire to be Judge Judy. Watch as she rips this ridiculous eBay scammer a new one.


Test With... Silverlight/CoreCLR

Jamie Cansdale has done it again, adding "Test With Silverlight" to TestDriven.NET.

Check it out. So hot.

TypeMock Case Study in Corillian

Eli Lopian from TypeMock has blogged the case study we did with TypeMock showing how much more productive we are in testing using TypeMock.

We've been vastly more productive using TypeMock than we were before we adopted it. If you get a chance, check out the Case Study PDF. It pretty much says it all. And if you haven't tried TypeMock yet, what are you waiting for? Go get it. You'll like it, I promise.

(In the interest of shameless-self-promotion full disclosure, I'm fairly prominently quoted in the case study. I can't lie; it makes me smile. Can't help but love TypeMock.)

I'm a CheckFree Associate Now

Corillian is now a part of CheckFreeIt's official - Corillian is now a part of CheckFree. That makes me an "associate," as CheckFree employees are called. Sweet.

There's a meeting tomorrow morning to discuss more detail about what's going on and the changes to come. I'm given to understand that we'll keep the Corillian name (which means my work email doesn't change, which is good because that'd just be a pain).

It's an exciting time to be a part of the Consumer Banking team at Corillian. I look forward to what's in store.

The Weekend and Guitar Hero

The weekend was sort of a mixed bag. For every good thing that happened, there was something bad to balance it out. Starting Friday...

Good: I finished up a huge piece of the project I've been working on and checked it in before leaving work. Love that closure!

Bad: Jenn's cat, Jack, decided to fervently clean his week-old declawed paws and opened one up. Spent most of the night at DoveLewis Animal Hospital getting him fixed up.

Good: My parents came over Saturday and we caught up, played some Guitar Hero 2, and went out to a great lunch at Costa Vida.

Bad: Determined that the cats really don't like using the litter box when it's got that crappy pine litter in it (gotta use pellet litter while Jack's paws heal up) and found that one of them - we don't know which - peed on the rug in front of the litter box rather than peeing in the litter box.

Good: Went tooling around on Sunday and stopped by GameStop on a whim. Found a used Xbox 360 Guitar Hero controller. Snapped that up and busted ass home to play a little cooperative Guitar Hero with Jenn.

Bad: Found out the tilt mechanism in the controller was bad so you can't turn on "star power" by tipping the guitar up in the air. (I think it was stuck "on" because in cooperative mode it's supposed to require both of you to tip your guitars up to enable "star power" but I seemed to be able to do it on my own. That said, we rebooted the console with just the new guitar plugged in, fired up the game, and in solo mode, you couldn't turn "star power" on. So... bum controller.)

Good: Got a lot of chores done on Sunday. House is vaccuumed, dusted, mopped, and generally straightened up.

Bad: Cats again decided not to pee in litter box, instead choosing to pee on a bathroom rug. And, no, the newspaper pellet litter isn't any better. We tried it. They want actual litter, not this pellet garbage.

Anyway, you see how that works. Overall, I think the weekend was good. Jenn and I had a total blast with Guitar Hero. We played every single song that you can unlock in Easy mode (neither of us are very good, so Easy was right up our alley). I've since ordered a controller directly from RedOctane. A little more expensive, but at least we know it'll work.

My aunt emailed me because my cousin is getting married this weekend (once again, I won't be able to make it to Code Camp) and it turns out that RSVPs are a source of tension. Huh. I never would have guessed. It just amazes me how people don't feel that responding for an event is important, let alone a big event like a wedding. It's not just annoying, it's disrespectful to the people inviting you. It's even worse if you don't respond and then you show up, or you respond saying you'll be there and then don't show. And the real killer is - unless you've had an event like this yourself in recent memory (because people seem to forget what a problem the RSVPs are if it's not recent or documented), you won't really understand. When it's your money on the line and you're paying a decent sum of money per head, suddenly you'll realize - "Aha! That's why it's so important to respond!"

But I digress.

This week the theme is going to be "taking care of business." This morning already I've met with a repairman named Yance from Dennis' Seven Dees because one zone of our sprinkler was not coming on and one of the nozzles on one of the heads was broken. Got that all fixed up in about five minutes, no problem. At lunch today I'm heading over to H&R Block to see how bad the CheckFree acquisition of Corillian is going to hose me tax-wise and see if I can do anything about it.

I'm also still working (very, very slowly, but surely!) on the blog conversion to Subtext as well as my Xbox 360 media center solution. Oh, and CR_Documentor emulation of Sandcastle. I think I'm going to get the blog converted over to Subtext first, then tackle the other two.

Registered Easier To Remember Domain Names

I've heard some whiny people complaining about how it's hard to remember my domain name, so to make it easier I've registered some domains that will redirect you here:

travisillig.com
travisillig.net
travisillig.org

So hitting http://www.travisillig.com should redirect you to http://www.paraesthesia.com. I even registered the .net and .org domains so you don't have to remember the extension, you lazy bums. All you have to do is remember my name, and *bam* you're here.

(I wanted "illig.com" but it's some punk clothing manufacturer... and "tillig.com" is a model train company... so you get the full name.)

posted @ Friday, May 11, 2007 8:18 AM | Feedback (0) | Filed Under [ GeekSpeak ]

Fix Xbox 360 USB Detection With a USB 2.0 Hub

I have the HD DVD drive, the Xbox Live Vision camera, and the wireless network adapter - all USB devices - for my Xbox 360. I had them set up like this:

Xbox 360 - Before

Note how I was using the HD DVD drive as a USB hub - the Xbox connected to the HD DVD drive, then the rest of the devices chained through that. The problem I was seeing is that the Xbox would start up, detect the HD DVD drive, and then would time out trying to find the rest of the USB devices. To fix it, you could either reboot the Xbox 360 a couple of times and hope or unplug and replug all of the devices it didn't find the first time (which, interestingly enough, was only about 80% successful).

I called Xbox support about this and they didn't have an answer, just that the Xbox was "timing out" while reading USB devices. I've never seen that before, but I've got a sneaking suspicion that the USB hub portion of the HD DVD drive doesn't become active until it's detected by the Xbox. Not sure why that would be, but that seems to be the behavior I'm seeing.

I got fed up with that and went to the store to pick up a USB hub. My setup looks like this now:

Xbox 360 - After

Now I have the Xbox 360 plugged into the hub and everything chains off that. So far, I've had 100% success - fire up the Xbox and everything is detected without issue.

The hub I bought was a Belkin Hi-Speed USB 2.0 4-Port Hub. It's nice and compact so it's easy to hide behind the Xbox.

Belkin Hi-Speed USB 2.0 4-Port Hub

You might ask why I didn't just plug everything into the Xbox directly - use the front ports on the Xbox as well as the back port. The reason is that I don't want a bunch of cables floating around on the front of the Xbox. It looks horrible. Plus, when I fire up Dance Dance Revolution, I need those front ports free for the dance pads. Or for my Guitar Hero guitar (coming soon).

Anyway, if you're having trouble getting the Xbox to find all of your USB devices, get a hub. It's worth the $20.

Random Catch-Up Post-MIX

So I was out Sunday night through Wednesday night at MIX07, which was hella cool and well worth the trip, but that means I didn't really get much chance to blog the random garbage that collects in my head, so here we go.

We bought this automatic light switch for the house that turns the exterior lights on and off. We wanted it timed so we wouldn't have to have someone watching the house. Home Depot had two models - one was this sort of bulky-looking analog deal, and one was this slick, clean digital one. For $1 extra, we bought the slick digital one.

I'm not a big handyman around the house, but aside from some fairly minor technical difficulties and a cat that just would not stop stealing the screws to the faceplate, I got it installed. Configuration, on the other hand... wow. This thing could pilot the space shuttle by itself. I'm afraid I'm going to want to turn on the lights and I'm going to hear HAL tell me he won't allow the lights to go on. It's pretty cool once you get it set up, though. It knows, based on your general location in the US, about when sunup and sundown are, and you can tell it to automatically turn off at those times. Or, if you don't like that, you have seven different programmable on/off times - one on and one off per day - that you can set. Or you can say "weekdays I want this, weekends I want that." Or, or, or. It's almost too configurable.

The automatic cat box worked out pretty well. I found it's not really a no-touch sort of thing; it requires interaction every couple of days. But I can put up with that - it's always nice and clean, and there's a certain cool factor about it.

Jenn is hobbling around the house because she blistered her feet so bad walking around in Vegas. I feel bad for her, but I have to laugh - she rented a car while we were down there specifically to avoid walking around. That worked out well.

I'm stoked about Silverlight but I've got to finish converting my blog over to Subtext before I start screwing around with it. I also want to finish the CR_Documentor support for Sandcastle, which shouldn't be overly difficult to do but isn't very fun and will just be a time consumer. I'd release it to the world to help out on, but I can't because there's some proprietary stuff in there left over from the original Lutz implementation and there's some crazy legal garbage stopping me. So I muscle through.

As far as the migration goes, I've got a BlogML converter to export my blog entries with, but I have to create a mapping between the pMachine entry IDs and the new Subtext IDs so I can put up a redirection mechanism to allow folks coming in using the old links to be forwarded to the new links. That's taking a little bit. I was trying to write it in a nice, reusable fashion (the ID mapping tool) so I could submit it to... well, some project out there, anyway, but it's taking far too much time to do that and since I'm really only going to use the thing once, I've got to scale back my effort and just get it done already. (Once I have that, I can write the redirector, update my cross-post links, figure out where my image content needs to go, and, finally, get Subtext up and going. Yeah, it's an effort.)

I had some Barnes and Noble gift certificates saved up so I ordered Guitar Hero II for my Xbox 360. That should be here soon and should provide some serious fun. I didn't get into any of the MIX07 Guitar Hero action, but I've played it in the store. I need to practice. The key really is all in getting used to the controller.

Speaking of Xbox 360, we finally got the points codes from the latest Red Ring of Death debacle so I'm going to spend some time tonight deleting and re-downloading all of our Xbox Live content so I don't have to be signed in when Jenn wants to play an arcade game. They have to fix this. It's ridiculous.

I got the Fergie CD The Dutchess and noticed a few things. First, the uncensored versions of the songs make a lot more sense than the censored versions you hear on the radio. I like the CD versions way better. Second, someone dropped the ball on the mixing. There are a couple of songs where Fergie's voice stands out from the music in places like it doesn't belong. It sounds... rushed. Third, and final, someone really needed to run QA on the language portion of the album. What the hell is "dutchess?" Is it ebonics for "more Dutch than anyone else" (as in "I know you're Dutch, but I'm the Dutchess fool here")? ("Duchess" doesn't have a 't' in it.) And in the first song, "Fergalicious," they spell "tasty" as "tastey" - with an 'e' in it. What the...? Doesn't anyone speak English anymore?

Our bad Jack cat is off getting declawed tonight and we'll be picking him up tomorrow. The vet called with an update after the surgery was over and I guess he's super wild and they can't give him enough toys to play with. I guess the fentanyl patch he's got on isn't slowing him down a bit.

Jenn has become addicted to Hotel Dusk: Room 215. She picked it up before we left for Vegas and hasn't put it down. It looks pretty good; I may have to play it.

I think that's it. It's been a heck of a week. Yesterday was pretty-much a no-op, trying to get expense reports filed and get back up to speed after being out of town, and today, frankly, I've had some severe motivational difficulties. Hopefully things will return to normal next week.

MIX07 - The PURE Party and the Morning After

Last night was the big mix-and-mingle party at the PURE nightclub in Caesar's Palace.

I got there around 6:30p, a little after it started, and, after going through a TSA-style checkpoint to get in (I was actually relieved we didn't have to take our shoes off), I got to start actually meeting some folks.

PURE itself is a pretty nice place inside with lots of little places to sit and gather and talk. Of course, that makes it a problem to find anyone specific you might be looking for because they could be hidden away in any number of little cubby holes. Good food, great drinks, decent music.

At one point The Pussycat Dolls came out and performed. It wasn't the actual Pussycat Dolls (like, the ones that tour and put out albums) but the performance was the same and it was a lot of fun.

I spent most of the time hanging out with Joe Pruitt, Jon Galloway, Phil Haack, and Miguel de Icaza. Hanselman made the rounds, and toward the end of the night on the way out the door we bumped into Clemens Vasters and Michele Bustamante. I tried to find Atwood, but never seemed to cross paths with him even though he was there. I think I crossed paths with Anders Hejlsberg at one point but wasn't sure and he seemed to be on a mission headed somewhere so I didn't get a chance to say hi.

Around 9:45p they opened the club up to the general public, and while I planned on staying, the way they did it was by locking different sections down so if you left the section you couldn't get back in, and drinks started costing upwards of $10 for a $5 drink. Thanks, but no thanks. Hanselman left, I left, and several other folks left (though I got a Twitter from Haack at 2:30a saying he was just then leaving).

All in all, a great party. I know where my conference registration fee went.

While that was good, the following several hours weren't as good. The Venetian is under some level of construction, so they shut off the water to the rooms at midnight and scheduled the water to be back on at 4:00a. They left us bottled water to drink, but that didn't stop me from having to get dressed at 3:00a, go down 20 floors, and cross the lobby just to go to the bathroom.

Oh, and water didn't get restored until about 7:30a. Hot water showed up closer to 8:30a, which means I missed breakfast and most of my first morning session. Lame.

Anyway, I'm in a Silverlight development session now. I like what I see. Sounds like there are a lot of folks in a "programmable web" session, but since this is a two-part session, I didn't want to miss the first part. I'll have to watch the video of the programmable web session.

MIX07 - Labs and Day 2 Keynotes

I've run late all day long today for some unknown reason so I ended up coming in on the tail end of lunch and missing my last session because it was overbooked. Instead, I spent some time with the hands-on labs and got some experience working with Silverlight.

The labs they have are good and really do illustrate the concepts behind working with Silverlight. I ran into a couple of snags because it's all running in Visual Studio "Orcas" so some of the debugging experience was a little flaky, but generally it's a pretty decent platform. Writing the XAML is easy as it is, but working a product like Expression Blend into the mix makes it super-simple.

I believe they're going to put these labs up on the web for folks to download and run through. I recommend doing the one where you build a Silverlight clock application and the one where you build a Silverlight image viewer.

Oh, and for some decent insight into Silverlight, check out Barak's blog - he's the PM for Silverlight and I have a feeling there's going to be good stuff showing up there.

The afternoon keynote started out with Robbie Bach, President of the Microsoft Entertainment and Devices Division. So, basically, he's over Xbox, Zune, Media Center, and that sort of thing.

The talk focused a lot on the marketing aspect of creating a good media experience. It felt a little like the same "how to get eyeballs on your product" sort of talk, and I know there's no free lunch - someone's got to pay for things, and advertising is huge revenue because you've got to sell product, but I felt sort of... well, dirty. I mean, I find things like in-game advertising annoying, but that was one of the big key things shown as a great way to go moving forward.

The overall notion is that a media experience should be personal (relevant to the user directly); interactive (let the user engage themselves in the experience); and social (let the user interact not only with the content but also with other users). To do that, new marketing efforts need to excite (make people excited to interact with it); attract (invite the user to gravitate toward the content); and engage (have a two-way interaction with the user).

Following Bach, Gayle Troberman, General Manger World Wide Branded Entertainment at Microsoft, came out and led a discussion with some marketing folks - Andrew Rashbass (Publisher and Managing Director, The Economist), Jonathan Hsia (Associate Marketing Director, Starcom MediaVest Group), Carol Kruse (Group Director, Interactive Marketing, Coca-Cola), and Winston Binch (Executive Integrated Producer, Crispin Porter and Bogusky).

By that time, I'd heard pretty much enough about how to interactively engage people to sell products in new ways in a digital fashion. I get it, it's just not my bag.

Back to the lab.

MIX07 - Developing ASP.NET AJAX Controls with Silverlight

This session discussed how you can use ASP.NET AJAX controls and take advantage of Silverlight at the same time - creating a server control using the ASP.NET AJAX server control framework that uses Silverlight for its presentation.

There are several advantages to doing things like this - you can do this to slowly migrate a site to using Silverlight (one control at a time); you can separate the presentation of the control into code and XAML, giving more control to site designers; and it gives you new abilities using cross-platform vector graphics.

The meat of this presentation was code, so there's not a lot of bullet-point style items to recount, but there were two controls shown using this technique. The first was a slideshow control that used Silverlight to show a nice transition when switching pictures in the slideshow; the second was a dynamic graph of stock prices that refreshed periodically.

The pattern for doing this is similar to that of creating other ASP.NET AJAX controls. To that end, both demos were done by deriving from the Xaml control that has a lot of base functionality and implements the proper AJAX script interface and saves you time when starting your own XAML based controls. The Xaml control is a part of ASP.NET Futures (so it's not the base package yet but should be soon).

Basically there are three parts - write your XAML to handle the UI, set the XamlUrl property on the Xaml control so it knows how to display, and write the client script to work against the XAML tree. Obviously that's pretty simplified, but it seems to me that the hard part really is working out the proper JavaScript to manipulate the XAML and intercept the events. ASP.NET AJAX seems to have a lot of helpers and convenience methods to make this easier, but if you're not writing this in Orcas I can see where it'll be a little slow to ramp up on.

I like the approach of writing controls using Silverlight. The ability to slowly migrate a site or individual functionality over to use Silverlight one control at a time is appealing. I can envision several charting or graphing applications I could use this sort of thing in.

MIX07 - Designing for AJAX/RIA

This session was a more general "patterns" type of session where there were several UI patterns demonstrated to help you make a better user experience when working in AJAX.

The patterns and principles discussed can be found in the Yahoo! Design Patterns Library.

The idea is that a common vocabulary needs to be arrived at so designers and developers can have meaningful discussion about user interaction.

Principle - Keep a Light Footprint
The idea here is that in a rich Internet application you can reduce the number of steps in a workflow or process and ensure simple interactions are simple. Identify pain points in the process and shorten the path. Design for engagement - keep the user's attention. An interesting side note - it's good to make things easier, but in some cases a design can have a very real economic impact on the application - for example, providing a lot of pre-action-lookup (like if Google Suggest returned search results, not just search terms) might make your application less scalable and require a lot more hardware to support.

Patterns: Inline Editing, In-Context Tools, Drag and Drop.

Principle - Cross Borders Reluctantly
If you don't have to take the user to a whole new page, don't. Rethink flows - base the flow on the user model, not a page model. Rethink paging - could you use scrolling or a carousel instead?

Patterns: Hover Details, On-Demand Scrolling, In-Context Expand, Inline Assistance, Lightweight Popups, Lightbox.

Principle - Give Live Feedback
Let the user preview the result of their action where possible. Provide things like field validation, inline previews (like a clothing store that lets you see what a piece of clothing might look like on you prior to you purchasing it), and so on. Try to prevent errors before they happen. If you refresh data on the page, be careful it's not distracting or annoying. When an action takes place, let the user know what happened.

Patterns: Live Suggest, Auto Complete, Periodic Refresh, Busy Indicators.

Principle - Offer an Invitation
Let the interface be discoverable by inviting the user to take relevant actions. Bridge the new with the old - use hyperlinks (a commonly understood indicator of action) provide a route to discovery, for example. Keep actions out of it - if you take actions as the user explores the interface, it makes them reluctant to search out new functionality. Unfortunately, there's no easy/single solution to this.

Patterns: Hover Invitation, Tour Invitation, Drop Invitation, Tooltip + Hover + Cursor Invitation.

Principle - Show Transitions
Show a user what happened (like when an item is deleted) by using transitions. For example, if an item is removed from a list, fade the deleted item out and shrink the list in an animated fashion to show the item being visually removed.

Patterns: Self-Healing Transition, Slide Transition, Active Spotlight.

Anyway, some great pointers. Definitely gives me some ideas for ways to solve some of the UI problems we face every day at work.

MIX07 - Front-Ending the Web with Microsoft Office

There's a lot of Silverlight content floating around at MIX07, so I thought I'd check out some different stuff.

The session on integrating web-oriented content into Office was lightly attended but very interesting. There are a lot of services out there and a lot of Microsoft Office users. The idea is that a user experience can be much richer if you don't make the user leave Office to get to the data they need - instead, integrate the data right into Office.

I like the idea. While it does mean an additional download/install for a user, as an additional offering for ways to access data, this is good stuff.

Demos were done using Visual Studio "Orcas" (an as-yet-unreleased build - so you can't do all the things quite as easily as the demos showed, but once it's out, it looks like extending Office is a piece of cake) and Visual Studio Tools for Office.

Some of the things shown - creating custom ribbons; integrating a hosted web browser in a task pane; creating Windows Presentation Foundation controls and displaying/using them; custom form creation and integration in Outlook (very cool - based on message content, a specific set of controls becomes active).

Two specific demos caught my eye, both in Outlook. The first was a custom form that lets you get sales contact data mailed to you and when you open the message, you can select a contact to see a map pop up and show you the geographic location of the contact. Select multiple contacts and it builds you a route and shows you directions on how to go from one contact to another. The second was plugin that worked against RSS messages such that when you're reading a post in Outlook you can click a button to show a panel that has the original blog post displayed in a browser so you can see it in its original context.

Anyway, very cool stuff. I can see that this would be more valuable to more internal IT-style development, but also opens up some nice value-added services. What if you could get an email notifying you of an incoming bill and click a button right in Outlook to pay it?