Thursday, August 22, 2013

Visual Studio 2012 and IP6 Loopback

Problem: When you upgrade your Visual Studio solution to VS 2012, the Web Applications that run inside the Visual Studio no longer resolve the localhost to 127.0.0.1  which is the IP4 loopback address. Instead it resolves to ::1 which is IP6 loopback address.

We faced this issue when we tried to upgrade our .net 3.5 solutions for VS 2010 and earlier to VS 2012. Rest of this post is about analyzing the issue and evolving a solution to the problem.

Our application is looking for UserHostAddress property on incoming requests and expecting it to be in certain format, IP4 4 octect format, in various parts of our code. This is, of course, a design smell. While this intimate reliance on low-level detail may be avoided in distant future, we were struck with VS 2012 solution that we can't run.

I tried to change hosts file (C:\Windows\system32\etc\drivers\hosts). It did not help. When I researched this problem on the web, most solutions suggested to disable all of the IP6 components. This is certainly feasible via registry manipulation and a restart. While this may solve the problem but it is not recommended by Microsoft.

Actually there is no problem with IP6 on your machine. Neither .net nor Windows 7 are culprits here. My lucky break came when I typed 127.0.0.1:57574 instead of going to localhost:57574 as my VS 2012 does. The UserHostAddress is no longer ::1 but it is 127.0.0.1 as expected by my application. The problem was due to the way Cassini (WebServer.exe, comes with Visual Studio) handle the incoming requests. It translates the localhost as IP6 loopback ::1 instead of 127.0.0.1. 

Here I suppressed the Cassini’s urge to translate the string localhost using latest technology.  This solution does not need any mucking of the registry and hence your spanking Windows 7 (or Windows 8) works perfectly for ,those components that may rely on IP6.

True to my calling, I am too lazy to type 127.0.0.1: 57574  , hence I mustered my energy to find an alternative that does not require me to type 127.0.0.1: 57574 every time I launch the application from inside Visual Studio 2012. Fortunately VS supports my laziness, no wonder companies are paying a lot of money for this reason (developer productivity).  All you need to do is to right clicking the Website project and selecting “Property Pages” , then “Startup Options” , and typing “127.0.0.1: 36869” in the “Start URL” box. This works perfectly also.  

The only problem is that it saves this option in binary .suo file rather than .sln which is a text file. Depending on the policies and policing of your configuration management system you may or may not be able to check-in .suo file.


Monday, August 20, 2012

Facebook Timeline is lame

I really don't know when my profile was switched to Timeline view on my Facebook profile. I don't like the way Facebook handles my information. Yet, I am forced to use it because all of my friends and family uses it. Despite the lack of respect for my privacy and the attitude of "opt in by default", I am forced to use it because of it provided a convenient way to stay in touch with my social contacts. This leverage Facebook has on people's lives has name a "Network effect".

I think Facebook went too far with Timeline feature. If we go by the Facebook the civilization started with the earliest date entry in their network. My marriage to my wife , according to Facebook timeline, happened on Dec 26, 2010. And I met my wife, again according to Facebook timeline, on Aug 27, 2007.

In my life these events happened much earlier than what "Facebook timeline" shows.  The dates on the Facebook timeline are probably when I added her as a Friend on Facebook and later as my spouse.

One thing it showed right is my year of graduation. I am glad that it did not show my date of birth as the day I joined Facebook. I feel it should treat other events in a person's life similarly.

This is does not appear to be a huge problem for many of the Facebook users. However the Facebook and its Timeline feature could be a great help for "memory loss patients" in future..



Thursday, July 12, 2012

ASP.net MVC Bread Crumbs

ASP.net WebForms has first class support for Breadcrumbs. Such first class treatment is missing when it comes to ASP.net MVC. You can either use MvcSiteMapProvider (recommended) or write custom code (put your reason here).

It is not all that difficult to write custom code to display bread crumbs on your pages served by ASP.net MVC.

You need to create Web.Sitemap in your root folder. Make sure the Url attribute is pointing to your controller

<?xml version="1.0" encoding="utf-8" ?>
<siteMap>
  <siteMapNode title="Home" url="~" >
    <siteMapNode title="Services" url="~/Services" >
      <siteMapNode title="Training" url="~/Training"/>
    </siteMapNode>
  </siteMapNode>
</siteMap>

Next you need to create a partial view that iterates the ancestry of the current node in reverse order (from the oldest to the newest including the current) and build the breadcrumbs as links and render them.

@using System.Text
@{
    var stack = new List<SiteMapNode>();
    var current = SiteMap.CurrentNode;
    
    while(current != null)
    {
        stack.Add(current);
        current = current.ParentNode;
    }

    var builder = new StringBuilder();
    foreach (var node in stack.Reverse<SiteMapNode>())
    {
        var tag = new TagBuilder("a");
        tag.MergeAttribute("href", node.Url);
        tag.InnerHtml = node.ToString();

        builder.AppendFormat("{0}>", tag.ToString());
    }
    
    ViewBag.SiteMap = MvcHtmlString.Create(builder.ToString());    
}

<h4>@ViewBag.SiteMap</h4>

Next use the partial view inside the pages or inside the _layout.cshtml using Html.Partial.

Disclaimer: The code in this article is experimental and does not reflect the way I write code in general. For example a lot of optimizations can be done to avoid the iteration of ancestral nodes by caching the results.