MVC 3 XML Sitemap

Ok, so you’ve got your shiny new mvc3 app up and running. Now, it’s time to bake in some of that SEO goodness. Here’s how you can easily add a sitemap.xml to your new mvc application. The solution specified below not only pumps out the xml file to submit to the search engines, but it is also a System.Web.SiteMapProvider, so you can use it for menus and wherever else you want to use your sitemap.

I’m a big fan of NuGet, so bring up the Package Manager Console and grab MvcSiteMapProvider (or download it from github).

Install-Package MvcSiteMapProvider

Once it is installed there will be a new Mvc.sitemap file added with the following to your solution:

<mvcSiteMapNode title="Home" controller="Home" action="Index">
    <mvcSiteMapNode title="About" controller="Home" action="About"/>
</mvcSiteMapNode>

Now for the easy bit: to get a ~/sitemap.xml to auto-generate for us based on our controller actions we specified in the sitemap file above. All you need to do is simply add the following to your route registration (generally Global.Application_Start()):

XmlSiteMapController.RegisterRoutes(RouteTable.Routes);

Now, like a lot of other people out there my next question was, what about my dynamically generated content from the database (such as Product/Details/1)?  Easy – MvcSiteMapProvider comes with dynamic node support. Just create a class like the following:


public class ProductDetailsDynamicNodeProvider : DynamicNodeProviderBase
 {
     public override IEnumerable<DynamicNode> GetDynamicNodeCollection()
     {
         // Create a node for each product
         foreach (Product product in productService.GetAllProducts())
         {
             var node = new DynamicNode();
             node.Title = product.Name;
             node.RouteValues.Add("id", product.Id);

             yield return node;
         }
     }
     public override CacheDescription GetCacheDescription()
     {
        return new CacheDescription("ProductDetailsDynamicNodeProvider")
        {
            SlidingExpiration = TimeSpan.FromMinutes(60);
        };
    }
 }

Things to note with the above code: you don’t have to override the cachedescription method, but this does allow us to specify how long all our products will be cached for in the sitemap. Then, you can add your dynamic node to the mvc.sitemap files as follows:

<mvcSiteMapNode title="Details" action="Details"
dynamicNodeProvider="Website.ProductDetailsDynamicNodeProvider, Website"/>

Now you are done and have a working auto-generated mvc sitemap. For those of us who are using it to generate breadcrumbs, check out the awesome example of html helpers in the documentation.

Next time, I’ll be looking at creating SEO friendly URLs in MVC.

Posted in .Net, Asp.Net, Xml at January 8th, 2012. No Comments.

Overriding the default serialization behavior in Json.NET

We use Newtonsoft Json.NET heavily in our project to control our JSON serialization. For the most part, it works absolutely perfectly out-of-the-box, but every now and then, we need to customize the way that serialization works for a particular object.

Such an occasion occurred today. Basically, I have a list of EmployeeActivity objects – where each instance is a subclass of EmployeeActivity. So, for example:

public abstract class EmployeeActivity
{
    public TimeSpan Start { get; set; }
    public TimeSpan Stop { get; set; }

    public virtual bool IsAvailable
    {
        get { return false; }
    }
}

public class AbsenceActivity : EmployeeActivity
{
    public string Reason { get; set; }
}

public class BreakActivity : EmployeeActivity
{
    public string BreakName { get; set; }
}

json.NET does a perfect job of serializing my objects, and they rebuild perfectly when I’m back in javascript land – however, I have no way of knowing the actual type of each activity in my array! To alleviate this, I wanted to create my own serializer which also injected the type name into each of the serialized objects – or at least, that’s what I thought I wanted to do!

As it turns out, there’s a bit of an easier option. JsonConvert uses a ContractResolver in order to work out how to Serialize/Deserialize each class, and you can override the default contract resolver when running serialization:

// This class contains the activity list
ActivityViewModel = new ActivityViewModel(DateTime.Today);

// Serialize using a custom contract resolver
string jsonViewModel = JsonConvert.SerializeObject(viewModel,
    Formatting.None, new JsonSerializerSettings
    {
        ContractResolver = new ActivityJsonContractResolver()
    });

The contract resolver’s job is to return a JsonContract which describes the object to be returned. For a POCO, this would typically be an instance of JsonObjectContract, which (amongst other things) describes the properties of the class which should be serialized.

So, all I needed to do was to extend the contract for subclasses of EmployeeActivity, such that it inherited a new Property to be serialized:

public class DiaryActivityJsonContractResolver : DefaultContractResolver
{
    protected override JsonObjectContract CreateObjectContract(Type objectType)
    {
        JsonObjectContract contract = base.CreateObjectContract(objectType);

        if (typeof(EmployeeActivity).IsAssignableFrom(objectType))
        {
            contract.Properties.Add(new JsonProperty
            {
                Readable = true,
                ShouldSerialize = value => true,
                PropertyName = "Type",
                PropertyType = typeof(string),
                Converter = ResolveContractConverter(typeof(string)),
                ValueProvider = new StaticValueProvider(objectType.Name)
            });
        }

        return contract;
    }
}

Truth be told, I’m not 100% sure if I need to implement as many of the properties on the JsonProperty that I’m creating. But you can see what’s going on here – I’m effectively telling the object contract that there’s an additional property called Type which needs to be serialized, that it’s a string, and that it should return whatever value is resolved by the StaticValueProvider. Speaking of which, here’s the last piece of the puzzle – a simple value resolver that always returns the same value:

/// <summary>
/// JSON value provider that always returns a static value
/// </summary>
public class StaticValueProvider : IValueProvider
{
    private readonly object _staticValue;

    public StaticValueProvider(object staticValue)
    {
        _staticValue = staticValue;
    }

    public void SetValue(object target, object value)
    {
        throw new NotSupportedException();
    }

    public object GetValue(object target)
    {
        return _staticValue;
    }
}

json.NET is fantastic, and it’s very extensible, but finding out where to start and what to do can be a little bit tricky. I managed to figure this out only by downloading the source files and poking through the code myself; hopefully this will be helpful to someone else in the same situation!

Posted in Asp.Net, C# at August 8th, 2011. No Comments.

Extension methods for base/derived types

I had a situation today which I thought was prime for writing some extension methods: I wasn’t allowed to modify the original type, and I also couldn’t subclass it, either. Extension methods to the rescue!

One thing which made the situation slightly interesting though, was that the original type also had a whole bunch of derived types – and for each of them, I wanted to customise the relevant extension method! Well, that’s all well and good, but what I really wanted to know was: lets say I was operating on a collection of the base types (where each individual item was an instance of a derived type), which extension method would get invoked?

Only one way to find out – write some code! For simplicity, I used the base class Animal, and added two derived types: Dog and Elephant.

    public abstract class Animal
    {
        public string Name { get; set; }
        public bool HasBoyBits { get; set; }
        public abstract string Type { get; }
    }

    public class Dog : Animal
    {
        public string Breed { get; set; }

        public override string Type
        {
            get { return "Dog"; }
        }
    }

    public class Elephant : Animal
    {
        public bool HasTusks { get; set; }

        public override string Type
        {
            get { return "Elephant"; }
        }
    }

Now for the extension method: CanBreed. For the base type Animal, the rule was simple – the animals had to be of the same type, and of the opposite sex:

    public static class AnimalExtensions
    {
        public static bool CanBreedWith(this Animal animal, Animal other)
        {
            return animal.Type == other.Type
                && animal.HasBoyBits != other.HasBoyBits;
        }
    }

For dogs, we only want to breed with dogs that are already of the same pedigree; and for elephants, we only want to breed with other elephants that have the same tusk status (yes, it’s pretty ambiguous, but whatever):

    public static class DogExtensions
    {
        public static bool CanBreedWith(this Dog dog, Animal other)
        {
            return AnimalExtensions.CanBreedWith(dog, other)
                && ((Dog) other).Breed == dog.Breed;
        }
    }

    public static class ElephantExtensions
    {
        public static bool CanBreedWith(this Elephant elephant, Animal other)
        {
            return AnimalExtensions.CanBreedWith(elephant, other)
                && ((Elephant) other).HasTusks == elephant.HasTusks;
        }
    }

Finally, the test data: two lists of animals, separated by gender:

    var baxter = new Dog { Name = "Baxter", HasBoyBits = true, Breed = "Jack Russell" };
    var missy = new Dog { Name = "Missy", HasBoyBits = false, Breed = "Jack Russell" };
    var jazzy = new Dog { Name = "Jazzy", HasBoyBits = false, Breed = "Poodle" };

    List<Animal> boys = new List<Animal>
    {
        baxter,
        new Elephant { Name = "Lance", HasBoyBits = true, HasTusks = true }
    };

    List<Animal> girls = new List<Animal>
    {
        missy,
        jazzy,
        new Elephant { Name = "Renee", HasBoyBits = false, HasTusks = true },
        new Elephant { Name = "Hephalump", HasBoyBits = false, HasTusks = false }
    };

Now, what I had to test was if .NET would use the Runtime type of each animal to work out which extension method to invoke. I was pretty confident that both of these would pass:

    Assert.IsTrue(baxter.CanBreedWith(missy));
    Assert.IsFalse(baxter.CanBreedWith(jazzy));

And sure enough, the unit test succeeds with flying colours. However, to make things slightly trickier, what if we do this?

    foreach (var boy in boys)
    {
        foreach (var girl in girls)
        {
            bool canBreed = boy.CanBreedWith(girl);

            Console.WriteLine("{0} can{2} breed with {1}",
                boy.Name, girl.Name, canBreed ? String.Empty : "'t");
        }
    }

Unfortunately, here’s what the output looks like:

Baxter can breed with Missy
Baxter can breed with Jazzy
Baxter can’t breed with Renee
Baxter can’t breed with Hephalump
Lance can’t breed with Missy
Lance can’t breed with Jazzy
Lance can breed with Renee
Lance can breed with Hephalump

So we can see that the animals aren’t allowed to breed when they’re of differing types (hence AnimalExtensions.CanBreedWith is being invoked); however, each type of animal is allowed to breed with any other animal of the same type. No joy! (Well, joy for the animals I suppose…)

On retrospect, this is pretty much the behavior that I expected, but I was still disappointed to find out that I had been right. Worse still, once the sample code was up and running, I thought, “Hey, I should have used Rabbits instead of Elephants, and then always returned false in the CanBreed method, because that would have been funnier”. Ahh, hindsight, where were you before?

Oh well. Time for some refactoring!

Posted in .Net, C# at July 25th, 2011. 1 Comment.

Fixing debugging displays with ToString()

Debugging can be tricky when you’re trying to inspect a collection of objects that superficially all look the same! But there’s a few things you can do to alleviate that problem, and a few gotchas to try and avoid, too.

Lets say you have a simple class called TimeRange, which defines a start time and an end time, and also has a calculated property for the length of time it represents. Your class might look something like this:

public class TimeRange
{
    public TimeSpan Start { get; set; }
    public TimeSpan End { get; set; }

    public TimeSpan Length
    {
        get { return End.Subtract(Start); }
    }
}

Now, lets say you create a list of these Time Ranges. When you debug your file, inspecting the list will give you a picture like this:

Unhelpful time ranges

That’s not very helpful now, is it?! It would be much easier to work out what was going on if the debugger showed us a little bit about each time range, rather than simply the object type’s full name.

Thankfully, it’s actually pretty easy to customise what the debugger displays during object inspection using one of two methods:

  • The “hard” way: Decorate your class with the DebuggerDisplayAttribute (which you can read about here). Essentially, this allows you to write custom text, and/or an expression which will be evaluated by the debugger when inspecting an object.
  • The “easy” way: Override the ToString() method! This is what the debugger uses by default to display information about your object.

(Note: If you override the ToString() method as well as decorate your class with the DebuggerDisplayAttribute, the attribute will take precedence.)

So, with that in mind, lets override ToString() to fix our debugging display:

override public string ToString()
{
    return String.Format("{0:hh:mm} - {1:hh:mm} (Length: {2:h}h {2:mm}m)",
        Start, End, Length);
}

And now lets run our debugger and check out… hey, wait a minute! Our debugging display hasn’t changed! What’s going on? I thought overriding ToString() would change what the debugger shows when inspecting our objects! Lets use a hammer to crack a nut, and add in the DebuggerDisplayAttribute as well:

[DebuggerDisplay("{ToString()}")]
public class TimeRange

And now lets see what we get:

Slightly more helpful...

Ah ha! We have a problem with our String.Format() statement – it turns out the formatting strings that we’ve used for the TimeSpan instances are incorrect. So, lets fix our formatting string, and remove the DebuggerDisplay attribute. Here’s how our class looks now:

public class TimeRange
{
    public TimeSpan Start { get; set; }
    public TimeSpan End { get; set; }

    public TimeSpan Length
    {
        get { return End.Subtract(Start); }
    }

    override public string ToString()
    {
        return String.Format(@"{0:hh\:mm} - {1:hh\:mm} (Length: {2:%h}h {2:mm}m)",
            Start, End, Length);
    }
}

And here’s what we see when we inspect a list of Time Ranges in the debugger:

Much better!

Much better!

Posted in C# at July 19th, 2011. 1 Comment.

IList and Covariance

Now that I’m developing in .NET 4.0 I thought all my covariance problems were behind me. This was until I tried to use the following:


public class  Animal {
    public void AttackOtherAnimals(IList<Animal> animals) { }
}

public class Dog : Animal { }

Dog angryDog = new Dog();
List dogsToAttack = new List<Dog>();
angryDog.AttackOtherAnimals(dogsToAttack);

Turns out, IEnumerable<T> has support for covariance, IList<T> does not. I’d like to thank Marc Gravell for his excellent writeup on this.

One way around this (instead of dogsToAttack.Cast<Animal>().ToList()) is to use generics to accept any IList<T> where T is of type Animal.

public void AttackOtherAnimals(IList<T> animals) where T : Animal { }
Posted in .Net at April 21st, 2011. No Comments.

jQuery Intellisense Support in Content Pages

I was trying my hand at whipping up some jQuery today and realising the awesome intellisense that is provided, couldn’t wait to get stuck in. Since I do enjoy adhering to the DRY principle wherever possible I decided I needed to use master pages first before I create my example content. I then set out to try and do a basic hello world example but realized my intellisense wasn’t working with jQuery. It was working with vanilla ASP .NET pages, just not content pages.

It turns out, that VS uses -vsdocs javascript files to provide this support. It requires it to be sitting next to your jquery file that you are referencing. Which it was thanks to the MVC Internet Application project template. It seems that ASP .NET doesn’t know at design time that I’m referencing jQuery in the master page.

After asking Professor Google, I stumbled upon a solution. I decided to slap the following bit of code into any content page that I have created and want some good ol’ intellisense.

<% #if (false) %>
<script src="~/scripts/jquery-1.4.4.js" type="text/javascript"></script>
<% #endif %>

Yes, this is a bit of hack to get it working and yes, I would like Microsoft to fix it. In the mean time, I will be egarly awaiting the intellisense support to be released for the latest 1.5 version.

UPDATE: I’ve just found that somebody has generated a new vsdoc for jQuery 1.5

UPDATE 2: If you reference your jQuery from the Microsoft CDN, you get intellisense since they also host the vsdoc files. Sadly, the Google CDN does not.

Posted in Asp.Net at February 3rd, 2011. 2 Comments.

CSS Case Sensitivity

Your learn something new everyday. Today I learnt that CSS is case sensitive. No big deal. What I do find perplexing though is the fact that a) html attribute selection is case insensitive and b) alot of older browsers (or those running in quirks mode) implement CSS class selection as case insensitive. It is probably easiest to just use lowercase to avoid any potential issues with your stylesheets!

Posted in .Net at December 2nd, 2010. No Comments.

Varchar, Nvarchar and Entity Framework

Further to my previous post about a bug with Entity Framework 1.0, I’ve have discovered another bug but this time due to its handling of varchars.

Let’s assume we’re using the following query:

var query = context.Orders.Where(o => o.Customer.Address.Country == "Australia");

If our Country column is a varchar Entity Framework will pass through our “Australia” string as an nvarchar parameter regardless of what we define in our SSDL!
Now has is this a bad thing you may ask? Well what this means is that even if we have an index on our country column, SQL Server will have to do an index scan rather than an index seek because it has to convert the nvarchar “Australia” down to a varchar and do the comparison across every row in the table.

Thankfully there is a workaround .

This problem has also been addressed in EF 4.0 as well.

Posted in .Net, C#, Sql Server at September 23rd, 2010. No Comments.

Question of the day: Threading

Here’s a little question about Threading – this would be a great interview question, in my opinion!

Given the code below:

public class Producer
{
    [ThreadStatic]
    readonly static private Producer _instance = new Producer();

    static private int _instanceCount;
    readonly private int _instanceId;

    private Producer()
    {
        _instanceId = ++_instanceCount;
    }

    static public Producer Instance
    {
        get { return _instance; }
    }

    public string Name
    {
        get
        {
            return String.Format("Instance {0} of {1}",
                _instanceId, _instanceCount);
        }
    }
}

public class Consumer
{
    public Consumer()
    {
        Thread t1 = new Thread(IdentifyProducer);
        t1.Start();

        Thread t2 = new Thread(IdentifyProducer);
        t2.Start();

        t1.Join();
        t2.Join();
    }

    public void IdentifyProducer()
    {
        Console.WriteLine(Producer.Instance.Name);
    }
}

What will happen when you create a new instance of the Consumer class?

Posted in Daily Question, Threading at June 30th, 2010. 2 Comments.

Star Sizing and Grid Size Sharing in WPF

They don’t work together. Full stop. Thank you Microsoft. The only way around this is to manually bind your columns/rows of one grid to another instead of using star sizing. Thanks to this article we can use this:

<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding ElementName=OtherGrid}, Path=ColumnDefinitions[0].Width}" />
</Grid.ColumnDefinitions>
Posted in .Net at June 22nd, 2010. No Comments.
Quickduck logo