Thoughts, Code, Other

Technical blog of Nik Smit

rainbow

Archive for the ‘Uncategorized’ Category

The Death of Sub-Identities

A very brief look into forces that are merging our previously distinct internet lives, and where it might take us.This article was originally written for 77agency

Sub-Identities

Being the savvy netizen you are, you have several accounts on the ‘net. Flickr, twitter, Facebook, Dopplr, Last.fm and endless other words that meant nothing to you 10 years ago, and continue to annoy those keen on correct spelling. You may use these accounts daily - engaging with others and contributing to a community, or treat them as a utility. But within each sphere there is data about you. Some you willingly provide through your profile information, the rest is populated based on the actions you perform.

Each of these accounts is nicely cordoned off from each other. Your colleagues at the bank may know that you tweet about financial stocks as “MrMoneyBrainz”, but they have no idea that you are the star contributor to Flickr’s kinkiest pictures group. That group in turn has no knowledge of your passion for early Abba on Last.fm (you oddball).

Your life on each of these separate planets form sub-identities, each expressing a part of your personality or interests in a narrow realm such as music or travel. We’re comfortable with this model as it’s exactly how we are used to managing our lives offline – our poker club friends don’t mix with our philosophy club friends. It’s simple to understand and there’s nothing to manage, except for a list of usernames and passwords longer than your arm (I recommend Roboform).

Life-Streaming

A few folks looked at this and decided we could do better. What if you wanted to show the world an integrated view of your sub-identities? Lifestream.fm, Friendfeed and Retaggr all provide for this. Enter all your usernames, and your activities are collated into a single stream of your life. Others can come to this place to get to know you, and connect where appropriate.

Interesting to watch here is the reaction to these ideas. Some leap at the opportunity to present a more holistic view on their life – they’re typically quite open to begin with, and happy to share more. The other contingent call it “Stalker 2.0″, and recoil in horror at the idea of becoming an open book. More and more are falling into the first camp however - the hundreds of thousands of accounts added to Facebook and twitter every day are testament to this. They notice that the sky hasn’t fallen, tell their friends, and the meme spreads.

Aggregating information like this is very useful, but still somewhat limited – I have to know both that such facilities exist, and that you are using one. The cordon between services is still somewhat in effect, and relegated to those in the know.

Collision

There are ways to overcome this. You can add your Flickr account to your Facebook stream, bringing the two worlds together for your Facebook friends. The latest Tweetdeck (a popular twitter client) integrates well with video blog 12 seconds, and ping.fm can push your status updates to almost any service you like, so your mood at any moment is known in all the communities you belong to. Your latest earworm you are listening to (again) in blip.fm can be pushed to twitter automatically. The list goes on, forming a massive matrix of connections between services.

Any modern web app knows that integrating with existing services is a lot easier than trying to operate as an island, and can make their service instantly more useful. It makes sense to give their users a chance to link their accounts in some way.

Every time someone does so, their sub-identities become less distinct, and we become more comfortable with the idea.

Laziness makes walls fall

So clearly the trend is for the walls between your sub-identities to come down. It’s still voluntary of course - you have to opt-in to connect your sub-identities, and you have to know that such facilities exist. But we’ve not accounted for a key catalyst in human progress yet: laziness (or to be more generously, “convenience”).

I simply don’t have time to upload photos to both Flickr and Facebook. And my common friends on both systems don’t have time to be notified twice about the same new photos from me. I don’t want to add the same (real) person on 10 different platforms as a “friend” - once should be enough. I don’t want to have to log into 10 different systems in addition to email to answer messages. My hunch is that most feel the same.

Wouldn’t it be great if the cornucopia of platforms could continue to proliferate, but differentiate purely on their own innovations? Trying to convince users they need another messaging system, another list of distinct “friends”, and yet another username seems like an unnecessary hurdle. Web developers would prefer to focus on creating interesting functionality.

Integration

Enter Facebook Connect. A system for both single-signon (no more usernames and passwords for every service) and a mechanism to push your activities to a central place (Facebook). This is really important. In one fell swoop it touches our laziness nerve, and brings a form of integrated life-streaming to the non-geeky masses. Facebook’s user momentum is currently so significant that achieving critical mass (becoming the de-facto login on any site) is not unthinkable. Instead of holding a smorgasbord of accounts, you hold one, and use it everywhere to interact.

Monopoly 2.0?

A closed, proprietary system like this is the antithesis of what the internet was founded on. Your online life becomes controlled by one entity, which doesn’t even bother with a warm fuzzy motto like “don’t be evil”. It’s therefore conceivable, and preferable, that we end up with two or three similar systems of this nature. They can compete on minor points, but must be largely interoperable. Anything is game for use as competitive advantage, but history shows us that interoperability is usually unavoidable eventually. Web developers for one will scream bloody murder at having to facilitate logging in via too many disparate systems.

One Identity to rule them all

Whether the mechanics of all this revolve around a monopoly, oligopoly, or a completely federated system, the norm will become to forgo distinct sub-identities. (For privacy reasons, you might retain one or two sub-identities that are unconnected to your main profile, but they will be the exception). What effects might this have?

  • Your social graph is more tightly integrated with your communities. You may love or hate this. You’ll like the serendipitous crossing of lives (a school-friend you added on Bebo years ago notices your Dopplr update about being in town, you meet for coffee and decide to form a company), and greater opportunities (an associate didn’t realize you were such an expert in goose mating rituals until you tweeted about it, and recommends you for that job at the zoo you’ve always wanted). You might dislike potential mates knowing about your obsession with stamps.
  • You’ll appreciate the integrated view of the people in your life, from business associates to family, all managed through the same portal. The software we use to view this integrated life will have to raise its game significantly. With all this data, we’ll need much better ways of categorizing people (some of it done automatically), more intelligent news feeds, and vastly improved methods of alerting us appropriately about activities.
  • Other “utility” upsides become easier to implement. For example, events and contact details are exchanged, synced, and kept up to date with no effort. Later this allows computers to be told “schedule a beer with Dave sometime next week when we both have time”, and it can handle the whole process, even though “Dave” is an entity on a completely different platform.
  • A unified identity, against your real name, alters the atmosphere on the internet. Again, this is spurred on by convenience. If a blog implements Facebook Connect, you can sign up and comment on an article in seconds. If not, you might have to do the whole “pick a username and password and check it’s all ok and then confirm your email address” song and dance. A hassle, with the only upside being the option for anonymity, by using fake credentials. Most will opt for the former, and we go from defaulting to potential anonymity, to defaulting to accountability. Almost accidentally, we might get more engagement and contributions to online communities (currently less than 10% contribute). Less lurking, and less trolling - a great thing.
  • The subtly different faces you maintain for different groups of people in your life will erode. Everyone from your place of worship will know that you listen to hardcore death metal. Despite being a powerful business-person, your childish penchant for lolcats will be common knowledge. Your grandmother could be revered for her extensive knowledge about dark dubstep. Our stereotypes may be forced to bend or break to accommodate all this.

But what about privacy?

This is where things get interesting. With all our interests and activities collated, we’ll be faced with new challenges on how to decide who gets to see all this data. We’ll be rightly concerned with stalking, ID theft, and having information used against you later - Google never forgets. We’ll face a choice:

  • Demand micro control privacy knobs on everything. We set exactly what is seen, by whom, when, at what level of detail. Technically somewhat feasible, but wildly impractical. Having complex rule systems (or choosing privacy settings on every action) is too much hassle and too complex for everyday use. The use of groups may prove too inflexible.
  • Evolve our ideas about what privacy really means. This is a complex issue, but a quick comment is justified. Our society seems to tolerate a gap between what is acceptable to portray in public, and what is acceptable behind closed doors (unless you’re a celebrity). Perhaps we’ll find that this gap actually doesn’t make sense, and some of our basic ideas about what privacy is, are founded on a gap that does us no good to begin with. A meritocracy, less obsessed with personal preferences, might flourish. See David Brin’s work for ideas about a more transparent society.
  • Drop off the grid entirely. “Facebook suicide” already happens, and faced with a new world of confusing choices, some will pick the blue pill in desperation. If current peer pressure is anything to go by, this option will become increasingly difficult. Once we start to organize our diaries automatically, it will amount to becoming a hermit.

A rough hybrid of the first two options – if you’re not my “friend” you see basic info, otherwise you see everything – seems likely to be taken up by most. Remember that by the time today’s toddlers start using online social systems, the sub-identity concept may seem genuinely archaic, anti-social, or even just unknown.

To boldly go

We’ll have to wait and see exactly how this pans out, but I’m optimistic. I see some interesting positive social effects potentially emerging (that might spill over to the offline realm) and great personal benefits and opportunities. New challenges, and a requirement to adapt to the unfamiliar also await, and will test us in unforeseen ways.

I’ve only lightly touched on some very big issues here, but the identity genie is out of the bottle. It’s up to us to adapt.

How to get normal 404 (Page not found) error pages using ASP.Net MVC

Currently there is no built-in mechanism to achieve regular 404 error pages from an MVC app. If a user tries to access /Products/Foo, or even /Foo, and Foo is not an action, you'll get an error message, similar to this:

The controller for path '/Foo' could not be found or it does not implement the IController interface

What we really want is to have a 404 error message generated. You can then optionally (ideally) redirect the user to a friendly error page appropriately styled for your site.

Fortunately the last bit we get for free with ASP.Net. Modifying your web.config to something similar to below would normally achieve this.

<customErrors mode="On" defaultRedirect="/Error">
<error statusCode="404" redirect="My404.html" />
</customErrors>

But out of the box MVC (preview 2) never generates the 404 error, so this functionality never kicks in. No doubt the MVC team will rectify this in a future release, but for now let's see if we can improve things.

Two modifications are needed :

a) To handle the unknown action (/Products/Foo)
b) To handle the unknown controller (/Foo)

a) This is the easier bit. Ensure your Controllers subclass your own common controller base class :

 
public class HomeController : ControllerBase
{
//..
}

This base class is a convenient place to put all sorts of common functionality - if you didn't need it to accomplish this particular task, you'll probably need to do it for something else, so it's good practice to have one.

 
public class ControllerBase : System.Web.Mvc.Controller
{
 
protected override void HandleUnknownAction(string actionName)
{
throw new HttpException(404, "");
}
 
//...
}
 

As you can see, we override the default behaviour of Mvc.Controller, when an unknown action is specified. By throwing the 404 ourselves, we induce the default ASP.Net behaviour specified in the web.config, which is what we want - redirection to our custom error page.

b) Handling the unknown controller is done by changing the Current ControllerBuilder's default Controller Factory. We create our own factory that does nothing more than throw that same HttpException, in the case that the controller could not be found.

 
public class IntelligentControllerFactory : System.Web.Mvc.DefaultControllerFactory
{
protected override IController CreateController(RequestContext requestContext, string controllerName)
{
IController controller = null;
try
{
controller = base.CreateController(requestContext, controllerName);
}
catch (ArgumentNullException ex) //Note : this exception type may change with future releases
{
throw new HttpException(404, "");
}
 
return controller;
}
 
}
 

Now we need to set up this factory to be used instead of the default, which is done in your global.asax.cs :

 
protected void Application_Start(object sender, EventArgs e)
{
 
ControllerBuilder.Current.SetControllerFactory( new IntelligentControllerFactory());
 
RegisterRoutes(RouteTable.Routes);
//....
}
 

You should now be in 404 bliss.

If you have found a better way to achieve this, drop me a line.

Some quick tips to speed up Visual Studio and help you develop faster

If you work with Visual Studio all day long, at some point you've just wanted it to go just that little bit faster. Don't get me wrong, it's certainly not a slow tool by any means, but if you're working with the same tool all day long, even minor improvements can add up to a significant amount over time.

Adding as much RAM as you can afford, using 10000 RPM drives, and using a dual core processor are the best things you can do hardware wise (in that order). Turning off anti-virus software (if you dare), and physically separating your data and OS also goes a long way. These things are all very well documented elsewhere.

But there are others ways to get you out of the office earlier, that don't require pulling out your credit card.

Have a look at your habits and processes while developing - particularly the ones you repeat a million times a day. Investing a bit of time to improve these can yield some good ROI in terms of efficiency.

Keyboard shortcuts = Speed

Every function in visual studio is exposed as a command that you can bind to (right click any toolbar, customize, keyboard....). Take note of what you do most often, and ensure those commands are bound. Of course, obvious tasks like building your project should be mapped to something comfortable on your keyboard (I use Alt-1).

But you'll probably find that navigating your way around your mega-solution keeps requiring some mouse action. The more you keep your hands on the keyboard, the faster you go, so ensure you are aware of at least the following commands :

  • Edit.GoToDefinition (F12).
  • View.NavigateBackward ( cntrl -). Great for returning to where you were working before navigating to that definition
  • Drop Bookmark (cntrl-k, cntrl-k)
  • Go to next bookmark (cntrl-k, cntrl-n)
  • Open window list (alt-w, w). With many windows open, this dialogue is a lot quicker than cntrl-tabbing around, as you can jump to the correct file by using its first letter).
  • Go to code behind : F7
  • Go to visual designer from ode behind : Shift-F7 (Unless you actually use the visual html designer, dont use this - the rendering is too slow).
  • Go to html source view from visual designer (cntrl-pg dn)

Cntl-F can be sped up

Often you know exactly where you need to be in your file. There's a specific piece of text (probably a function name) that'll get you there quickly if you search for it with cntrl-F. I do this a million times a day. But with VS 2008 (and I think with 2005) bringing up that search dialogue takes about a second for no good reason. It really should be instant - if you do 300 searches in a day, that amounts to time for another cup of coffee. I would hope this is fixed in a service pack, but until it is, dock that dialogue somewhere. I dock it with my solution explorer (bring it back to the fore with cntrl-alt-l). With it docked, its never destroyed, and hitting cntrl-f just brings it to the foreground quickly.

Use aliases in the command window

I'd forgotten about this powerful feature until recently. All those commands above can be accessed from the command window. Call it up with cntrl-alt-a. If you've ever used the console in Quake, this is the same concept. All the commands are exposed for you to play with (use the intellisense!), so typing

File.OpenFile MyProject\Web.config

will unsurprisingly open web.config for you to edit (Intellisense is there for the filename too). While that may seem like a step backward in terms of speed, if you know the exact file you're trying to open, it can be a lot quicker to type that than navigating through a bunch of projects and folders. Plus, it gets better.

Any command can be aliased. So executing

alias o File.OpenFile

means we can now type

o MyProject\Web.config

to open that same file! We can go further though. Perhaps you have a bunch of files you need to access all the time. For me these include web.configs, the main css file, the main javascript file and so on.

Try something like this :

alias css File.OpenFile MyProject\content\style\main.css

(To delete that alias execute alias css /delete)

One could go wild here - I'm not trying to say alias everything. Just optimize those you're doing often (especially those that currently involve the mouse). Which brings me to....

Web developers! Bind a macro for attaching to the w3p process

Some web developers test their pages by hitting F5 and launching Visual Studio's built in Casini web server. I've never liked this approach:

a) I prefer to navigate around my site and then decide I need to do some debugging at that point (its taken a bunch of steps to get to this point)

b) I like the warm fuzzy feeling of knowing there are no surprises at deploy time, so would rather use IIS7 proper.

So the process is easy - just call up Visual Studio's "attach to process" dialog, find w3p.exe, attach, and you're in business. I think you can guess where I'm going with this - that just takes too long. Sometimes enumerating all those processes seems to take forever in the dialogue, which is kinda silly when you know the one you want.

The solution is to use a macro for this purpose, and bind it to a keyboard shortcut. You're attached in a second or two - lovely! Hit Alt-F11 to bring up your macro editor, and drop this into a new module.

 
Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports System.IO
Public Module Misc
 Public Sub AttachToFirstDevWebServer()
 Dim process As EnvDTE.Process
For Each process In DTE.Debugger.LocalProcesses
 System.Diagnostics.Debug.Print(process.Name)
 If (Path.GetFileName(process.Name).ToLower() = "w3wp.exe") Then
 process.Attach()
 Exit Sub
 End If
 Next
MsgBox("Could not find web server")
 End Sub
End Module
 

Note : if you are using the built-in server, you can still get the benefits of this, by swapping out "w3p.exe" for "WebDev.WebServer.exe" in the macro.

I'll be posting more on this topic in future. Until then, drop me a line if you have any cunning efficiency tips :)

Make ASP.Net controls implement modern layout principles

One of ASP.Net's greatest strengths is surely its built-in controls. With each iteration of the product their features expand, and they do their bit towards programming's greatest goal :

Reducing the plumbing, increase the productivity.

Microsoft generally also does an excellent job of facilitating "drag-n-drop" component use, while still allowing the developer to customise behaviour, layout and so on.

So it was that recently I wanted to use the Menu component, for this site actually. Up until now for some reason I've always used 3rd party tools (such as ComponentArt's Menu), or rolled my own. So there I was thinking this would be easy - declare a <asp:menu> object, assign it a sitemap, a bit of CSS assignment, and be on my way.

It was not to be.

Unless you've been asleep at the wheel as a web developer for the last couple years, you'll know that using table elements for layout is frowned upon. For very good reasons. Tables are fine for tabular data, but sites are more flexibile and resiliant to change when layed out in CSS. (Check out this link for help with migrating your site from tables).

Plus, if you're using a CSS template (I know great design when I see it, I leave it to the designers to come up with it!), like those available here, you'll want to be emitting clean CSS so that you can mark it up easily with your chosen template.

Unfortunately, some ASP.Net still produce table layout code, and Menu is one of them. How to solve this conundrum? Check out the ASP.Net 2.0 CSS Friendly Adapters. These adapters plug into the ASP.Net controls

  • ChangePassword
    CreateUserWizard
    DataList
    DetailsView
    FormView
    GridView
    Login
    LoginStatus
    Menu
    PasswordRecovery
    TreeView

and cause them to emit nice clean divs, while not requiring any code changes on your part. This is done using ASP.Net's "control adapters" which allow you to override, modify and/or tweak the rendering output logic of any ASP.NET server control.

Problem solved! Almost....

The css class the control uses (after being adapted) for the selected menu item is AspNet-Menu-Selected. This overrides any settings related to the style of the selected item you may have set on the menu. Which is fine normally, you can go ahead and alter that css style in the supplied css file to meet your own needs, but as I said, my goal was to plug in a provided css template, with its own style.

In other words, I still wanted to be able to say : StaticSelectedStyle-CssClass="myTemplateStyle", in the Menu's declaration.

One quick change to MenuAdapter.cs, and we're done :

 
private string GetSelectStatusClass(MenuItem item)
{
string value = "";
if (item.Selected)
{
value += " AspNet-Menu-Selected";
 
Menu menu = Control as Menu;
if (menu.StaticSelectedStyle != null &amp;&amp; !String.IsNullOrEmpty(menu.StaticSelectedStyle.CssClass))
{
value += " " + menu.StaticSelectedStyle.CssClass;
}
}
else if (IsChildItemSelected(item))
{
value += " AspNet-Menu-ChildSelected";
}
else if (IsParentItemSelected(item))
{
value += " AspNet-Menu-ParentSelected";
}
 
return value;
}
 

You are currently browsing the archives for the Uncategorized category.