Cyotek.com runs on its own custom CMS/blog engine developed in ASP.NET MVC 1.0, which has a number of advantages and disadvantages. One of these disadvantages is no automatic support for some common blog features such as trackbacks and pingbacks.
This article will describe how to create a trackback handler for use with MVC and the more traditional webforms.
What is a trackback?
A trackback is a way to be notified when a website links to a resource on your own site. Some blogging software supports automatic linking, so if a post on that site links to another, when the post is submitted, it will automatically detect the link and attempt to send a trackback to the original author. If successful, a link is generally created from the original author to the new post, thus building a web of interconnected resources (in theory). You can learn a little more about trackbacks from Wikipedia.
The full trackback specification can be viewed at the SixApart website
A trackback handler in C#
Unlike pingbacks (which we'll address in a future article), trackbacks use standard HTTP requests and so are extremely easy to implement.
Available for download at the end of this article is a sample library which you can use to implement your trackbacks.
As a trackback is comprised of several pieces of information which we'll be passing about, we'll start by defining a structure to hold this information.
The properties of this structure mirror the required information from the trackback specification.
Next, we'll define an enum for the different result codes you can return. The specification states 0 for success and 1 for error, but I'm uncertain if you can extend this, ie is any non-zero is classed as an error. We'll play it safe and just use a single error code.
I'd considered two ways of implementing this, the first being an abstract class containing methods which must be implemented in order to provide the functionality for saving a trackback into your chosen data source, or using delegates. In order to make it a simple as possible to use, I've went with the latter. Therefore, we need two delegates, one which will resolve the "permalink" for the given ID, and another to actually save the trackback.
Implementing the handler
We've created a static class named
contains all the functionality we'll need. We expose a single
GetTrackback, which will return the XML block
required to notify the sender of the result of the request.
This function accepts the following arguments:
NameValueCollectionholding the submitted trackback data - supporting both the MVC
- An implementation of the
SaveTrackbackDelegatedelegate for saving the trackback to your chosen data store.
- An implementation of the
GetTrackbackUrlDelegatefor resolving a permalink URL of the given ID.
Assuming none of these are null, the method then calls a private overload, explicitly specifying the individual items of data.
First, we validate that the request is being made via a
and not any other HTTP request, and that both the entry ID and
the URL of the sender are specified.
If everything is fine, we then construct our
object for passing to our delegates, and then try and get the
permalink for the trackback ID.
If we don't have a URL, we return an error code to the sender.
If we do have a URL another method,
called. This method will download the HTML of the caller and
attempt to verify if the senders page does in fact contain a
link matching the permalink. If it doesn't, then we'll abort
If the method is successful and a link is detected, the method will return the title of the senders HTML page as an out parameter. This will be used if the trackback information didn't include a blog name (as this is an optional field).
Finally, if everything went to plan, we save the trackback to our data store, and return a success code. In the event of any part of this process failing, then we return an error result.
Downloading the senders html and checking if a link exists
In this implementation, we won't link to the senders site unless they have already linked to us. We do this by downloading the HTML of the senders site and checking to see if our link is present.
GetDocumentTitle uses the Html Agility Pack
to parse the HTML looking for the title tag. As the
CheckSourceLinkExists function is only checking to see if the
link exists somewhere inside the HTML you may wish to update
this to ensure that the link is actually within an anchor tag -
the Html Agility Pack makes this extremely easy.
Returning a response
In several places, the
GetTrackback method calls
GetTrackbackResponse. This helper function returns a block of
XML which describes the result of the operation.
Implementing an MVC Action for handling trackbacks
In order to use the handler from MVC, define a new action which
ContentResult. It should only be callable from a
POST, and ideally it shouldn't validate input. Even if you
don't want HTML present in your trackbacks, you should strip any
HTML yourself - if you have ASP.NET validation enabled and an
attempt is made to post data containing HTML, then ASP.NET will
return the yellow screen of death HTML to the sender, not the
nice block of XML it was expecting.
Simply return a new
ContentResult containing the result of the
GetTrackback method and a mime type of
In this case, I'm also checking the query string for the ID of the article to link to as we use a single trackback action to handle all resources. If your trackback submission URL is unique for resource supporting trackbacks, then you wouldn't need to do this.
The implementations of your two delegates will vary depending on how your own website is structured and how it stores data. As an example I have included the ones used here at Cyotek.com (Entity Framework on SQL Server 2005 using a repository pattern):
Implementing an ASP.NET Webforms trackback handler
Using this library from ASP.NET webforms is almost as straightforward. You could, as in the example below, create a normal page containing no HTML such as trackback.aspx which will omit the XML when called.
Ideally however, you would probably want to implement this as a HTTP Handler, although this is beyond the scope of this article.
Providing the trackback URL
Of course, having a trackback handler is of no use if third party sites can't find it! For sites to discover your trackback URLs, you need to embed a block of HTML inside your blog articles containing a link to your trackback handler. This URL should be unique for each article. For cyotek.com, we append the ID of the article as part of the query string of the URL, then extract this in the controller action, but this isn't the only way to do it - choose whatever suits the needs of your site.
The following shows the auto discovery information for this URL:
It includes the trackback URL (with article ID 21) and the title of the article, plus the permalink.
Cyotek.com doesn't get a huge amount of traffic, and so this library has not been extensively tested. It has worked so far, but I can't guarantee it to be bug free!
Possible enhancements would be to add some form of deny list, so if you were getting spam requests, you could more easily disable these. Also the link checking could be made more robust by ensure its within a valid anchor, although there's only so much you can do.
I hope you find this library useful, the download link is below. As mentioned, this library uses the Html Agility Pack for parsing HTML, however you can replace this if required with your own custom solution.
- 2010-09-22 - First published
- 2020-11-21 - Updated formatting
Like what you're reading? Perhaps you like to buy us a coffee?