SEO

ASP.NET MVC meet SEO; SEO meet ASP.NET MVC

Whilst ASP.NET is clearly the best thing to hit .NET web development in a long-time it seems like the framework itself is somewhat challenged when it comes to SEO.   For starters the concept of a page has all but disappeared – sure you can have a ViewPage but there’s no code associated with it.  And sure, you have ASP.NET Routing so you can do anything you like with routes but the catchall route {Controller}/{Action}/{id} is as much a liability as it is a benefit as it catches things you really didn’t want it to catch and generates routes you really didn’t want to generate all too easily.

Convention over configuration is nice and all that, but sometimes a bit of configuration is necessary to bring your house into order, especially when the convention doesn’t allow things you really want for SEO.

So let’s take a look at all the things we really want to be able to do when creating an SEO friendly web site and see how we can get ASP.NET MVC to handle them.

For SEO we need:-

1. The ability to define a canonical url for a page.  To use that canonical URL whenever we generate a route.  To include that canonical url in the page header to instruct search engines that this is the canonical url for that page.

2. The ability to define multiple alternate URLs for a page.   Plans change and your site changes too but you don’t want 404 errors, you want the user to land on the same page even if you changed the URL to improve its SEO keyword content for example.  Ideally you’d like to 301 redirect these legacy urls but having them at least display the right page and including the canonical url in the header for that page is good enough.

3. The ability to use hyphens in urls.  But since Controllers are classes and Actions are methods and the convention is to use them as parts of the URL this isn’t supported out of the box.

4. The ability to define title, meta description and meta keywords tags for a page in such a way that you can enforce rules around them such as requiring every public page to have a title tag, or ensuring that the length of the title tag is reasonable, or ensuring that your product name is on the end of every title tag.

5. The ability to build a sitemap.xml file that we can submit to Google or Bing containing every URL that we want them to index.

In my next few posts I’ll explain how we can overcome all of these shortcomings of ASP.NET MVC to create a great SEO-friendly web site.

Stay tuned!

Building sitemap.xml for SEO ASP.NET MVC

Creating a sitemap.xml file for Google and other search engines can be accomplished in MVC using a simple ActionResult that returns the appropriate XML blog. The problem however is in generating the list of URLs to go into that sitemap.xml file.

In ASP.NET MVC there is no distinction between an action method that is a page and one that is a service call. To remedy that let’s create an ActionFilterAttribute that can be applied to any method to mark it as a page and to record the URL that we want that page to show up as in our sitemap:

1 /// <summary>

2 /// This attribute indicates that a method is an actual page and gives the data for it

3 /// </summary>

4 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]

5 public class MVCUrlAttribute : ActionFilterAttribute

6 {

7 public string Url { get; private set; }

8

9 public MVCUrlAttribute(string url)

10 {

11 this.Url = url;

12 }

13

14 public override void OnResultExecuting(ResultExecutingContext filterContext)

15 {

16 string fullyQualifiedUrl = filterContext.HttpContext.Request.Url.GetLeftPart(UriPartial.Authority) + this.Url;

17 // We build HTML here because we want the View to be easily able to include it without any conditionals

18 // and because the ASP.NET WebForms view engine sometimes doesn’t subsitute <% in certain head items

19 filterContext.Controller.ViewData["CanonicalUrl"] = @”<link rel=”"canonical”" href=”"” + fullyQualifiedUrl + ” />”;

20 base.OnResultExecuting(filterContext);

21 }

22 }

You may wonder at this point why we can’t just use the Routing table to figure this out. The issue is that multiple routes may map onto one page but we still want it to show up just once in the sitemap otherwise we will get slammed for duplicate content. We also want to be able to mark each page with its canonical URL.

Now we can use reflection to find all of the ‘pages’ in our ASP.NET MVC Application and then build a sitemap.xml file from them.

1 List<string> allPageUrls = new List<string>();

2

3 // Find all the MVC Routes

4 Log.Debug(“*** FINDING ALL MVC ROUTES MARKED FOR INCLUSION IN SITEMAP”);

5 var allControllers = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.IsSubclassOf(typeof(Controller)));

6 Log.DebugFormat(“Found {0} controllers”, allControllers.Count());

7

8 foreach (var controllerType in allControllers)

9 {

10 var allPublicMethodsOnController = controllerType.GetMethods(BindingFlags.Public | BindingFlags.Instance);

11 Log.DebugFormat(“Found {0} public methods on {1}”, allPublicMethodsOnController.Count(), controllerType.Name);

12

13 foreach (var publicMethod in allPublicMethodsOnController)

14 {

15 var mvcurlattr = publicMethod.GetCustomAttributes(true).OfType<MVCUrlAttribute>().FirstOrDefault();

16 if (mvcurlattr != null)

17 {

18 string url = mvcurlattr.Url;

19 Log.Debug(“Found “ + controllerType.Name + “.” + publicMethod.Name + ” <– “ + url);

20 allPageUrls.Add(url);

21 }

22 }

23 }

Seo for beginners

Many friends have asked me for advice on optimizing their site for search engines so I thought I’d put together some notes here collecting the advice I’ve handed out recently.

1. The first thing to do is to get a Google analytics account and add the tracking code to all your pages.  Unless you are measuring your current site’s performance you’ll never know how much you’ve managed to improve it.

2. If your site is a simple static site consider whether it would be better to create it using a content management system like WordPress than to try to do it yourself in HTML using Notepad (or some better tool).  WordPress will mostly do the right thing for you in terms of building a search engine optimized site.

3. Next, go to Google Adwords and figure out what keywords you should care about.  Start with the keyword phrases you think people might use to find your site and then use their keyword tools to expand those phrases to generate lists of keywords and their related volumes.  Look at the local search volume for local services or the global numbers.

4. Use the Google Adwords downloadable keyword tool to generate a CSV of all the ones that make some sense to you or if you prefer a more graphical approach, try my SEO Keyword Search tool which can give you an idea about how they are related and how important each is.

5. Armed with a list of keyword phrases sorted by volume you are now ready to start crafting pages for your site that will be found by people using Google, but before you start writing pages, check your domain name.  Is it really the best domain name for what you are offering.  Sure it’s nice to have a fancy company name and a domain name that matches but will people be finding you by word of mouth or will they in fact be using search engines, email links, links from other web pages, …?  If you plan to be the next Amazon.com one day, go ahead and use your fancy company name, otherwise, consider naming your site something highly functional that includes the keywords you want to be found using.

6. Make a plan for how you will map keywords to pages.  How many pages do you need? What words should be optimized on each page?

7. Build your site pages.  For each page, make a note (comment in HTML maybe) of the keywords for which you are optimizing that page.  I suggest putting them in the HTML so you remember never to change them by accident.  Using those keywords create an URL for the page, a Title, an H1 heading and ideally some bold text and some images with ALT text including those keywords.  Create a meta keywords tag including just those words (arguably search engines mostly ignore the keywords meta tag now).  Create a meta description that is actionable because this is likely to be the line your customers see in Google – use verbs, explain why your page is interesting, encourage them to click through to you.  Don’t use the same description on every page on you site, make it relevant to the page it is on.

8. If you ever move a page that has been indexed, be sure to use a 301 redirect to transfer the user to the new page and to tell the search engines where to go.

9. Make sure all your pages are accessible through links on the site.  A site map down the bottom of the page listing all the pages on your site is a good way to do this.

10. Use Google.com/Webmasters to check your site for mistakes.

11. Update your site frequently so that Google thinks that it’s newsworthy and so that they index you more often.

12. Consider putting your blog on your site (or using WordPress make blog and site the same thing with Pages and Posts as appropriate).

13. Get the free tools from SeoMoz, use them to check each page of your site to make sure you have URL, Title, H1, B tags all containing the keywords for that page.  Make sure your meta description tag is what you’d want the user to see if they found your page in Google.

14. Once your site is keyword optimized now it’s all about inbound links from relevant sites but only ones that aren’t ‘nofollow’ on their links.  SeoMoz has a toolbar for Firefox that will show you whether links on a page are nofollow.  Visit relevant sites where you can comment and include a link back to your site.  If SeoMoz shows the link backs in pink, don’t bother commenting, go find somewhere else that will give you some credit for your work in crafting relevant comments.

15. Do not pay for any links from directory sites or otherwise.  Google and Bing discount them and may even penalize you for doing them.

16. Do list your business on Bing and Google local business listings

17. Some of the free press release sites and article sites can be worthwhile – write some articles and seed them, but check them with SeoMoz first to see if the links are marked ‘nofollow’.

18. Don’t do anything “black hat”!  No hidden white text just for the search engines, no cloaking, no browser detection to show different content, …

WordPress Plugins I’ve found useful so far

Broken Link Checker
Checks your posts for broken links and missing images and notifies you on the dashboard if any are found.

Flash Photo Gallery
Creates a Flash Photo Gallery like one provided in Adobe Photoshop CS2 Flash Web Photo Gallery templates.

Google XML Sitemaps
This plugin will generate a special XML sitemap which will help search engines like Google, Yahoo, Bing and Ask.com to better index your blog.

HeadSpace2
Meta-data manager on steroids, allowing complete control over all SEO needs such as keywords/tags, titles, description, stylesheets, and many many other goodies.

Next Page
Provides shortcodes and template tags for next/previous navigation in pages.

Page Flip Image Gallery
FlippingBook Photo gallery plugin with page flip effects.

Page Tagger
Enables tagging for pages. PHP 5 required.

Photo Dropper
Lets you add Creative commons licensed Photos to Your Posts from Flickr. By activating this plugin you agree to be fully responsbile for adhering to Creative Commons licenses for all photos you post to your blog.

Useful 404′s
Create more useful 404 error pages, including email notifications for bad links. See http://www.alistapart.com/articles/amoreuseful404 for the inspiration behind this plugin.

SEO Keyword Tool in Action

Here’s an example of the SEO Keyword Search Tool in action, untangling the subject of ‘digital signage’ and some related keywords.  Larger boxes indicate more searched-for terms, thicker lines indicate stronger connections.

SEO Keyword diagram