Customizing Visual Studio with external tools

February 25, 2012

Last month I wrote a 3-part series on the Headspring blog about Visual Studio’s external tools feature. An external tool is really just a path to an external executable that you can configure. Visual Studio 2010 is awkward to customize to say the least, but once you learn your way through the dialogs you can set up your own toolbars, buttons and context menus to perform nearly any action.

A custom toolbar of external tools:

image

A custom context menu of tools:

image

Links to the posts are below, enjoy!

Part 1: Creating external tools

Part 2: Creating a custom toolbar

Part 3: Customizing the context menu

Lowercase Urls with ASP.NET MVC

February 24, 2012

One minor annoyance with ASP.NET MVC is that Urls generated via the routing mechanism are based exactly on the Controller and Action names. These will typically be camel-cased resulting in urls like www.example.com/Home/Index. Routing is case-insensitive, however, so a request to www.example.com/home/index works just the same.

In terms of SEO, it’s considered bad practice to allow Urls with any casing because it could technically be considered to be duplicate pages with the same content. (Frankly, I find this hard to believe, but nevertheless I follow along and would rather be safe than sorry)

IIS 7 Url Rewrite rule

The quickest way enforce all Urls to lowercase is to implement a single Url Rewrite rule. This comes as a template out of the box if you open up the Url Rewrite module in the IIS7 management console and click “Add Rule(s)…”.

An enforce-lowercase rule looks like this:

<rule name="LowerCaseRule" stopProcessing="true">
  <match url="[A-Z]" ignoreCase="false" />
  <conditions>
    <add input="{REQUEST_METHOD}" matchType="Pattern" pattern="POST" ignoreCase="true" negate="true" />
  </conditions>
  <action type="Redirect" url="{ToLower:{URL}}" redirectType="Permanent" />
</rule>

It’s important to note that out of the box, the IIS generated rule with apply to all request methods (GET, POST, etc). I added the condition above that does not apply the rule to POST requests. Typically user-agents won’t follow a redirect on a POST, which will result in an error. I only really care about GETs anyway.

Force routing to generate lowercase Urls

The problem with only applying the redirect rule is that nearly any Url your application generates will hit the rule and force needless round-trips and redirects. What we really want is for the ASP.NET MVC routing system to simply only generate Urls of the lowercase variety.

You could manually configure it to do so (or avoid convention and just name your controller/actions lowercase), but there’s a great little NuGet package that will take care of it for us!

LowercaseRoutesMVC is a sweet little NuGet package by Lee Dumond that enforces lowercase Urls, doesn’t affect querstrings, and works with virtually zero configuration. All you have to do after installing the package is to change your route registrations to call MapRouteLowercase instead of MapRoute.

routes.MapRouteLowercase(
    "default", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);

I just installed LowercaseRoutesMVC (the project page is on codeplex) and it’s working great!

Tags: routes, routing, lowercase, url
Categories: ASP.NET MVC

Using conversion operators to create flexible types

February 20, 2012

Follow along with me. Have you ever had a situation where you had to represent some conceptually complex or flexible value in a class? For instance, the the concept of “hours”? Maybe you would start off simple with something like:

public class Foo
{
    public decimal Hours { get; set; }
}

//usage
foo.Hours = 1;
foo.Hours = 1.5m;

You were clever to note that hours may be used as whole numbers or fractions, so you made sure  you could assign int and decimal values. But it turns out your data is more complex than that. You also must account for string representations of hours, such as “1:30” (one hour and thirty minutes).

Easy enough. It’s probably time to create a custom class or struct to encapsulate all that. If you’re not familiar with implicit or explicit conversion operators, you may end up with a simple class with overloaded constructors that accept int, decimal, or string, so that it could be used like this:

hours = new Hours(1);
hours = new Hours(1.5m);
hours = new Hours("1:30");

decimal hoursAsDecimal = hours.Value;

It works. But this is kinda lame. Wouldn’t it be cool if you could just do something like this:

hours = 1;
hours = 1.5m; 
hours = "1:30";

decimal hoursAsDecimal = hours;

You can!

Understanding conversion operators

To quote MSDN: C# enables programmers to declare conversions on classes or structs so that classes or structs can be converted to and/or from other classes or structs, or basic types. Conversions are defined like operators and are named for the type to which they convert. Either the type of the argument to be converted, or the type of the result of the conversion, but not both, must be the containing type.

Here’s a basic Hours struct that has just one conversion operator:

public struct Hours
{
    private readonly decimal _hours;
    private Hours(decimal hours) { _hours = hours; }

    //implicit decimal to Hours conversion operator
    public static implicit operator Hours(decimal value)
    {
        return new Hours(value);
    }
}

This implicit operator is specifying that types of decimal can be implicitly converted into types of Hours, and the method body is how the conversion is performed (in this case, decimal is the underlying type, so it just returns a new Hours instance).

To allow other values to be converted, just specify additional implicit operators:

//implicit int to Hours conversion operator
public static implicit operator Hours(int value)
{
    return new Hours(value);
}

//implicit string to Hours conversion operator
public static implicit operator Hours(string value)
{
    //Parse() is the private method of Hours responsible for
    //converting the string to a decimal. It's omitted for brevity
    return Parse(value);
}

Switching things around

Every operator above defines how a particular type can be converted into the custom type Hours, but what about the other way around? How can we make Hours directly assignable to a decimal type? All you have to do is flip it around.

//implicit Hours to decimal conversion operator
public static implicit operator decimal(Hours value)
{
    return value._hours;
}

Again, this is defining that the type Hours can be implicitly converted into type decimal. The net result of this and the other operators defined above is that you can write super flexible and clean code:

hours = 1;
hours = 1.5m; 
hours = "1:30";

decimal hoursAsDecimal = hours;

A quick note about explicit operators

You can also make operators explicit. They work the same way, but require an explicit cast to work.

//explicit decimal to Hours conversion operator
public static explicit operator Hours(decimal value)
{
    return new Hours(value);
}

//usage
hours = (Hours) 1.5m; //explicit cast from decimal to Hours

hours = 1.5m; //compile error, "cannot convert decimal to Hours"

Because of this, implicit operators are generally preferred, but if you want callers of your code to be explicitly aware that they must cast properly you can do so.

Next time you find yourself creating a custom chameleon-like type that must be assignable to or from several different types, consider encapsulating all of the conversion code by putting it into the type and then creating implicit or explicit conversion operators to make the calling code clean, easy and flexible.

About Kurt

I'm a senior consultant at Headspring in Austin, TX. My passion is creating web-based applications that are well crafted and solve real problems for real people. Want to know more? Check out my about page.

At my sister's wedding. I routinely have to develop software with specifications less detailed than this! http://t.co/RcZDbfZvgX 12 days ago