Skip to main content

First NuGet Public Package: States & Provinces

I recently had to code a drop down for a state field on an entry form. Didn’t take long and not a big pain but I thought, why is there no NuGet package for this. So,,,,

First, states and provinces are generically termed political subregions or geographic subdivisions. There is an ISO standard so we’ll follow that.

First thing we need is a representation of the subregion.

/// <summary>
/// Represents a political subregion such as a state or province.
/// </summary>
public class SubRegion
{
    /// <summary>
    /// Gets or sets the name of the subregion.
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// Gets or sets the ISO-3166 code for the subregion.
    /// </summary>
    public string IsoCode { get; set; }

    /// <summary>
    /// Gets or sets the standard abbreviation for the subregion.
    /// </summary>
    /// <remarks>
    /// For the US, this is the USPS 2 character abbreviation.
    /// </remarks>
    public string Abbreviation { get; set; }

    /// <summary>
    /// Gets or sets an alternative abbreviation that may be used.
    /// </summary>
    /// <remarks>
    /// This is a common local or historical abbreviation.
    /// </remarks>
    public string AlternateAbbreviation { get; set; }
}

Now we need a way to identify which countries we can produce. I’m only going to do the US and Canada since that’s all I’ve had to deal with so far. Since we’ll want to support returning more than one country, we’ll add the FlagsAttribute to our enum.

/// <summary>
/// Represents the countries for whom subregions are available.
/// </summary>
[Flags]
public enum CountrySelection
{
    [Description("Canada")]
    Canada = 1,

    [Description("United States")]
    UnitedStates = 2
}

Now we need a factory to make our lists. The Make method creates an empty list and then adds the desired countries’ subregions. This allows us to return more than just one at a time.

/// <summary>
/// Public member for creating a list of subregions.
/// </summary>
/// <param name="selection">The country or countries that define the desired subregions.</param>
/// <returns>A generic List of Subregions.</returns>
/// <remarks>
/// More that one country may be returned by using the bitwise OR operator.
/// </remarks>
public static List<SubRegion> Make(CountrySelection selection)
{
    var results = new List<SubRegion>();

    if (selection.HasFlag(CountrySelection.Canada))
    {
        results.AddRange(MakeCanadianProvinces());
    }

    if (selection.HasFlag(CountrySelection.UnitedStates))
    {
        results.AddRange(MakeUSStates());
    }

    if (results.Count == 0)
    {
        throw new System.NotImplementedException("The country selection has not been implemented.");
    }
    return results;
}

Then we have a method for each country to keep things neat and organized. Here’s the one for Canada.

/// <summary>
/// Creates the list of Canadian provinces.
/// </summary>
/// <returns>A generic List of provinces.</returns>
private static List<SubRegion> MakeCanadianProvinces()
{
    var results = new List<SubRegion>();
    results.Add(new SubRegion() { Abbreviation = "AB", Name = "Alberta", AlternateAbbreviation = "Alta.", IsoCode = "CA-AB" });
    results.Add(new SubRegion() { Abbreviation = "BC", Name = "British Columbia", AlternateAbbreviation = "B.C.", IsoCode = "CA-BC" });
    results.Add(new SubRegion() { Abbreviation = "MB", Name = "Manitoba", AlternateAbbreviation = "Man.", IsoCode = "CA-MB" });
    results.Add(new SubRegion() { Abbreviation = "NB", Name = "New Brunswick", AlternateAbbreviation = "N.B.", IsoCode = "CA-NB" });
    results.Add(new SubRegion() { Abbreviation = "NL", Name = "Newfoundland and Labrador", AlternateAbbreviation = "Nfld.", IsoCode = "CA-NL" });
    results.Add(new SubRegion() { Abbreviation = "NS", Name = "Nova Scotia", AlternateAbbreviation = "N.S.", IsoCode = "CA-NS" });
    results.Add(new SubRegion() { Abbreviation = "NT", Name = "Northwest Territories", AlternateAbbreviation = "N.W.T.", IsoCode = "CA-NT" });
    results.Add(new SubRegion() { Abbreviation = "NU", Name = "Nunavut", AlternateAbbreviation = "Nun.", IsoCode = "CA-NU" });
    results.Add(new SubRegion() { Abbreviation = "ON", Name = "Ontario", AlternateAbbreviation = "Ont.", IsoCode = "CA-ON" });
    results.Add(new SubRegion() { Abbreviation = "PE", Name = "Prince Edward Island", AlternateAbbreviation = "P.E.I.", IsoCode = "CA-PE" });
    results.Add(new SubRegion() { Abbreviation = "QC", Name = "Quebec", AlternateAbbreviation = "Que.", IsoCode = "CA-QC" });
    results.Add(new SubRegion() { Abbreviation = "SK", Name = "Saskatchewan", AlternateAbbreviation = "Sask.", IsoCode = "CA-SK" });
    results.Add(new SubRegion() { Abbreviation = "YT", Name = "Yukon", AlternateAbbreviation = "Yuk.", IsoCode = "CA-YT" });
    return results;
}

So, if we want to make a list of US states, we simply call our factory.

var states = Factory.Make(CountrySelection.UnitedStates);

Let’s get the US and Canada

var usAndCanada = Factory.Make(CountrySelection.UnitedStates | CountrySelection.Canada);

I’m making this a public project on GitHub so others can add the information for their country. Hope you find it useful.

Comments

Popular posts from this blog

Migrating Legacy Apps to the New SimpleMembership Provider

Asp.Net MVC4 uses the new SimpleMembership provider, changes the table structure and adds a new hashing algorithm. The reasons for the changes can be found in this article by Jon Galloway. This article shows how to migrate your existing apps to the new provider.I’m assuming that you stored your passwords in the unrecoverable SHA-1 format. If you didn’t, then you’ll have to change a couple of things. All of my apps are done this way so… I’m also assuming that you have created the basic skeleton of the new app and ran it once so the correct tables will be created.First, we’ll look at the new tables. Previously, we had all of those aspnet_xxxxxx tables. Here’s the new ones.UserProfileContains all of the elements relevant to the user. This is a combination of the aspnet_Users table and the aspnet_Profiles table.webpages_MembershipStores the password info when not using OAuth, Live, Facebook, etc. This table is somewhat of a match to the aspnet_Membership table.webpages_OAuthMembershipStor…

JavaScript function to automatically add slashes to date

In converting an old Windows app to a browser app, the user wanted to be able to enter dates without the slashes. Here's a simple jscript: 1:// Function to convert short date string (MMddyy) 2:// or (MMddyyyy) to a date string (mm/dd/yyyy). 3:// txtBox is the actual textbox control 4:// with the value to be processed. 5:function FixShortDate(txtBox) { 6:if (txtBox == null) { 7:return'' } 8: 9:var re = new RegExp(/(\d{6})(\d{2})?/); 10: 11:if (re.test(txtBox.value)) 12: { 13:if (txtBox.value.length == 8) { 14: txtBox.value = txtBox.value.substring(0, 2) + '/' + txtBox.value.substring(2, 4) + '/' + txtBox.value.substring(4, 8) 15: } 16: 17:if (txtBox.value.length == 6) { 18:if (txtBox.value.substring(4, 6) < 20)