DateTime Localization in ASP .NET

You’ve got an ASP .NET app and you need to display a date. Normally that just involves the old DateTime.ToShortDateString() or DateTime.ToString(“d”) and you continue coding on your merry little way. But what happens when your users are from different countries and expect different date formats.  Between Australia, USA and Japan there are 3 different date formats.

Then answer? The HttpRequest’s UserLanguages. This string array basically maps to the following languages that you can setup in your browser:

Now for the code:


CultureInfo culture = Request.UserLanguages != null
? CultureInfo.CreateSpecificCulture(Request.UserLanguages[0])
: CultureInfo.CurrentCulture;
myLabel.Text = DateTimeOffset.Now.ToLocalTime().ToString("d", culture);
Don’t forget to check if the UserLanguages is not null since you can remove all the values from the list if you like.
Also, if you are looking at ways to do this client side, ScottGu’s Blog has a nice post on a new jquery plugin for this.

* Update *
Just realised that you don’t need to any of this if you use the following in your web.config:

<globalization uiCulture="auto" culture="auto" />
Posted in .Net, Asp.Net, C# at June 18th, 2010. No Comments.

Parsing comma separated values with regular expressions

We’ve all had to write code to parse comma separated values before; it sounds simple, but it can actually be quite tricky! Sure, if our lists were always nicely defined like this:

  • “one”,”two”,”three”,”four”
  • five,six,seven,eight

Then we could simply use String.Split. But life is never that kind! When your input strings may be a bit more loosely defined, like this:

  • one,”two,three”,four,,six,”seven”
  • ,two,”three,four,five”,,

It gets a little tougher.

So can you do it using a single regular expression? Yes, you most certainly can! It’s simply a matter of breaking down the possibilities, then catering for the best case scenario (quoted values), down to the worse case scenario (zero-length values), and finally, catering for the delimiters (either a comma, or the end of the string). Lets look at them one step at a time.

Firstly, quoted values. This is by far the easiest of all the conditions – find any length of text between two quotes. We’ll use a non-greedy expression (the question mark after the star) to ensure we don’t over-extend the length of text that we match:

private const string
    Template_QuotedValues = @"""(?<content>.*?)""";

The next easiest type of match to capture are non-quoted, non-zero length values. To do this, we’ll simply look for one or more characters which are not a comma. Again, we’re using a non-greedy match:

private const string
    Template_UnquotedValues = @"(?<content>[^,]+?)";

Notice also that that for both templates, we’re creating a named group called “content” – this allows us to easily extract the contents the match, no matter what conditions were matched under.

The last type of match we need to cater for is non-quoted, zero-length matches. This is the trickiest of the three situations, since there’s “nothing” to actually match on! So instead, we look zero repetitions of any character, immediately after a delimiter. Since the first value in the list may be empty, the possible values for our delimiter are either the start of string (specified by the hat – ^), or a comma:

private const string
    Template_EmptyValues = @"(?<=(?:,|^))(?<content>.{0})",

The final piece of the puzzle is the delimiters. Since we’re matching from left-to-right, we can assume that every match will be followed either by a comma, or the end of the string. We’ll use a non-capturing group since we don’t want the delimiter to be explicitly captured in a group.

private const string
    Template_Delimiter = @"(?=(?:,|$))";

Now, to put it all together. We have our three types of matches that we’re expecting, and our delimiter, so all we need to do is create a single RegEx for it all. Here goes:

private const string
    // Any length value within quotes...
    Template_QuotedValues = @"""(?<content>.*?)""",

    // ... or values with at least 1 character, not in quotes...
    Template_UnquotedValues = @"(?<content>[^,]+?)",

    // ...or zero-length matches, not in quotes...
    Template_EmptyValues = @"(?<=(?:,|^))(?<content>.{0})",

    // ... followed either a comma, or end of string
    Template_Delimiter = @"(?=(?:,|$))";

// Now join as one Template - notice the OR condition (pipe)
// between the three match types
readonly static private string
    Template = String.Format("({0}|{1}|{2}){3}",
        Template_QuotedValues,
        Template_UnquotedValues,
        Template_EmptyValues,
        Template_Delimiter);

// Finally, our RegEx!
readonly static private Regex CsvSplitterRegex
    = new Regex(Template, RegexOptions.Compiled);

Was that so bad? ;-) Iterating through the list of values in our comma separated list is now a piece of cake.

// Assume CSV is in "record" field
foreach (Match match in CsvSplitterRegex.Matches(record))
{
    Console.WriteLine("Match value: {0}",
        match.Groups["content"].Value);
}

Simple, eh?

Posted in C#, RegEx at May 15th, 2010. 2 Comments.

Handling of Nulls in Entity Framework

I think most of you can agree that we are advocates of Entity Framework here. But sometimes things can get a little hairy (as with all ORM solutions). So I just thought I’d post a quick solution to a problem that had me tearing my hair out at work to solve the other day.

Given the following two queries using Entity Framework one would assume the generated sql would the same?

string country = null;
var query = context.Orders.Where(o => o.Customer.Address.Country == country);
var query2 = context.Orders.Where(o => o.Customer.Address.Country == null);
Wrong. Thanks to this bug and this Microsoft article, I found out that not only will Entity Framwork will not honour what I have specified for ANSI NULLs, it will result in two inconsistent sql queries as the first query will do a “@country = null” comparison while the second query will do a “Country IS NULL” comparison.
Now, while I get that just because two objects are null it doesn’t mean they are equal, the workaround here can result in some ugly looking linq queries! Thank you ever so much Microsoft :)
Posted in .Net, C#, Sql Server at April 24th, 2010. 2 Comments.

Path resolution in ASP.NET

One thing I’ve always thought that ASP.NET doesn’t do a great job of is handling resource paths. For example, lets say on your development box, you have a website hosted under the virtual directory “MyProject”, such that you browse to http://localhost/MyProject/ to go to the home page. Lets also say that when you deploy the website to an external domain, it falls into the domain root, so instead you go to http://myproject.com/ to see your home page.

Sound familiar? The real problem then comes when you try and define a resource (e.g. a javascript file) using a relative path:

<script
    type="text/javascript"
    src="/Scripts/jquery.js">

This will work fine and dandy when you deploy the website, however on your local machine it will be looking for jquery at the path http://localhost/Scripts/jquery.js” – which more than likely isn’t going to work.

To get around this problem, I wrote a quick helper method called “Locate”, which I find myself reusing time and time again between websites. More often than not, I put it into a static class called “SiteManager” which basically just contains a bunch of helper functions relevant to the current website. Here’s the method:

/// <summary>
/// Resolves the path to a URL
/// </summary>
/// <param name="url">The path to be resolved, relative to the
/// application root</param>
/// <param name="formatArgs">String formatting arguments</param>
/// <returns>The URL</returns>
static public string Locate(string url, params object[] formatArgs)
{
    if (String.IsNullOrEmpty(url))
        url = "/";

    if (formatArgs != null && formatArgs.Length > 0)
        url = String.Format(url, formatArgs);

    HttpContext context = HttpContext.Current;
    return String.Concat(
        context.Request.ApplicationPath,
        !url.StartsWith("/") ? "/" : String.Empty,
        url);
}

To use the method, you simply change your script declaration (or whatever resource you’re trying to find) as follows:

<script
    type="text/javascript"
    src="<%= SiteManager.Locate("/Scripts/jquery.js") %>">
</script>

You’ll also notice that it supports string formatting – so even though it would be pointless in this particular example, you could, if you preferred, do something like this:

<script
    type="text/javascript"
    src="<%= SiteManager.Locate("/Scripts/{0}.js", "jquery") %>">
</script>

In both instances, this will resolve the URL in your output document using the current application path –

  • http://localhost/MyProject/Scripts/jquery.js on your local machine; and
  • http://myproject.com/Scripts/jquery.js on the web server.

Enjoy!

Posted in Asp.Net, C# at January 14th, 2010. 5 Comments.

Quick WPF Performance Statistics

Just thought I’d put out some quick WPF performance statistics thanks to Microsoft. You can download the entire slideshow here.
  • DependencyProperty is x3 faster than INotifyPropertyChanged
  • ObservableCollection accesses single items 90 times faster than List
  • ObjectDataProvider is x20 smaller than XmlDataProvider

Microsoft also have some other good tips over here too.
I’d like to see some real world statistics on the differences between using static vs dynamic resources too. Anybody know of any?

Posted in .Net, C# at December 23rd, 2009. 1 Comment.

Question of the day: Enums

Some fun with enums! Assume you have an enum defined as follows:

enum Frequency {
    None = 0,
    Annual = 1,
    SemiAnnual = 2,
    Quarterly = 4,
    Monthly = 12,
    Weekly = 52
}

Now, given the following block of code:

Frequency myFrequency = (Frequency) 104;
System.Console.WriteLine("My frequency is: {0}", myFrequency.ToString());
bool is100Defined = Enum.IsDefined(typeof(Frequency), 100);
bool is52Defined  = Enum.IsDefined(typeof(Frequency), 52);
  1. What is written to the console?
  2. What is the value of is100Defined?
  3. What is the value of is52Defined?

First correct answer gets absolutely nothing (but think how great you’ll feel!)

Posted in C#, Daily Question at October 7th, 2009. 2 Comments.

Unit Testing DateTime.Now

I’m sure alot of you have come across a method that uses DateTime.Now at some point in your lives. Normally this is fine and nobody blinks an eyelid… until we need to unit test it.

Consider the follow code:

public class MyEntity
 {
   public DateTime Created { get; set; }
 }

 public class MyRepository
 {
   public void UpdateMyEntity(MyEntity entity)
   {
     entity.Created = DateTime.Now;
   }
 }

Unless you are one of one of those fancy pants with TypeMock and the ability to fake DateTime.Now, the rest of use must look elsewhere for a solution. Here are three different ways to solve this.

1. Wrap your DateTime calls with another class

Some people prefer using a static “Clock” class to handle this which can be easily faked out during your unit testing.

public static class Clock
{
    public static Func<DateTime> Now = () => DateTime.Now;
}

This approach, while decoupling your dependency on System.DateTime is a bit of overkill and requires all developers on the project to be aware of it and to use it.

2.Use an Interface and your favourite Isolation Framework

public interface IClock
{
  DateTime Now {get;}
}

public class SystemClock : IClock
{
  public DateTime Now { get { return DateTime.Now; } }
}

You can now use an isolation framework such as Rhino.Mocks to fake the call to Now();

3. Use a DateTime Comparer that accepts a range

While not 100% accurate to the millisecond, this approach is my prefered approach as you don’t have to change to your code just to unit test it. No littering your code with IClock dependencies or using a delegate to return the current DateTime.Now (although one could argue that DateTime.Now shouldn’t be a property to begin with). This approach asserts that the Created property that is set in MyRepository.Update is within a certain range.

 /// <summary>
 /// Helper class to compare 2 values are within a certain range.
 /// </summary>
 public class DateComparer : IComparer<DateTime>
 {
 public TimeSpan MarginOfError { get; private set; }

 public DateComparer(TimeSpan marginOfError)
 {
   MarginOfError = marginOfError;
 }

  public int Compare(DateTime x, DateTime y)  // x = expected, y = actual
   {
     var margin = x - y;
     if (margin <= MarginOfError)
       return 0;
     return new Comparer(CultureInfo.CurrentUICulture).Compare(x, y);
   }
 }

You can now write the follow test:

public void MyRepository_UpdateTest()
 {
   var repository = new MyRepository();
   var entity = new MyEntity();
   repository.UpdateMyEntity(entity);
   var comparer = new DateComparer(new TimeSpan(0, 0, 0, 5));
   Assert.IsTrue(comparer.Compare(entity.Created, DateTime.Now) == 0);
 }
Posted in .Net, C#, Unit Testing at September 7th, 2009. No Comments.

Unit Testing Expression Tree Equality

Sometimes you need to test whether two expressions are the same. However when you do a simple AreEqual() test on two expressions that look the same you get a negative result.

This method will fail

[TestMethod]
public void TestDoesNotWork()
{
  Expression<Func<int, int>> expressionA = x => x + 1;
  Expression<Func<int, int>> expressionB = x => x + 1;

  Assert.AreEqual(expressionA, expressionB);
}

This looks like it should work however it doesn’t. This is because when using anonymous expressions/delegates the CLR does some magic behind the scene to add a method on the fly, creating a new instance for every anonymous expression/delegate.

So if you have two expressions that are syntactically the same but not the same reference the easiest way to ensure they are the same is to compile the expression and invoke it comparing the resultant value.

[TestMethod]
public void TestDoesWork()
{
  Expression<Func<int, int>> expressionA = x => x + 1;
  Expression<Func<int, int>> expressionB = x => x + 1;

  Assert.AreEqual(expressionA.Compile().Invoke(3), expressionB.Compile().Invoke(3));
}

An alternate approach would be to de-construct each constituent part of the expression trees comparing each part as you go. This however is far more complex.

For a more real world example that involves using Rhino mocks and Expect calls please read on:

Read More…

Posted in .Net, C#, Unit Testing at August 25th, 2009. 4 Comments.

C# 3.0 – Variance Explained

The problem:

Why can’t I create a List of type Dog and assign it to a List of type Animal?

IList<Animal> animals = new List<Dog>(); // no good

Theory:

There are 3 terms relating to variance:

Covariance – allows more specific types to be assigned to more general types. (i.e. sub-types (classes, interfaces) can be assigned to any types (classes, interfaces) that they inherit from).

C# Example: Method Return types are Covariant. We can return a sub-type of the method’s declaring return type.


IAnimal GetAnimal(string animalName) {...};

GetAnimal("dog") {return new Dog();} // the dog is more specific and returned as the general type IAnimal
GetAnimal("cat") {return new Cat();} // the cat is more specific and returned as the general type IAnimal

Contravariance – allows general types to accept more specific types – i.e. The reverse of covariance.

C# Example: Method parameters are Contravariant. We can call a method with a parameter that is a sub-type of the parameters declaring type.


IAnimal GetAnimal(IAnimal animal) {...};
GetAnimal(new Dog()); // the method takes a general type IAnimal but is called with the more specific type Dog
GetAnimal(new Cat()); // the method takes a general type IAnimal but is called with the more specific type Dog

Invariance – occurs when neither of these conditions are met.

C# Example: In C# 3.0 Generics are invariant. C# 4.0 allows the variance of generics to be defined (with restrictions).


IList<Animal> animals = new IList<Animal>();
animals.Add(new Dog());
animals.Add(new Cat()); 

IList<Animal> animals = new List<Dog>();
animals.Add(new Dog());
animals.Add(new Cat()); // no dice. You can’t assign a cat to a list of dogs.

Posted in .Net, C# at July 30th, 2009. 2 Comments.

Two nice string extensions

Here’s a couple (well, one is an overload of the other) of string extension methods I wrote today which I’m quite fond of:


/// <summary>
/// Determines if any of the given matches are a case sensitive match for the
/// nominated string value
/// </summary>
/// <param name="text">The string value to be checked</param>
/// <param name="matches">The list of potential matches</param>
static public bool IsIn(this string text, params string[] matches)
{
    return IsIn(text, true, matches);
}

/// <summary>
/// Determines if any of the given matches are a case sensitive match for the
/// nominated string value
/// </summary>
/// <param name="text">The string value to be checked</param>
/// <param name="caseSensitive"><c>true</c> to perform a case
/// sensitive match</param>
/// <param name="matches">The list of potential matches</param>
static public bool IsIn(this string text, bool caseSensitive, params string[] matches)
{
    StringComparison comparer = caseSensitive
        ? StringComparison.CurrentCulture
        : StringComparison.CurrentCultureIgnoreCase;

    return matches.Any(value => text.Equals(value, comparer));
}


So instead of writing this:


if (name == "James" || name == "Peter" || name == "Sally")
    Console.WriteLine("Your name is too generic!");

You can simply write this:


if (name.IsIn("James", "Peter", "Sally")
    Console.WriteLine("Your name is too generic!");

No offence to the James, Peters, and Sallys of the world.

Posted in .Net, C# at July 9th, 2009. No Comments.