Dynamic sitemaps with ASP.NET MVC

by October 16, 2008 02:40 PM

I read Jeff Atwood’s post on The Importance of Sitemaps and thought I'd utilize one from the get-go on a site I'm creating for a side project. Seemed simple enough... Well, it didn't turn out a quick 5 minute task like I hoped.

Basically there were two issues. How to return raw content and how to get the encoding right.

How to return raw content was actually pretty easy to find. There's a method on System.Web.Mvc.Controller called Content that accepts a string, the content type, and the encoding. Perfect.

Now, this is probably easy to most, but I've never had to worry about encoding so this one took me a while to get right. First when I tried to serialize my xml document to a string, I ended up with utf-16 in the xml declaration. I knew that's not right because the sitemap specification specifically says it needs to be utf-8.

Help me Google!

The Google gods provided a lot of stuff... and a lot of rabbits to chase and a lot of less than perfect solutions. It was insane how much junk I came across. Many of which provided solutions that basically hacked the phrase "uft-8" into the xml declaration even though the document was physically still utf-16.

In the end I obviously figured it out - or at least, I figured out a solution that works for me and one I feel is somewhat slick. The code:

public ActionResult Sitemap()
{
   XNamespace xmlns = "http://www.sitemaps.org/schemas/sitemap/0.9";
   var root = new XElement(xmlns + "urlset");

   var repository = IoC.Resolve<IRepository<Location>>();
   foreach (var location in repository.FindValid())
   {
      object routeValues =
         new
            {
               state = location.State,
               location = location.Name,
               controller = "Agenda",
               action = "List"
            };

      root.Add(
         new XElement("url",
            new XElement("loc", GetUrl(routeValues)),
            new XElement("changefreq", "daily")));
   }

   var memoryStream = new MemoryStream();
   using (var writer = new StreamWriter(memoryStream, Encoding.UTF8))
      root.Save(writer);

   return Content(
      Encoding.UTF8.GetString(memoryStream.ToArray()),
      "text/xml",
      Encoding.UTF8);
}

The main part that took me so long to figure out is the last part where I'm trying to return the XElement I created. The keys ended up being the use of MemoryStream, StreamWriter with the UTF8 argument, and finally using Encoding.UTF8 to get the string to pass to Content().

That's it for the problems that held me up. I would like to add a final note about a problem I'm still having though. Notice the line where I'm calling GetUrl(). That's a utility method I wrote to get a full url from within the controllers. It's easy as pie from within the views, but I haven't found a built in easy way to do it within the controllers - or anywhere else where you don't have an HtmlHelper to play with. Here is that method, but I am still hopeful that an easier built in method exists that I just haven't found yet.

protected string GetUrl(object routeValues)
{
   var values = new RouteValueDictionary(routeValues);
   var context = new RequestContext(HttpContext, RouteData);

   var url = RouteTable.Routes.GetVirtualPath(context, values).VirtualPath;

   return new Uri(Request.Url, url).AbsoluteUri;
}

Happy coding!

Tags: ,

Project Architecture

by October 4, 2008 06:13 AM

I read and loved the series of posts called The Onion Architecture by Jeffrey Palermo. As he put it:

The main premise is that it controls coupling. The fundamental rule is that all code can depend on layers more central, but code cannot depend on layers further out from the core. In other words, all coupling is toward the center. This architecture is unashamedly biased toward object-oriented programming, and it puts objects before all others.

Sweet! Everything a good architecture astronaut such as myself would love. Well, I thought I’d see how well it performed down here where the oxygen is breathable. I’m currently working on a side project for a buddy at work and thought that it would be the perfect test bed as there isn’t a hard deadline for it.

So, here is our “Agenda Management System”. Basically it’s going to expose city council voting records in new and interesting ways.

VS Solution

This is the actual solution. Two of the projects you see exist in every project I create no matter what the chosen architecture is: _build and Tests. _build contains deploy scripts and all of my project dependencies that aren’t “out of the box”. The Tests project contains all of my unit tests (there aren’t many – yes, I suck at this still). The other three projects make up the “onion”.

image

The most interesting parts of the solution to me are the dependencies. You can see here that Core doesn’t reference anything. That means everything my domain objects and services could possibly need have to live within the Core project. Sounds reasonable until you realize they will at some point need data from the database and to log information. The details of those concerns aren’t “domain” type things of course so they live in the infrastructure project. But Core doesn’t reference Infrastructure! Oh my.

This is where the Dependency Inversion principle comes into play. Basically, anything the domain layer could need that isn’t a “domain” type of concern is split into a contract and implementation. The contract (interface) lives within Core and the implementation lives within Infrastructure. The two are tied together only once at application startup.

Full Solution

Hopefully the image to the left isn’t too tiny to see, but basically there are three players required to make this work smoothly. The class IoC in Core is a static container for the interface of an inversion of control container that will resolve interfaces for me. The InversionOfControlContainer in Infrastructure is the implementation of the container defined in Core. At application startup in the Global.asax, I tie the two together.

So in Global.asax.cs you’ll see this:

protected void Application_Start()
{
IoC.Initialize(new InversionOfControlContainer());

You can probably imagine that all I'm doing in "Initialize" is setting a private static variable that will be referenced throughout the rest of the application’s lifetime. For example, a method on IoC is:

public static T Resolve<T>() { return iocContainer.Resolve<T>(); }

And I use IoC like this:

IoC.Resolve<IUnitOfWork>().Begin();

Of course, note that in this situation, both the interface IUnitOfWork and it's implementation are in Infrastructure, but the use of IoC is the point :)

Well, hopefully that conveys my implementation of The Onion Architecture. I must say, this is something that I’m finding extremely pleasant to work with. Due to the fact that Core doesn’t reference Infrastructure, I’m forced to find solutions strictly in terms of my domain and the repositories. Very cool stuff indeed!

Happy coding!

Tags: , ,

Mocking with rhino mocks follow up

by May 22, 2008 08:11 PM

This is just a quick follow up to my Mocking with Rhino Mocks post.

You can see the entire thread here, but the essence of it is this.

DynamicMock creates a mock where all unexpected calls are ignored with no error. So, if we were to create a dynamic mock and then set an expectation that a method on it is called twice, there would be a requirement for two calls, but a third cal would just be ignored rather than cause an error.

If we absolutely want the behavior of an exact number of calls, then use CreateMock instead of DynamicMock. Nice and simple solution :)

Tags: ,

Mocking with Rhino Mocks

by May 16, 2008 05:29 PM

Ok, myself and a couple of colleagues spent a ton of time today scratching our heads because of an odd behavior in Rhino Mocks. Basically, we set an expectation, set the expectation to repeat only once, and then were surprised to see a passing test when we knew the actual code was calling the expectation too many times. So we created the below example. The test in the example should fail, but it passes.

using NUnit.Framework;
using Rhino.Mocks;

namespace UnitTests
{
   public interface IMyTestInterface
   {
      void MyTestMethod();
   }

   [TestFixture]
   public class RepeatTests
   {
      [Test]
      public void Test()
      {
         var mockery = new MockRepository();
         var myMock = mockery.DynamicMock<IMyTestInterface>();

         using (mockery.Record())
         {
            myMock.MyTestMethod();
            LastCall.Repeat.Once();
         }
         using (mockery.Playback())
         {
            myMock.MyTestMethod();
            myMock.MyTestMethod();
         }
      }
   }
}

Now to do some searching and querying to figure out what we're doing wrong.

Tags: ,

Throwing Exceptions

by May 1, 2008 03:56 AM

I wanted to capture this in case I ever find myself trying to present this concept again and am failing to come up with a simple example that works. It's about exception handling in C#. I've known about this issue for quite some time and tried to present the problem to an internal user group where I work. Unfortunately the example I came up with didn't provide the expected result and we spent the whole presentation floundering around with the damn thing. Kudos to a buddy of mine for taking the time one weekend to come up with this working version (Thanks Paul).

Basically, when you catch exceptions, the way you re-throw them has a very important impact on the stack trace of the exception when it is caught later. Below is the code in its entirety. I'm mostly putting it here for reference, but would be glad to answer any questions you may have.

using System;

namespace ThrowSpike
{
   class Program
   {
      static void Main()
      {
         try
         {
            Console.WriteLine("ThrowOnly...");
            ThrowOnly();
         }
         catch (Exception ex)
         {
            Console.WriteLine(ex); // See a good stack trace
         }

         try
         {
            Console.WriteLine("ThrowCaughtException...");
            ThrowCaughtException();
         }
         catch (Exception ex)
         {
            Console.WriteLine(ex); // See an bad stack trace
         }
      }

      private static void ThrowOnly()
      {
         try
         {
            ThrowException();
         }
         catch
         {
            throw;
         }
      }

      private static void ThrowCaughtException()
      {
         try
         {
            ThrowException();
         }
         catch (Exception ex)
         {
            throw ex;
         }
      }

      private static void ThrowException()
      {
         throw new ApplicationException("This is a test");
      }
   }
}

Tags: