Wednesday, October 15, 2008

Connecting to iPhone Applications via Peer-To-Peer Networking

I recently found myself wanting to copy some documents to the AirSharing application on my iPhone but I was not able to connect to a Wi-Fi network at the time.

As it turns out, this is really easy to do using peer-to-peer wireless networking, enabling applications like AirSharing or the Apple Remote to connect to your machine regardless of if there is an available wireless network.

Note: This can be done on Windows as well, however, I will only be covering the process on a Mac.
  1. First you need to create a new network on your Mac by selecting your AirPort menu item and choosing "Create Network...".

  2. Choose a name for your network, and optionally require a password (I would suggest adding a password to restrict access to your machine).

  3. On your iPhone, tap Setttings then Wi-Fi.

  4. Your phone should find the network you just created, tap it and enter your password if you chose to set one up.

  5. Now open AirSharing.

  6. Back on your Mac, from the Finder menu, select "Connect to Server..." (this can also be opened by pressing Command+K on your keyboard).

  7. Enter the address specified by AirSharing for connecting and click "Connect".

  8. A finder window will open with the AirSharing share and a mounted disk will appear on your desktop.

As I mentioned above, this tip is not limited to the AirSharing application.  Any iPhone application that uses wireless connectivity to interface with your machine, such as the Apple Remote, should work with this method.

Friday, August 15, 2008

Active Directory Role Provider


I've been using the ActiveDirectoryMembershipProvider to allow my users to login to a custom ASP.Net site with their AD credentials and it is pretty straight forward. Recently I needed to add more granularity to who can view various parts of the site. I wanted to take advantage of our existing AD groups so I assumed there would be something like an ActiveDirectoryRoleProvider as well. After a little searching, it became clear that wasn't the case, so I decided to roll my own.

Creating a custom role provider is pretty easy, all you have to do is create a new class and inherit RoleProvider:


public class ActiveDirectoryRoleProvider : RoleProvider
{}


You will have to create stubs for all the inherited members. We only need to implement a couple of them to get basic role membership checking. We need to get our AD configuration information out of the Web.Config values, so we'll create a few properties and override the Initialize method:



private string ConnectionStringName { get; set; }
private string ConnectionUsername { get; set; }
private string ConnectionPassword { get; set; }
private string AttributeMapUsername { get; set; }

public override void Initialize(string name, NameValueCollection config)
{
ConnectionStringName = config["connectionStringName"];
ConnectionUsername = config["connectionUsername"];
ConnectionPassword = config["connectionPassword"];
AttributeMapUsername = config["attributeMapUsername"];

base.Initialize(name, config);
}


Now we'll override GetRolesForUser which is the bulk of our implementation. We use the DirectorySearcher class in System.DirectoryServices to query AD for the passed username. We then pull the memberOf property from that user and extract the CN component for each entry as the role:



public override string[] GetRolesForUser(string username)
{
var allRoles = new List<string>();

var root = new DirectoryEntry(WebConfigurationManager.ConnectionStrings[ConnectionStringName].ConnectionString, ConnectionUsername, ConnectionPassword);

var searcher = new DirectorySearcher(root, string.Format(CultureInfo.InvariantCulture, "(&(objectClass=user)({0}={1}))", AttributeMapUsername, username));
searcher.PropertiesToLoad.Add("memberOf");

SearchResult result = searcher.FindOne();

if (result != null && !string.IsNullOrEmpty(result.Path))
{
DirectoryEntry user = result.GetDirectoryEntry();

PropertyValueCollection groups = user.Properties["memberOf"];

foreach (string path in groups)
{
string[] parts = path.Split(',');

if (parts.Length > 0)
{
foreach (string part in parts)
{
string[] p = part.Split('=');

if (p[0].Equals("cn", StringComparison.OrdinalIgnoreCase))
{
allRoles.Add(p[1]);
}
}
}
}
}

return allRoles.ToArray();
}


And finally we need to override IsUserInRole so we can easily check for role membership in code:



public override bool IsUserInRole(string username, string roleName)
{
string[] roles = GetRolesForUser(username);

foreach (string role in roles)
{
if (role.Equals(roleName, StringComparison.OrdinalIgnoreCase))
{
return true;
}
}

return false;
}


Here's the the full code (minus the unimplemented inherited methods):



public class ActiveDirectoryRoleProvider : RoleProvider
{
private string ConnectionStringName { get; set; }
private string ConnectionUsername { get; set; }
private string ConnectionPassword { get; set; }
private string AttributeMapUsername { get; set; }

public override void Initialize(string name, NameValueCollection config)
{
ConnectionStringName = config["connectionStringName"];
ConnectionUsername = config["connectionUsername"];
ConnectionPassword = config["connectionPassword"];
AttributeMapUsername = config["attributeMapUsername"];

base.Initialize(name, config);
}

public override bool IsUserInRole(string username, string roleName)
{
string[] roles = GetRolesForUser(username);

foreach (string role in roles)
{
if (role.Equals(roleName, StringComparison.OrdinalIgnoreCase))
{
return true;
}
}

return false;
}

public override string[] GetRolesForUser(string username)
{
var allRoles = new List<string>();

var root = new DirectoryEntry(WebConfigurationManager.ConnectionStrings[ConnectionStringName].ConnectionString, ConnectionUsername, ConnectionPassword);

var searcher = new DirectorySearcher(root, string.Format(CultureInfo.InvariantCulture, "(&(objectClass=user)({0}={1}))", AttributeMapUsername, username));
searcher.PropertiesToLoad.Add("memberOf");

SearchResult result = searcher.FindOne();

if (result != null && !string.IsNullOrEmpty(result.Path))
{
DirectoryEntry user = result.GetDirectoryEntry();

PropertyValueCollection groups = user.Properties["memberOf"];

foreach (string path in groups)
{
string[] parts = path.Split(',');

if (parts.Length > 0)
{
foreach (string part in parts)
{
string[] p = part.Split('=');

if (p[0].Equals("cn", StringComparison.OrdinalIgnoreCase))
{
allRoles.Add(p[1]);
}
}
}
}
}

return allRoles.ToArray();
}
}


Add the role provider to your Web.Config:



<system.web>
<roleManager enabled="true" defaultProvider="ADRoleProvider" cacheRolesInCookie="true" cookieName=".ASPXROLES" cookiePath="/"
cookieTimeout="30" cookieRequireSSL="false" cookieSlidingExpiration="true" createPersistentCookie="false" cookieProtection="All">
<providers>
<clear />
<add name="ActiveDirectoryRoleProvider" connectionStringName="ADConnectionString" connectionUsername="username"
connectionPassword="password" attributeMapUsername="sAMAccountName" type="ActiveDirectoryRoleProvider" />
</providers>
</roleManager>
</system.web>


You can then check the roles of your user in code like so:



Roles.IsUserInRole("My Group")


Or control access to entire directories via the Web.Config:



<location path="RestrictedSubDirectory">
<system.web>
<authorization>
<allow roles="My Group"/>
<deny users="*" />
</authorization>
</system.web>
</location>

Tuesday, July 29, 2008

My Fancy New 3G Wireless Card

Lately I have been finding myself in more and more situations where I am giving a presentation and I need wireless connectivity and it isn't readily available.  Yesterday I finally broke down and picked up a USBConnect 881 card from AT&T, and so far, I like it.  For about $60 a month the cost isn't too bad for what you are getting, and in using it last night, the 3G speeds were pretty good for doing what I needed to do.  I orginally wanted to go with an Express PCI card for my Mac, but opted for the USB card for more flexibility.

Saturday, July 19, 2008

My Top 5 iPhone Applications

So of course I picked up a shiny new iPhone 3G on launch day.  I was lucky to be in Hillsboro Oregon at the time which meant my line was not too long and I got to take advantage of no sales tax.  It's been a while since I've posted (I'm going to correct that in the next few weeks), so I thought I'd do a round-up of my top 5 favorite 3rd party applications.  In no particular order here they are...

This is Apple's fantastic iTunes remote.  I don't have an Apple TV yet, but I have been playing with this with my iTunes library on my laptop and it works flawlessly.  I can't wait to get my condo all setup so I can take full advantage of this tool.

This has to be one of the less polished games in the iTunes store, but it is addicting. The basic goal is to fly your little ship through a minefield of cubes, if you hit a cube, you die. You pretty much just compete against yourself for high score. The game could use stages, so you don't just end up playing the same first level over and over again, but short of that, it is an awesome first showing for a casual game.

Evernote is a great desktop tool for knowledge capture.  It works on Mac and Windows, and with their latest release they have included an iPhone client.  This comes in handy so often in my life when I have meetings where lots of white boarding occurs.  All I have to do is open Evernote and take a picture of the whiteboard and the image is automatically synced with my laptop.  On top of that, Evernote has fantastic OCR technology allowing you to then search all of your content, even my aweful whiteboard chicken scratch gets properly indexed.

I always have a terrible time picking a restaurant when it comes time to go out to eat.  This tool solves that problem in a fun way.  Using location based services, Urbanspoon will zero in on your city.  You then lock in your options, be it neighborhood, cuisine or price.  Then simply shake your phone and Urbanspoon will randomly pick a place for you, if you don't like it, shake it again!

Tie: Pandora and Last.fm
Both of these applications do very similar things. Based on the same technologies of their respective web sites, you can get a customized radio station based on your music tastes. Pandora is based on the Music Genome Project, which uses a more scientific approach to matching tunes. Last.fm relies on social networks and listening patterns to do something very similar. I am a Last.fm user, so I like this app for that reason, however, I believe Pandora streams much more reliably with less waiting for buffering.

Monday, June 9, 2008

WWDC 2008 Keynote

I got to attend the Apple Worldwide Developers Conference 2008 keynote this morning, it was a lot of fun. Luckily for me I didn't have to get there at 6am like my colleges who held a spot for me. I got to see Steve Balmer speak at Mix '08 back in March, he was good, but doesn't hold a candle to watching Mr. Jobs.

On the left is a picture I took from line, so may nerds, myself included.

Sunday, June 1, 2008

TripIt - One of My Favorite Tools

I tend to fly fairly often (at least once a month). I have been using TripIt for a few months now and I'm a big fan. TripIt helps you track your travels very easily. All you do is forward your email confirmations for your flights, hotels or rental cars and TripIt will consume the information and keep all your travel information in one handy place. That combined with the ability to subscribe to your trip details via an iCal feed, as well as a new mobile site that looks great on the iPhone, make it a great tool for any frequent traveler.

Monday, May 19, 2008

ReSharper 4.0 Nightly Build Finally Stable?

My all time favorite add-on for Visual Studio, ReSharper, has finally marked one of their nightly builds for the upcoming 4.0 version as "Stable". This is good news since 4.0 brings support for Visual Studio 2008 and the new .Net 3.5 language features such as LINQ, Extension Methods and Automatic Properties. ReSharper has become a tool that I find hard to live without and I have been using the nightly builds for the last couple months. For the most part they have been good but I'm hoping this means they will have a final release soon, originally they promised the release to be in mid-Februrary.

[UPDATE]: Looks like they have finally launched the beta for 4.0, get it here.

[UPDATE 6/26/2008]: Hooray, the final version was released last week, get it here.

Sunday, May 4, 2008

Maker Faire 2008

Today I attended the Bay Area Maker Faire 2008. Over all it was an entertaining trip, except for the hour we sat on the onramp to get to the fairgrounds. I got to see Adam Savage of the Mythbusters speak, as well as enjoy a couple rounds of Battle Bots. And for your viewing pleasure, here are some Battle Bot videos taken with my new Flip Video camera.



Tuesday, April 29, 2008

New Date and Time Data Types in SQL Server 2008

I am delinquent in the one-a-week challenge post for last week, and on top of that this is going to be a pretty lazy one, as I'm just going to refer to a good article I just found.

My current client has taken to early adopting the latest SQL Server 2008 CTP. One of my favorite new features are the enhanced date and time data types. Dinesh Asanka has a good summary of these new types over at SQL Server Performance and you should really just go check out his article.

My favorite additions are the DATE and TIME data types, how many times have you wanted to just specify a date or time portion of a value and had to do some sort of crazy truncation or logic in code to keep it straight? Well no longer.

Another great addition is the DATETIME2 data type, though its not going to win any awards for clever naming, the gist of it is that you now can specify the millisecond resolution of your DATETIME, previously it was defaulted to 3 decimal places, now you can specify from 0 to 7.

Sunday, April 20, 2008

TFS Blog Series: Setting Up Projects

Welcome to the second entry in Joel and my series on Microsoft Teams System (aka Team Foundation Server, aka TFS). To catch up, check out the previous entries in the series:
  1. Overview
In this post I'm going to cover the details of creating a new team project including the intricacies of setting up project permissions and permissions for the corresponding SharePoint and Reporting Services.

Creating a New Project

Creating a new project in TFS is pretty straight forward and involves the following steps:
  1. Launch Team Explorer (Visual Studio).
  2. In the Team Explorer toolbox, right click on your server name and choose "New Team Project...".
  3. In the wizard, give your project a proper name and description. You can name a project anything you want, but you should give some thought to this before committing to something because you cannot change this once the project is created. If you work in an organization like ours where you have many projects, a consistent naming convention is important. We use {ClientName}.{ProjectName}, so for this test I will create a project called Slalom.Test, Slalom because it is an internal project so we are our own client and Test because I'm just going to delete this thing when I'm done.

  4. Choose a project template. TFS comes with two built in, however you can create your own custom templates as well, allowing you to have some pre-canned work items generated for every project you create. We'll talk about template customization later in the series, for now we will just choose Agile.

  5. Choose where you want your source control, by default TFS builds out a new repository, in most cases this is what you will want to do.
  6. Once you click finish and let TFS build out your project you will have a new project listed in Team Explorer.

Setting Project Permissions

TFS allows you apply roles to your different users, these roles can be adjusted by right clicking on your team project and choosing "Team Project Settings > Group Membership..."





For a project, there are four groups available for classifying your users rights:
  1. Readers - Users that can access the project, but are not able to modify work items or check in code.
  2. Project Administrators - Users that can do anything within the project.
  3. Contributers - Users that can make changes in the project but are now allowed administrative tasks.
  4. Build Services - System role for building the project (for service accounts only).
Most people generally fall under project administrators or contributors.

Setting SharePoint and Reporting Services Permissions

Unfortunately setting permissions within TFS does not complete the process. Permissions must also be granted individually to the corresponding SharePoint site and SQL Server Reporting Services.

For SSRS permissions, we have simplified this by creating a Team Foundation Server Users domain group and putting all valid TFS users into that group, then giving that group read permission on the reporting server. This saves us from having to set these permissions each time.

For SharePoint we still must grant users proper access, do this follow these steps:
  1. Access your project portal (right click on your project and choose "Show Project Portal...") as an administrator.
  2. Choose "Site Settings" from the "Site Actions" drop down on the site.
  3. Choose "Advanced Permissions" from "Users and Permissions".
  4. Choose "New" to add your users and give them specific SharePoint permissions.



Sunday, April 13, 2008

Bad Dog

Well, this post is a little bit of a cop-out, but I'm still counting it for the "one a week" challenge. Next week I will get part two of Joel and my series on TFS out.

My mom called me this morning, she was upset because her dog jumped up and grabbed her iPhone off the kitchen counter in the middle of the night, and pretty much destroyed it. It will power on, but the screen is completely white. When I plugged it in, it did sync, so we were able to get her a new one and restore from the backup. Check out the photos below:







Tuesday, April 1, 2008

My First "Valley" Event

Well as a follow-up to my last post about how Seattle compares to The Valley last night I attended my first "Valley" event. A friend of mine that works for a PR firm down here told me about Mozilla's 10 year anniversary celebration that was going on last night. So I decided to check it out. It was pretty packed when I got there, but they had just made it open bar, so thanks Mozilla for the gin and tonics. There were a lot of .com folks chatting it up, a few folks that were clearly Mozilla contributors and a few valley celebrities (or so I'm told, I didn't really know who any of them were). At one point Mitchell Baker (I think) and Brendan Eich got up and thanked everyone and said some words that most of us couldn't hear. All-in-all it was an interesting experience and I hope to find my way into more of these things.

UPDATE: Here is proof that I was there, or at least that the back of my head was: http://valleywag.com/photogallery/mozilla10/1001073788

Sunday, March 30, 2008

The Valley vs. The Emerald City

I don't know, how about we call this one an opinion piece. So the New York Times published an article about how Seattle is becoming the next Silicon Valley. Glenn Kelman of Redfin then commented on it favorably. Then TechCrunch's Michael Arrington disagreed. And now the rest of the world is throwing in their two cents. So I thought, why shouldn't I add my thoughts to the ether.

I spent the better part of the last 5 years working in Seattle as a software developer. In August I transfered to our San Francisco office for a change of scenery. I can't claim any real insight from a start-up perspective. I have friends who have done start-ups, I've consulted for start-ups, but I've never been a part of starting my own, and I may never, who knows.

I have a hard time believing that your likelihood of success can so be so heavily weighted by your location. Sure, being in Silicon Valley, amidst all the others can have its advantages, especially when it comes time to start raising money or recruiting new talent. But good ideas can come from anywhere, be it Stanford or rural Saskatchewan.

If you take a look at my Shelfari reading list on the right (a Seattle based start-up that one of my good friend's from college help found) you'll see I am in the middle of reading "Founders at Work". I find this book to be pretty interesting, and one of the most interesting things I have pulled from it is that you don't have to be in Silicon Valley to succeed. Sure a lot of the companies profiled are based in the valley, but certainly not all of them, and the ones that weren't don't seem to have been at a disadvantage because of it. Their keys to success are having a good idea and having smart, motivated people making that idea reality.

You can live in San Francisco and try to start as many Twitter and Digg clones as you like, good luck with that. But its the next big thing that matters, and that can come from anywhere.

Saturday, March 22, 2008

Learning Cocoa

With the recent release of the iPhone SDK I've gotten pretty excited about trying my hand at building some custom iPhone applications. Since I pay the bills writing software using Microsoft technologies I rarely write anything that isn't in C# these days. I took plenty of C and C++ centric courses in college, but frankly I've gotten rusty.

Coding for the Mac and the iPhone means working with Apple's Cocoa libraries which is done in Objective-C, a language I have never spent any time with, in Xcode, an IDE I've probably opened a handful of times but never built anything in.

So in the last week or so I've been doing a lot of reading on both of these subjects. Like most things there is a wealth of information out there that can be found with a simple Google search. In my hunting I've found a couple of resources for Cocoa, Objective-C and Xcode that I found to be the most helpful:

Programming Mac OS X with Cocoa for beginners

Programming Mac OS X with Cocoa for beginners is a book I found on Wikibooks. This source does a good job of explaining what Cocoa and Objective-C are and especially does a good job explaining some of the unique syntax of Objective-C that at first glance might make someone who is familiar with C, C++ or C# rub their eyes in an comically exaggerated manor indicating bewilderment.

Long Pointers - Xcode 3.0 Tutorial

The Xcode 3.0 tutorial on the Long Pointers blog does a great job of walking you through how you would build a windowed application in Cocoa with the Xcode tool. It is specifically very good at outlining how you build the interface in Interface Builder and wire it up to your controller code.

I am still early in my journey to become a Mac developer, but these resources definitely helped me feel like I am moving forward as I learn more. I'm sure there are more Mac and iPhone development posts coming in the future.

Friday, March 14, 2008

What is ALT.Net

One of the bloggers I follow regularly in the .Net community is Jeremy D. Miller. I have used his post on the model view presenter as a reference many times when explaining the pattern to developers who have not yet been exposed to it.

Jeremy has an article on the back page of March's MSDN magazine explaining what ALT.Net is. It's a very concise and informative explanation. The tenets of being an ALT.Net developer that he digs into more detail are:

  1. You're the type of developer who uses whatever works while keeping an eye out for a better way.
  2. You reach outside the mainstream to adopt the best of any community.
  3. You're not content with the status quo.
  4. You realize that tools are great, but they only take you so far.

After just getting back from Mix '08 it is really encouraging to see Microsoft begin to embrace the ALT.Net community by doing things like hiring Scott Hanselman and creating the ASP.Net MVC framework.

My IDataRecord Extension Methods

I decided it was high time I did a post with some actual code samples in it, so here we go.

I am really enjoying some of the new C# 3.0 language features, one in particular is extensions methods. If you are not yet familiar with extension methods, ScottGu has a good overview. I want to highlight some specific extension methods I've created for IDataRecord that I think are extremely handy, especially when you spend a lot of time working in the data layer with DataReaders like I do. I feel like I've written variations on the same data layer 100 times. Every time it evolves, when I went from .Net 1.1 to 2.0 I took heavy advantage of generics. Now in .Net 3.5 I am simplifying it even more with extensions.

When working with DataReaders you might often have a ton of code that looks like this:


string myString = record.GetString(record.GetOrdinal("MyField"));


Where record is an IDataRecord coming from a SqlDataReader or something similar. Now that's not a terrible line of code, but it gets pretty annoying typing record.GetOrdinal all the time. So to save me that annoyance I've added the following to my IDataRecordExtensions class:


public static long GetString(this IDataRecord record, string field)
{
return record.GetString(record.GetOrdinal(field));
}


An now all I have to call in my record handling code is this:


string myString = record.GetString("MyField");


Not ground-breaking, but better, and you can write an extension for all the types you are getting data for. Here's a better example of how extension methods for your IDataRecord can be more useful. Sometimes you might be dealing with a nullable type, IDataRecord doesn't handle this too gracefully, you end up having to write code that looks something like this:


string myString = null;
int ordinal = record.GetOrdinal("MyField");

if(!record.IsDBNull(ordinal))
{
myString = record.GetString(ordinal);
}


Again, not a ton of code, but if you have to do this hundreds of times it's going to get annoying and you are going to make mistakes. Now check this out, in my IDataRecordExtensions class I add the following two methods:


private static T GetNullable<T>(IDataRecord record, string field, Func<int, T> func)
{
T result = default(T);
int ordinal = record.GetOrdinal(field);

if (!record.IsDBNull(ordinal))
{
result = func(ordinal);
}

return result;
}

public static String GetNullableString(this IDataRecord record, string field)
{
return GetNullable<string>(record, field, x => record.GetString(x));
}


OK, what the heck is going on here. Lets look at GetNullableString first. This is an extension method for an IDataRecord that takes a field name and then calls this private GetNullable method. Check out that third argument though. In GetNullable its defined as Func<int, T> func. What we are doing is taking advantage of lambda support in C# 3.0 and we are saying, pass me a function that takes an int and returns me a generic T, and in this case T is a string. x => record.GetString(x) is saying passing the record's GetString method as that parameter. Now in our data handling code we can just write:


string myString = record.GetNullableString("MyField");


Nice. What's even better, is now we can easily add other extensions for other more interesting nullable types, such as double by adding code like this to the IDataRecordExtensions class:

public static double? GetNullableDouble(this IDataRecord record, string field)
{
return GetNullable<double?>(record, field, x => record.GetDouble(x));
}


So there you go. Hopefully my experiences with extension methods and IDataRecord are helpful to others.

One a Week Challenge

Joel and I were talking about ways to give ourselves more incentive to blog more. We decided on a friendly challenge that would require us to both post at least once a week. You can read Joel's post for this week highlighting Silverlight 2 from our recent trip to Mix '08. Don't worry Joel, I'm not counting this as my post for this week, check back later for my "real" post.

Sunday, March 9, 2008

Back from Mix '08

I attended the Mix '08 conference in lovely Las Vegas last week. Mix is Microsoft's conference for discussing and launching web technologies held at the Venician Hotel and Casino.

The opening keynote by Scott Guthrie (who's blog I recommend subscribing to) was pretty good. There were two primary announcements:

Silverlight 2

At Mix '07 Microsoft launched Silverlight, their competitive technology to Adobe's Flash. This year they launched Sliverlight 2 Beta 1 during the keynote. Not having ever worked with Silverlight 1 I cannot speak with much authority on the subject. I can say that the demos were impressive, especially the Hard Rock Memorabilia Deep Zoom demo. In addition, my colleague Than, who has been working with Silverlight 1 for the last year, informs me that the 2.0 release is an enormous improvement on the prior version.

Internet Explorer 8

Also during the keynote Microsoft launched Internet Explorer 8 beta. I did not expect to care much about this announcement considering my primary browser has been Firefox for years now, even before I made the move to the Mac. However, my tune quickly changed as they demoed the new version. Having been a web developer for many years now, I have come to accept the constant battle with browser compatibility. I was not prepared for their first demo to involve a basic CSS styled site, being shown in Firefox. The site looked fine, and then the speaker switched to Safari and again, it looked just fine. Then he switched to IE 7, and a giant red square appeared on the page, obviously highlighting a standards compatibility issue that IE has had for ages. And finally, he switch to IE 8, and the sight looked just like it did in Firefox and Safari. I am truly impressed with Microsoft's acceptance of the fact that yes, they are not standards compliant, and one of their major goals in IE 8 is to fix that. This feels like a complete 180 from the Microsoft of the past, and it is a welcome change in my opinion. The rest of the IE 8 demo was pretty good as well. They showed off built in development tools that should make anyone's life much easier as we all continue to build sites that must work across various browsers.

I attended a couple of session that I found to surprising as well.

Developing Data Driven Web Applications Using ASP.Net Dynamic Data

I walked into this session not really knowing what I was about to see. The presentation was about how Dynamic Data allows you to generate a UI scaffolding based on your data model for instant CRUD based UIs, sound familiar? It should, this is clearly Microsoft's answer to Ruby on Rails, or at least part of it. What they demoed was fairly good and comprehensive, and moreover, it wasn't being pushed as the end-all-be-all of frameworks as MS is known to do, but rather as yet another option in your ASP.Net arsenal. This again, is not not something I would have expected to hear out of the Microsoft of the past.

The ASP.Net MVC Framework

By far my favorite presentation was Scott Hanselman's session on the new MVC framework for ASP.Net. This was true for a couple of reasons, the first being that Scott is a truly engaging and entertaining speaker, which is a pretty impressive feat when you consider the content and audience. Secondly I enjoyed it because again, this framework was not being pushed as a replacement of anything, but rather another alternative. MVC makes up the second piece of competing with the Ruby on Rails framework, with the model-view-controller architecture becoming baked into the tools. It is still in its early stages, but looks very promising. I have been doing a lot of iPhone web application development lately, and one of my biggest issues is keeping may page size small. Due to the MVC framework's natural lack of your standard viewstate/postback architecture, it seems to me that the views you generate can be much more easily optimized for a device like the iPhone that can handle full HTML, but may sometimes be limited by bandwidth.

Overall I had a blast at Mix. Thanks Microsoft for hosting the party at Tao in the Venician, I can't imagine what the bar bill looked like for that.

The NGChart Project

In a previous post I mentioned that I was beginning work on a .Net library for wrapping the new Google Chart API. As it turns out, a couple of other people had the same idea. Today I joined the NGChart project on Google Code in order to help enhance this existing library. I was able to easily integrate it into my current project, I urge you to check it out if you need a simple way to add basic charts to your web projects.