First time here? Check out the site's "greatest hits" or read a post from the archives. Feel free to leave a comment or ask a question, and consider subscribing to the latest posts via RSS or e-mail. Thanks for visiting!

I posted the month before last that the Mix08 Sessions, mine included, were up and available at http://sessions.visitmix.com. I posted links to the MP4, WMVs and other downloaded versions at the time as well. The Silverlight versions were the same versions, so there wasn't really a compelling reason to use Silverlight.

What I didn't know, however, is that they (the powers that be) not only recorded the slides and demos, but also had cameras going at the same time. They did some post processing (on hundreds of sessions) and those new "dual stream" sessions are up and available online in Silverlight. One stream is a camera on me, and one is the slides and demos.

I'm fairly physical, so I really prefer my talks if you can see me. If you haven't seen the MVC talk before, you might enjoy watching this new version. You can see a screenshot below. If you click the screenshot you'll go directly to the site.

image

UPDATE: It looks like the servers are having trouble keeping up, but they're working on it. For now, don't select a chapter or you might be in for a wait. If the streams start, for now you'll just have to watch it straight through until they've fixed it. It's working well for me if you just let it play.



The Beta of .NET 3.5 and VS2008 SP1 is out. I'm sure everyone is blogging the heck out of it, so I'll try to add my own specific kind of value. There's fixes, many improvements (some subtle, some dramatic), and some new technology.

Should You Fear This (Beta) Release?

Maybe a little bit. Don't be afraid of the new assemblies or the bug fixes, I have found them to be very good and have no stability problems, but this Service Pack Installer might cause you some trouble in this beta, especially if you already have beta stuff installed over the top of VS2008RTM (the original version). It'll be correct when it releases later this summer.

Now, if you're going to decide to install a Beta of a Service Pack, do read the ReadMe and ScottGu's post. Go ahead, I'll wait here. OK, if you're already running some beta stuff, like the Silverlight Tools for Visual Studio, you'll want to uninstall that FIRST, otherwise you'll get an error and be upset. This will also be figured out when the SP actually releases, but be warned.

In this release, I have found the Progress Bar is wonky on XP and 2k3. It might say failed, and then succeed. Watch for the final message, not the bar. This will be fixed. Be aware also that it can be a long-ass install so get a coffee and pillow.

On the developer side, this is much more than just a "tightening of the screws" release, as it also kind of breaks a few rules and introduces some new stuff I've been personally waiting for.

What's New?

video-292ASP.NET Dynamic Data, ADO.NET Data Services ("Astoria"), ADO.NET Entity Framework (LINQ to Entities) are all additive. ScottGu has an extensive post detailing all the interesting bits.

Here's my explanation on ASP.NET Dynamic Data and why you might care. I've been doing talks around on ADO.NET Data Services, sharing my thoughts on how its RESTfulness relates to ASMX/SCF Web Services and WS-*.*, and I'm going to dig deeper into it this year because I think it's pretty sweet, especially if Ayende and I (mostly him) get it running over NHibernate. The ADO.NET Entity Framework can be plugged in underneath both ASP.NET Dynamic Data and ADO.NET Data Services, so taken as a whole, the data story is starting to be a lot clearer and more useful and I'm continuing to work/push for all this stuff over POCO (Plain ol' CLR Objects) whenever possible and/or appropriate.

For this release I've personally recorded seven (whew!) How-To Videos on ASP.NET Dynamic Data and the Dynamic Data Samples can be downloaded here. They videos and samples are short, sweet and to the point. I'm also hoping to do more integration-style videos showing all this stuff working together in something of a larger context.

There's also a bunch of fixes like VS2008 starts faster and the IDE is snappier in spots, the WPF Designers are beefed up, and a bunch of editor/designer bugs have been squashed.

Don't Mess With My GAC, Dude!

UPDATE: Patrick Smacchia, who certainly knows his product better than I, has posted a follow up with more detailed information about what's changed in .NET 3.5 SP1.

On the .NET 3.5 side of things, since this is an SP (Service Pack), yes, some stuff goes in your GAC and gets changed. However, the changes are completely additive. That means if an API's method signature has changed, that's a bug that we need to fix. It will be a fully compatible service pack release. It shouldn't break any of your existing code.

There's roughly 50 new or modified types throughout or about 80 to 100 if you count Dynamic Data. On the WPF side, there's a bunch of new stuff in System.Windows.Effects that will make WPF people happy. There's a new WebBrowserControl in System.Windows.Controls that's like "whew! about time!" as well as new DataBinding support in System.Windows.Data.

When folks tell me that things have changed, I personally don't always take their word for it, and would rather dig in and find out for myself what's changed in what assemblies.

As far as I know there are four major tools for doing Assembly Differences (some have been added since I blogged about Assembly Differences last year):

  • Libcheck - Over three years old, obscure, command-line, confusing, but still useful. I used this when diffing .NET 2.0 and 3.5 a while back.
  • Framework Design Studio - A recent tool by Krzysztof Cwalina, a personal hero of mine, along with his helpers Hongping Lim and David Fowler, it has both a GUI and a command-line option.
  • BitDiffer - This new tool from Greg Ennis is very polished and includes both a GUI and Command Line version. If it supported drag-and-drop it'd be even better. Unfortunately it crashed while I was trying to diff these assemblies.
  • NDepend - Last, but not least, a favorite tool of mine that I've blogged about and podcast about has been dramatically updated to do Assembly Diffs as well in a very cool way. The tool is very polished and lets you compare projects, dlls, supports drag and drop and is generally polished and wonderful, so I ended up using this tool.

So, Libcheck is frustrating, FDS is close, but only creates a text-based report on what's changed, BitDiffer crashed, and while NDepend does have some weird painting issues, but I was able to create this diagram with NDepend:

WhatIsNewInVS2008SP1

Here's a close up (you can get the whole picture by clicking on it). In this example I was hovering over a method that was blue, and got a tooltip indicating that a method has changed in that type.

image

I created the graphic by getting the DLLs from the GAC on a .NET 3.5 machine and the DLLs from a .NET 3.5 SP1 machine. Then I put them in two different folders on a machine that *did not have .NET 3.5 on it* to avoid any wackiness. Then I ran this Code Query Language (CQL) query:

SELECT METHODS WHERE CodeWasChanged

The results of that query were displayed in a number of ways, the most interesting one being the Metrics View. I set the metric to show the # of methods. In this example, 1 method = 104 pixels. Blue methods are CHANGED methods. Then I took 2 screenshots while scrolling horizontally and stitched them together in Paint.NET.

You'll see when you look at the diagram that there's some fixes here and there, but from a visual 20,000 foot view, perspective, nothing major that looks like more than bug fixes or smells of a systemic issue. Focusing on the Bug Fixes, it's onesy-twosy, bug fixes within a method here and there. The complete list of fixes is here and here.

BTW: I'm a huge NDepend fan, but I'm not associated with company at all, other than being a fanboy.

My Conclusion

Now that you've been both educated and warned, if you're not willing to wait a bit, you can download the VS2008 SP1 BETA here. Remember, this is a BETA of a Service Pack, so I'm personally continuing to install only on Virtual Machines that have VS2008 RTM.

If you have anything Beta that's layered on top of VS2008, like the Silverlight Tools, or something like that, back those off first, before installing this SP, and again, read the readme, as most known to-be-fixed issues are called out there already.

As ScottGu says:

"It will be a fully compatible service pack release.  We plan to ship the final release of both .NET 3.5 SP1 and VS 2008 SP1 this summer as free updates. "

So I'm feeling good about the final release later this year. But, for this beta, I don't want to take any chances with installer issues so it just seems prudent that I keep my primary machine on the initial version of VS2008/.NET3.5 until this SP1 is released. Have fun!

Related Links

Technorati Tags: ,,


I've been getting more and more interested in how folks extend their applications using plugins and things. In my new ongoing quest to read source code to be a better developer, Dear Reader, I present to you twenty-sixth (half a year!) in a infinite number of posts of "The Weekly Source Code."

Sometimes when I read code, I kick myself (mentally) and say "Man, I should have thought of that!" Then I realize I'm not nearly as good a programmer as I think I am, and then I just let the source just wash over my brain.

Here's some source by smart people I've been reading this week that I should have thought of. ;) Coincidentally they are both examples of languages ported or re-imagined in another language.

"Processing" in JavaScript

When I say "Processing" I mean the open-source Java-based visualization language from http://processing.org/. Jeff calls it "more akin to sketching than coding" while I say it's sketching with code! Jeff yearns: "for the day when web pages are regularly illustrated with the kind of beautiful, dynamic visualizations that Ben Fry creates."

molten2

Well, John Resig, arguably already considered one of the best JavaScript coders on the planet after he gave us the tour de force that is JQuery, has ported Processing to Javascript and gives us Processing.js.

You can interact with it in two ways. First, as an elegant and tight Javascript API:

var p = Processing(CanvasElement);
p.size(100, 100);
p.background(0);
p.fill(255);
p.ellipse(50, 50, 50, 50);

Or, you can tunnel the actual Processing language like this:

Processing(CanvasElement, "size(100, 100); background(0);" + "fill(255); ellipse(50, 50, 50, 50);");

clockThis release is specifically targeted to Firefox3, Opera 9.5 and the Webkit Nightlies (Safari) - all unreleased, beta browsers. I'm going to try it under the DLR with Javascript in Silverlight. Heh heh.

Here are his demos. Remember, these don't work in IE7.

There's a load of demos, but here's a powerful one. A working clock in 17 lines of code.

void setup() {
size(200, 200);
stroke(255);
smooth();
}
void draw() {
background(0);
fill(80);
noStroke();
// Angles for sin() and cos() start at 3 o'clock;
// subtract HALF_PI to make them start at the top
ellipse(100, 100, 160, 160);
float s = map(second(), 0, 60, 0, TWO_PI) - HALF_PI;
float m = map(minute(), 0, 60, 0, TWO_PI) - HALF_PI;
float h = map(hour() % 12, 0, 12, 0, TWO_PI) - HALF_PI;
stroke(255);
strokeWeight(1);
line(100, 100, cos(s) * 72 + 100, sin(s) * 72 + 100);
strokeWeight(2);
line(100, 100, cos(m) * 60 + 100, sin(m) * 60 + 100);
strokeWeight(4);
line(100, 100, cos(h) * 50 + 100, sin(h) * 50 + 100);
}

His code leans heavily on the Canvas which is why IE7 doesn't work. Much of the processing.js file is mapping from one API (the processing API) to Javascript constructs, usually canvas ones. For example, making a point(x,y) is:

  p.point = function point( x, y )
{
var oldFill = curContext.fillStyle;
curContext.fillStyle = curContext.strokeStyle;
curContext.fillRect( Math.round( x ), Math.round( y ), 1, 1 );
curContext.fillStyle = oldFill;
}

Note the rectangle that is 1 by 1. That's funny, but that's the life an API mapper. Remind me someday to tell you, Dear Reader, how I got filled pie charts working on an Original Palm Pilot that not only didn't support Put/GetPixel but didn't have floating point math. That was a hoot.

Anyway, one really good example of this guy's clean cleverness is the triangle function. Remember, this is a processing function and he's not only got to implement it, but also make the building blocks for doing it cleanly.

To start:

  p.triangle = function triangle( x1, y1, x2, y2, x3, y3 )
{
p.beginShape();
p.vertex( x1, y1 );
p.vertex( x2, y2 );
p.vertex( x3, y3 );
p.endShape();
}

Obvious, right? Well, not really, considering that the 2D Canvas doesn't have any of those three higher-level methods. Begin and EndShape are fairly clean. However, he had to implement a nice Fill, Stroke and ClosePath to do this cleanly.

  p.beginShape = function beginShape( type )
{
curShape = type;
curShapeCount = 0;
}

p.endShape = function endShape( close )
{
if ( curShapeCount != 0 )
{
curContext.lineTo( firstX, firstY );

if ( doFill )
curContext.fill();

if ( doStroke )
curContext.stroke();

curContext.closePath();
curShapeCount = 0;
pathOpen = false;
}

if ( pathOpen )
{
curContext.closePath();
}
}

It's about four layers deep, each primitive building on the next until he gets a nice clean triangle implementation, but then he can use it for quad() and it the same method handles bezierVertex as well. It would do you well to FireBug your way through his code. It's a wonderful fun way to re-learn Javascript from a gentleman who knows what he's doing.

LINQ to RegEx and Fluent Regular Expressions

I was trying to re-re-re-learn Regular Expressions again this week for a small task. It's funny how Regular Expressions are the first thing to leave my brain even though there are a bunch of Regular Expression Tools out there. Josh Flanagan came up with a Fluent Interface for Regular Expressions like:

Regex socialSecurityNumberCheck = new Regex(@"^\d{3}-?\d{2}-?\d{4}$");

would look like this:

Regex socialSecurityNumberCheck = new Regex(Pattern.With.AtBeginning 
.Digit.Repeat.Exactly(3)
.Literal("-").Repeat.Optional
.Digit.Repeat.Exactly(2)
.Literal("-").Repeat.Optional
.Digit.Repeat.Exactly(4)
.AtEnd);

It took me a second to like this. OK, it took me a while. Breathe for a minute, and read it out loud. It kind of makes sense, actually, although there is a reasonable argument against in the comments of Josh's post:

[It] strikes me that a user of this library needs to learn a fairly complex syntax which is almost as far from "plain english" as regex, when they could simply learn how to do regex.

Sure, but it's fun to try new things. If you look a his source, it's really just a really smart string concatenator. I think it would actually be a very interesting way to teach or learn regular expressions, especially if you're a casual RegEx'er like me.

Krzysztof Koźmic created a similar API in 2007. His fluent interface over RegEx looks like this:

Pattern pattern = Pattern.Define().
As("Kot".Count(Times.AtLeast(2))).
FollowedBy(Any.Except('a','b','c')).
Start(At.BeginingOfStringOrLine);

Then Roy Osherove took Josh's API further and took Josh's Fluent Interface to RegEx from 2006 and applied a LINQ query syntax , creating in the process, LINQ to Regex.

Here's Roy's example:

public void FindEmailUsingPattern()
{
var query = from match in
RegexQuery.Against("sdlfjsfl43r3490r98*(*Email@somewhere.com_dakj3j")
where match.Word.Repeat.AtLeast(1)
.Literal("@")
.Word.Repeat.AtLeast(1)
.Literal(".")
.Choice.Either(
Pattern.With.Literal("com"),
Pattern.With.Literal("net"))
.IsTrue()
select match;
foreach (var match in query)
{
Assert.AreEqual("Email@somewhere.com",match.Value);
}
}

After the "from match in", the simple heart of it is Roy's static Against() call that returns a RegexQuery that is IEnumerable of Match, thereby supporting the foreach later on:

namespace Osherove.LinqToRegex 
{
public class RegexQuery : IEnumerable
{
private readonly string input;
private object lastPatternRetVal;
private RegexQuery(string input)
{
this.input = input;
}
public static RegexQuery Against(string input)
{
return new RegexQuery(input);
}

private string _regex;
public RegexQuery Where(Expression<func><pattern,bool> predicate)
{
_regex = new PatternVisitor().VisitExpression(predicate).ToString();
return this;
}

public RegexQuery Select<t>(Expression<func><pattern,t> selector)
{
return this;
}
#region IEnumerable Members

IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)this).GetEnumerator();
}

public IEnumerator GetEnumerator()
{
MatchCollection matches = Regex.Matches(input, _regex);
foreach (Match found in matches)
{
yield return found;
}
}
}
}

You can find all the source for Roy's project up at his assembla.com project site and Josh's source is on his blog. It is worth noting, though that you can combine LINQ Queries with Regular Expressions without any tricks because Matches are returned in a MatchCollection an LINQ loves things that are IEnumerable.

You can use LINQ projections to pull objects out of a collection of matches like:

    List<yourType> = (from Match m in matches
select new YourType
{
Id = m.Groups[1].Value,
Something = m.Groups[2].Value
}).ToList();

So, we've got two sides of the coin here. First, the creation of the Regular Expression. That can be the standard way, or with a fluent interface. Either way, you end up with a string. Second, you've got the extraction of the information. Most often you'll care about the MatchCollection that comes back. You'll usually want to pull information out, so while you're foreach'ing your way over the collection, you can use LINQ to create an object projection that's chopped up and sorted and grouped all with one query, regardless of how you created the query in the first place.

Choice is good.



While reading source today, I saw some code in the wild today that looked roughly like this (not the actual code):

type = typeof(T);
if (type == typeof(Boolean))
{
returnValue = (T)((object)Convert.ToBoolean(value));
}
else if (type == typeof(String))
{
returnValue = (T)((object)value);
}
else if (type == typeof(Int16))
{
returnValue = (T)((object)Convert.ToInt16(value));
}
else if (type == typeof(Int32))
{
returnValue = (T)((object)Convert.ToInt32(value));
}
//...and on and on for a dozen+ types

You get the idea. This isn't that uncommon, I've seen it more of than not. The person who is writing it usually knows it's bad 50% of the time, but it's always a trade-off between figuring out the right search query (a tough one, in this case!) and knowing what to look for in MSDN.

This brings up one of my favorite classes in the BCL, the TypeDescriptor class. A method like this:

public static T GetTfromString<T>(string mystring)
{
var foo = TypeDescriptor.GetConverter(typeof(T));
return (T)(foo.ConvertFromInvariantString(mystring));
}

...would allow all that switch/if/else to go away replaced by:

bool b = GetTfromString("true");

You'd probably want to expand the method with checks to see if T was in fact, System.Type, or System.String, but you get the idea.

image There are lots of standard converters like EnumConvertor, ColorConvertor, and more, all waiting for you in System.ComponentModel as seen in the image at right.

Not only that, but you can make your own TypeConverters and spread the love. They are used extensively when displaying types in Property Grids, in WinForms, or in XAML. You can also use them in PowerShell as a better way to present your objects as strings when "casting" in PowerShell.

Jesse Liberty has a fine example showing how to use Type Convertors in Silverlight to enable you to put complex types in XAML attributes.

From MSDN:

To implement a simple type converter that can translate a string to a [Type]

  1. Define a class that derives from TypeConverter.

  2. Override the CanConvertFrom method that specifies which type the converter can convert from. This method is overloaded.

  3. Override the ConvertFrom method that implements the conversion. This method is overloaded.

  4. Override the CanConvertTo method that specifies which type the converter can convert to. It is not necessary to override this method for conversion to a string type. This method is overloaded.

  5. Override the ConvertTo method that implements the conversion. This method is overloaded.

  6. Override the IsValid method that performs validation. This method is overloaded.

That's it, and when that Type was decorated with an attribute like:

[TypeConverter(typeof(MyNewTypeConverter))]

Then that new TypeConverter would be picked up and used by the line of code I showed before. Much better than a switch or pile of if/elses, I think.



When I came to Microsoft I saw a really cool tool being used internally and immediately wanted to work with the author, Rocky Downs (who is blogless, but exceeding talented), to get it released. Fast forward to now, plus an installer, and here it is.

The basic (as in "only") idea is that RockScroll extends the scrollbar in Visual Studio to show a syntax highlighted thumbnail view of your source. This is really useful for those excessively long source code files you know you have. It's just one DLL and you can turn it off from Tools|AddIns just by un-checking the checkbox.

Enjoy!

RockScroll

works-on-my-machine-starburst Works On My Machine Disclaimer: This is released with exactly zero warranty or support. If it deletes files or kills your family pet, you have been warned. It might work great, and it might not. It hasn't been tested against the myriad of other VS Add-Ins, but it works on my machine in both VS2005 and VS2008. It does look a little odd next to Resharper, a tool that also adds a scrollbar. Good luck.



My one-hundred-and-tenth podcast is up. This episode was recorded at the ALT.NET Open Spaces Conference in Seattle a few weeks back. I got to sit down with two gentlemen from Microsoft Research, Mike and Rustan, and talk about Spec# after their presentation at the conference.

What's Spec#? Currently it's a new language that is essentially extensions to C# 2.0. For example:

class ArrayList { public virtual void Insert(int index , object value)
requires 0 <= index && index <= Count;
requires !IsReadOnly && !IsFixedSize;
{ . . . }

See all that new stuff BEFORE the first curly brace? That's where you specify preconditions that you want enforced. You can also specify postconditions:

ensures Count == old(Count) + 1;
ensures value == this[index ];
ensures Forall{int i in 0 : index ; old(this[i]) == this[i]};
ensures Forall{int i in index : old(Count); old(this[i]) == this[i + 1]};

There's LOTS more, including a pretty extraordinary static analysis that runs in the background, kind of like the grammar checker in Word. Word has the spelling checker that turns errors red with squiggly underlines, and the grammar checker that turns grammatical errors green with squiggly underlines. Spec# will turn static errors into squiggles while you type.

They've even added specifications for the Base Class Library (BCL) that have previously only existed in documentation.

UseMscorlibContracts - Microsoft Visual Studio

BTW, if you want to see horribly shaky cellphone video of their presentation, you can see it at Greg Young's blog. He's posted recently about Spec# as well. If you don't like videos or podcasts, you can also read the Spec# Research Paper (PDF).

How can you get involved? We need to convince that folks on the C# team that Spec# is a valuable thing and that we'd like it sooner than later. Go over to Charlie Calvert's blog and email him that you want Spec# and why!

Subscribe: Subscribe to Hanselminutes Subscribe to my Podcast in iTunes

If you have trouble downloading, or your download is slow, do try the torrent with µtorrent or another BitTorrent Downloader.

Do also remember the complete archives are always up and they have PDF Transcripts, a little known feature that show up a few weeks after each show.

Telerik is our sponsor for this show.

Check out their UI Suite of controls for ASP.NET. It's very hardcore stuff. One of the things I appreciate about Telerik is their commitment to completeness. For example, they have a page about their Right-to-Left support while some vendors have zero support, or don't bother testing. They also are committed to XHTML compliance and publish their roadmap. It's nice when your controls vendor is very transparent.

As I've said before this show comes to you with the audio expertise and stewardship of Carl Franklin. The name comes from Travis Illig, but the goal of the show is simple. Avoid wasting the listener's time. (and make the commute less boring)

Enjoy. Who knows what'll happen in the next show?



I'm thoroughly enjoying Twitter (follow me!) Apparently others are enjoying it also as there's a funny estimate that it's costing $14 billion in lost productivity (via a back of envelope calculation). There is about a million people on Twitter and maybe 60k adding each a month. Certainly it'll be blocked by most corporate firewalls soon for just this reason.

Twitter is also down ALL the time and it's been having weekly (daily?) scale problems for a YEAR, culminating in rumors that the development team is leaving Ruby on Rails that have been denied by Evan Williams (via a "Tweet," of course). However, that doesn't change the fact that Twitter is down so often there is a site dedicated to "Twitter Down Art" showcasing all the pictures that Twitter puts up when their sites are down. Google changes their art monthly and during holidays, but never goes down. Twitter goes down so often that they use that as an opportunity to change their art! So far, in this era of transparency, no one has explained in technical (or any) terms what the problem with Twitter is and folks are getting impatient. I think that it would be a great PR and Karmic move to just start a Twitter Technical Blog and share the crazy IT problem of the day. Surely someone is sleeping on a cot next to the TweetBoxes and has a story to tell.

There's another rumor that Twitter is worth about $150M. Seems to me that the second bubble hasn't popped. I'm certainly no business man, but we can build this better ourselves.

Twitter is centralized, which is insane (unless you're Google or Amazon or Live.com, etc, which are actually distributed in their own special way).

Twitter is IRC, it's IM, it's chatrooms, but ultimately it's just microblogging with a multi-format API. Here's the XML for my Twitter Account but it looks nicer as Atom.

But I already have a blog! Why use a service when I already host a blog? I hooked up Microsummaries to DasBlog two years ago. There's clearly precedent.

Two folks I know already have Twitter Backup Feeds. Both LazyCoder (backup twitstream) and Dave Winer (twitstream) have Backup Twitter Feeds. Dave takes it even farther and makes his twistream discoverable via a link in his blog:

<link rel="twitstream" href="http://twitter.scripting.com/daveRss.xml" />

With backups like these, who needs Twitter? There is already a very responsive group of Twitter client applications some of which, like twhirl cross-post to Pownce and Jaiku, two Twitter competitors. Russell Beattie has an idea for an Open Twitter Server called Peep using Jabber.

I propose that we distribute Twitter into generalized spec for microblogging and just use RSS or Jabber for the transport. I think the very-fast-rev'ing Twitter clients would support it. 

Thoughts? Should Twitter be a service or should Microblogging be an Open Thing?



OpenID Logo We spent a lot of time at Corillian (my last job) thinking about Identity, and a few months before I left I started getting into Cardspace and OpenID. This was a little over a year ago. We did a podcast on OpenID as well.

At that time, I tried to take the only .NET implementation at the time of OpenID which was written in in Boo written originally by Grant Monroe and port it to C# causing me to go through the Programmer Phases of Grief. Andrew Arnott and Jason Alexander took the reins and we spend a number of late nights trying to get a good OpenID library working. I gave up, but they soldiered on and created dotnetopenid (downloads), including a client and server as well as Andrew's excellent ASP.NET controls .

Fast-forward to now. My new friend Aaron Hockley decided to a stands and promote OpenID. He said:

Effective immediately, I will no longer comment on tech blogs that don’t support OpenID for comment authentication.

He's just one guy, but his heart is in the right place. He points out that:

Google offers it as a Blogger option. It’s available as a super-easy-to-install WordPress plugin. Movable Type has it as a built-in feature.

OpenID is a good thing and it's Growing. You may already have an OpenID if, for example, you have a Yahoo! account. More on this soon.

How to turn your blog into an OpenID

Simon Willison wrote How to turn your blog into an OpenID and it's very easy.

STEP 1: Get an OpenID. There a lots of servers and services out there you can use. I use http://www.myopenid.com for two reasons. One, I know the CEO (they're in Portland), and two, they support optionally using CardSpace to authenticate yourself (as well as the standard way with password).

STEP 2: Add these two lines to your blog's main template in-between the <HEAD></HEAD> tags at the top of your template. Most all blog engines support editing your template so this should be an easy and very possible thing to do.

Example:

<link rel="openid.server" href="http://www.myopenid.com/server" />
<link rel="openid.delegate" href=
http://YOURUSERNAME.myopenid.com/ />

This will let you use your domain/blog  as your OpenID. Now, I can log in with "http://www.hanselman.com" when I see an OpenID Login option - and so can you! Go do it now!

Making OpenID Logins Easier

If you have a blog or site with OpenID support, you should go get this little snippet of JavaScript and install an OpenID ID Selector on your blog from http://www.idselector.com/.

virgin-3

One of the things that is slowing OpenID adoption is that many people don't realize that they may already have one. That's what this little Javascript is trying to do by showing folks sites that they recognize. This way my Dad could login using Yahoo and it would make sense to him. It's a little busy, but it's a start. I've added an http://www.idselector.com/ to my blog for comments.

Adding OpenID Support to DasBlog

A year ago, I originally tried to port the Boo code to C# in an attempt to enable OpenID in DasBlog but eventually gave up. However, last night, I re-familiarized myself with the OpenID spec (it's on 2.0 now) and started reading the source for http://code.google.com/p/dotnetopenid/.

In a word, it's a joy. I was able to get OpenID running OK in two hours and working well and up on my blog in two more. I have to give credit to the fantastic work that Andrew Arnott and Jason Alexander and team are doing. It's come far and you should know about it, Dear Reader.

I had two scenarios in DasBlog (again, in case you didn't know, it's the C# and XML-based blog that runs this site and others) to handle.

First, I wanted to support OpenID for Comments which wouldn't actually "log a user in" in the stateful FormsAuthentication sense. I think this isn't a very common scenario, and I'd describe it as One-Time Occasional Authentication. In this case, I used the dotnetopenid classes directly in a moderately complex scenario.

Second, I wanted to support OpenID to login as the Administrator for my site. This would, in fact, log me in via FormsAuthentication. This would be a common scenario that you'd probably care about as it's very typical. In this case, I used the dotnetopenid ASP.NET Controls, which were about as easy as falling off a log. (That's pretty easy.)

Here's the first, harder, scenario.

If you've entered your OpenID and hit Submit Comment then we'll store the current entry and the comment you're submitting. We'll be redirecting away to get authenticated and we'll need them when we get back. If you're running in a WebFarm, you'll want to store these temporary variables in a database or somewhere that doesn't have node-affinity.

Session["pendingComment"] = comment.Text;
Session["pendingEntryId"] = ViewState["entryId"] as string;
OpenIdRelyingParty openid = new OpenIdRelyingParty();
IAuthenticationRequest req = openid.CreateRequest(openid_identifier.Text);
ClaimsRequest fetch = new ClaimsRequest();
fetch.Email = DemandLevel.Require;
fetch.Nickname = DemandLevel.Require;
req.AddExtension(fetch);
SaveCookies();
req.RedirectToProvider();
return;

What I think of as an "OpenID Client" is called a "Relying Party" or "RP" in the parlance of the OpenID folks. In this code we create an AuthenticationRequest and add some additional claims. There's a nice interface-based extension model in this lower-level library that lets you Request or Require information from the user's profile. For comments on the blog, I just need your email for your Gravatar and your Nickname for Display.

I then call RedirectToProvider, and that's if for the request side. Remember I said this was the hard scenario! Not so hard. ;)

Next, we're redirected to an OpenIDProvider, we authenticate (or not) and are redirected BACK with additional information encoded on the GET. On the way back in, in our Page_Load (or an HttpHandler if you like) we check the Response status.  If we're Authenticated, we grab the info we requested and add the comment. Bam. Sprinkle in a little error handling and we're all set.

OpenIdRelyingParty openid = new OpenIdRelyingParty();
if (openid.Response != null)
{
// Stage 3: OpenID Provider sending assertion response
switch (openid.Response.Status)
{
case AuthenticationStatus.Authenticated:
ClaimsResponse fetch = openid.Response.GetExtension(typeof(ClaimsResponse)) as ClaimsResponse;
string nick = fetch.Nickname;
string homepage = openid.Response.ClaimedIdentifier;
string email = fetch.Email;
string comment = Session["pendingComment"] as string;
string entryId = Session["pendingEntryId"] as string;
if (String.IsNullOrEmpty(comment) == false && String.IsNullOrEmpty(entryId) == false)
{
AddNewComment(nick, email, homepage, comment, entryId, true);
}
break;
}
}

Here's the second scenario where we'll log in as the Administrator of the blog. I just register the DotNetOpenId assembly in my ASPX page and put an <openidlogin> control on the page. Notice that even the claims I created in the manual scenario above are just properties on this control. There's also events like OnLoggedIn to handle the results.

<%@ Register Assembly="DotNetOpenId" Namespace="DotNetOpenId.RelyingParty" TagPrefix="cc1" %>
<cc1:openidlogin id="OpenIdLogin1"
RequestEmail="Require" RequestNickname="Request" RegisterVisible="false"
RememberMeVisible="True" PolicyUrl="~/PrivacyPolicy.aspx" TabIndex="1"
OnLoggedIn="OpenIdLogin1_LoggedIn"/></cc1:openidlogin>

This controls renders nicely as seen in the screenshot below.

image

In the OnLoggedIn event, I call my existing security APIs (Thanks to Tony Bunce and Anthony Bouch) and set the AuthCookie from FormsAuthentication.

protected void OpenIdLogin1_LoggedIn(object sender, OpenIdEventArgs e)
{
UserToken token = SiteSecurity.Login(e.Response);
if (token != null)
{
FormsAuthentication.SetAuthCookie(userName, rememberCheckbox.Checked);
Response.Redirect(SiteUtilities.GetAdminPageUrl(), true);
}
}

Poof. I love using well designed libraries and just work. At this point all that was left was adding some CSS and tidying up.

OpenID and ASP.NET WebForms and MVC

The dotnetopenid source includes source for sample sites. It actually includes three samples, two WebForms and one ASP.NET MVC.

The MVC implementation is very clean, even though (or because?) it doesn't use controls. Here's the Authenticate Controller Action:

public void Authenticate() {
var openid = new OpenIdRelyingParty();
if (openid.Response == null) {
// Stage 2: user submitting Identifier
openid.CreateRequest(Request.Form["openid_identifier"]).RedirectToProvider();
} else {
// Stage 3: OpenID Provider sending assertion response
switch (openid.Response.Status) {
case AuthenticationStatus.Authenticated:
FormsAuthentication.RedirectFromLoginPage(openid.Response.ClaimedIdentifier, false);
break;
case AuthenticationStatus.Canceled:
ViewData["Message"] = "Canceled at provider";
RenderView("Login");
break;
case AuthenticationStatus.Failed:
ViewData["Message"] = openid.Response.Exception.Message;
RenderView("Login");
break;
}
}
}

What about CardSpace?

Infocard LogoOpenID is a spec for a protocol that "eliminates the need for multiple usernames across different websites, simplifying your online experience."  What's cool is that it's open, so you (the consumer) gets to pick your Provider. It's not owned by anyone, so it's ours to screw up (or succeed with).

CardSpace is built into Vista and installed on XP when you put .NET 3.0 on your system. There are also Identity Selectors for Safari and Firefox in the works. It's different than OpenID in that it's concerned with strong authentication. Therefore, they are very complimentary.

Here's my CardSpace login as I'm getting ready to log into this blog...

image

...because my chosen OpenID provider at http://www.myopenid.com (it's free) also supports both InfoCards and SSL Certificates for authentication as well as strong passwords.

Notice the "Sign into Information Card" icon below next to the IconCard purple icon.

image

An OpenID provider can choose to use anything available with which to authenticate you. Here's a video of a Belgian using an eID to authenticate against an OpenID provider at http://openid.trustbearer.com/ that supports biometric devices, USB keys, and smart cards.

So What?

Get involved and give it a try! Here's some things you can do.

  1. Sign up for a Free OpenID at MyOpenID or one of the many public OpenID providers out there.
  2. Go use your new OpenID at one of the many sites that supports OpenID.
    • Come back to this post and leave your first comment using OpenID!
  3. Watch Simon Willison talk about the case for OpenID (video)

And, if you're a developer, get an OpenID library like dotnetopenid and consider enabling your app. Consider using the Javascript ID Selector to make for a nicer User Experience.

Technorati Tags: ,,


Contact

Sponsors

Xceed - The Free WPF Grid
ASP.NET HOSTING
GUI Controls For Drop-In Windows Explorer Like File/Folder Browsing Functionality
SyncBackSE from 2BrightSparks
Free WinForms Library from ComponentFactory.com
CodeIt.Right The First Time
Get closer with NCover
Dell Laptops
Error displaying xml file:

The operation has timed out

System

at System.Net.HttpWebRequest.GetResponse() at Hanselman.TextLinkMacro.TextLinks(String adID, String inventoryKey)

On this page...

Tags

Calendar

<May 2008>
SunMonTueWedThuFriSat
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

Archives

Google Ads