Keyvan Nayyeri

God breathing through me

How to Implement Trackback Handler in ASP.NET

Back in May I wrote a blog post as a guide to implement MetaWeblog API in ASP.NET. There are some common features among modern blogging engines and MetaWeblog API is one of them. Other features are trackbacks and pingbacks as two mechanisms to connect related content between two blogs or sites.

Even though these two concepts are spam-prone but in my honest opinion they worth it to be there. Trackbacks and pingbacks can let us find the related content much easier than any other option like Technorati reactions or Google blog search!

So I think it’s worthwhile to write a short tutorial about implementing a trackback handler in ASP.NET. There is a forthcoming guide for pingback handler as well.

Overview

Trackback is one of the common concepts among internet content providers (especially bloggers) and refers to a link between a page on the internet that refers to another and that destination page. Trackback is stored automatically via a mechanism provided on both ends and is shown as a regular feedback item on destination site. Not only you can use trackbacks for external sites but also you can use it for internal pages of your own site. Here is an example of a trackback sent by DotNetKicks to one of my older posts.

But how trackback does work? The workflow for trackback is simple and can be outlined here:

  • Content on the source site is published and contains a link to a destination page.
  • Source site looks for some specific information in the destination page. This information is stored as RDF code and can be seen in the HTML source code of the page. This RDF code is mainly responsible to provide a unique URI for the source site that can be used to send the trackback.
  • Using the information provided by destination site, source site builds a request with some information and sends it to the destination site.
  • Destination site handles this request and stores the link to the content on source site.

This is a simple workflow that can be achieved with some means. Main requirements for this workflow are:

  • The capability to find RDF code on destination site by source site.
  • The capability to build and send trackback request by source site.
  • The capability to provide appropriate RDF code by destination site.
  • The capability to handle and store the trackback by destination site.

Nowadays most of the common blogging engines provide such features out of the box or via plug-ins and extensions so you shouldn’t worry about anything. But if you’re a developer and need to develop a trackback mechanism for your own blogging engine or site then you need to get some additional information.

One side of this workflow is what you do to detect RDF code in the links that are entered in your content and sending a trackback request to appropriate URI but here I don’t want to talk about this part that relates to the source site. I may publish a separate post about this topic.

But the main topic of this post is how to implement a trackback handler that can catch trackbacks and store them on your own site (destination site).

Create an HTTP Handler

You can implement a trackback handler mechanism in several forms but the main structure is constant. However, the best form of implementation is via a HTTP handler which is the most appropriate form for this scenario (as its name suggests).

So the first step is to create an ASP.NET web page and map it to a HTTP handler class. I can configure my web application to define this HTTP handler. Don’t forget to define your handler within <system.webServer /> element for IIS 7.0.

<httpHandlers>

  <add verb="*"

      path="Trackback.aspx"

      type="TrackbackSample.TrackbackHandler, TrackbackSample"/>

</httpHandlers>

So Trackback.aspx page will be handled by TrackbackHandler class. Trackback.aspx page has an id parameter that can be used to pass post identifiers to handler in order to be able to store the trackback for appropriate post.

Implement the HTTP Handler

Of course the main part of this implementation is writing the HTTP handler class. TrackbackHandler is responsible to handle trackback requests and store them.

Following code is what I’ve written to implement my handler. I think that it’s self-explanatory but will give a short description, though.

using System;

using System.Data;

using System.Configuration;

using System.Linq;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.HtmlControls;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Xml.Linq;

using System.Xml;

using System.IO;

 

namespace TrackbackSample

{

    public class TrackbackHandler : IHttpHandler

    {

        #region IHttpHandler Members

 

        public bool IsReusable

        {

            get { return false; }

        }

 

        public void ProcessRequest(HttpContext context)

        {

            var request = context.Request;

            var response = context.Response;

 

            response.Buffer = false;

            response.Clear();

            response.ContentType = "application/xml";

 

            var writer = XmlWriter.Create(response.Output);

 

            if (!string.IsNullOrEmpty(request["id"]))

            {

                var blogTitle = string.Empty;

                if (!string.IsNullOrEmpty(request["blog_name"]))

                    blogTitle = request["blog_name"];

 

                var url = string.Empty;

                if (!string.IsNullOrEmpty(request["url"]))

                    url = request["url"];

 

                var title = string.Empty;

                if (!string.IsNullOrEmpty(request["title"]))

                    title = request["title"];

 

                var excerpt = string.Empty;

                if (!string.IsNullOrEmpty(request["excerpt"]))

                    excerpt = request["excerpt"];

 

                if (request.HttpMethod == "POST")

                {

                    // Store trackback based on the id parameter

                    GenerateSuccessResponse(writer);

                }

                else

                {

                    GenerateErrorResponse(2, "Only HTTP POST verb can be used to send trackbacks", writer);

                }

            }

            else

            {

                GenerateErrorResponse(1, "Item identifier is missing", writer);

            }

        }

 

        private void GenerateSuccessResponse(XmlWriter writer)

        {

            writer.WriteStartElement("response");

            writer.WriteElementString("error", "0");

            writer.WriteStartElement("rss");

            writer.WriteAttributeString("version", "0.91");

            writer.WriteStartElement("channel");

 

            writer.WriteElementString("title", "Sample Page");

            writer.WriteElementString("link", "http://localhost:5935/default.aspx");

            writer.WriteElementString("description", "This is just a sample page.");

            writer.WriteElementString("language", "");

 

            writer.WriteEndElement();

            writer.WriteEndElement();

            writer.WriteEndElement();

 

            writer.Flush();

            writer.Close();

        }

 

        private void GenerateErrorResponse(int number, string message, XmlWriter writer)

        {

            writer.WriteStartElement("response");

 

            if (number > 0)

                writer.WriteElementString("error", number.ToString());

            if (!string.IsNullOrEmpty(message))

                writer.WriteElementString("message", message);

 

            writer.WriteEndElement();

 

            writer.Flush();

            writer.Close();

        }

 

        #endregion

    }

}

The structure of this class is as same as regular ASP.NET HTTP handlers. In the ProcessRequest method the main logic is lied and GenerateSuccessResponse and GenerateErrorResponse method write the XML response for success and failure cases respectively. The structure of output responses is something constant and is defined by specifications.

But in the ProcessRequest method first I checked for the existence of an id parameter then extracted appropriate parameters from the request. The final step is to check if request is sent with a HTTP POST verb and then store the trackback in storage system. It’s necessary to have POST verbs for trackback requests.

Here there is a point. Trackback and pingback entry points are good candidates for spammers to attack your sites or blogs. Before storing a trackback you can use a mechanism to send back a request to source page in order to check for the existence of a link to your page in its HTML source code. You can also use some anti-spam mechanisms to check the incoming trackback before storing it.

Add RDF Code to Pages

But there is a last step before testing the handler and that is, adding appropriate RDF (Resource Description Framework) code to your content pages. Usually this code should be added to individual blog post pages as a HTML code comment that can be seen by machines.

Here is an example of this RDF code for one of my recent blog posts.

<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"

        xmlns:dc="http://purl.org/dc/elements/1.1/"

        xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">

  <rdf:Description rdf:about="http://nayyeri.net/blog/results-of-first-waegis-survey/"

  dc:identifier="http://nayyeri.net/blog/results-of-first-waegis-survey/"

  dc:title="Results of First Waegis Survey"

  trackback:ping="http://nayyeri.net/trackback.ashx?id=882" />

</rdf:RDF>

As you see, this RDF code has a root element that contains a <rdf:Description> element. This element has some attributes that define some properties of your trackback handling system such as a unique URI that can be used to send trackbacks to.

For real world scenarios you need to write a simple code to generate this code automatically but here and for this example I add my RDF code to a page manually. So here is the code-behind for my page:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TrackbackSample._Default" %>

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

    <title>Sample Page</title>

</head>

<body>

    <form id="form1" runat="server">

    <div>

        This is just a sample page to test trackback!

    </div>

    <!--

    <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"

    xmlns:dc="http://purl.org/dc/elements/1.1/"

    xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">

    <rdf:Description

    rdf:about="http://localhost:5935/default.aspx"

    dc:identifier="http://localhost:5935/default.aspx"

    dc:title="Keyvan Nayyeri - Sample Page"

    trackback:ping="http://localhost:5935/trackback.aspx?id=1" />

    </rdf:RDF>

    -->

    </form>

</body>

</html>

It’s all done! Now it’s time to test the code but testing the success case is a little hard because it requires you to send a POST request to the trackback page. This can be done with a tool like Fiddler but I ignore it here.

If you’re interested to discover the source code sample of this post, you can grab it from here.

9 Comments

Pingback from Reflective Perspective - Chris Alcock » The Morning Brew #148

Pingback from Dew Drop - July 31, 2008 | Alvin Ashcraft's Morning Dew

One of my yesterday’s blog posts was about implementing a trackback handler in ASP.NET and I stated that

Last week I published two blog posts about implementing a trackback handler and pingback handler in ASP

Pingback from MetaWeblog, Trackback and Pingback in ASP.NET « vincenthome’s Software Development


My Best Blog Posts in 2008
Dec 31, 2008 1:40 PM
#

In the past 3.5 years of blogging, I haven’t had such best pick up collections in the end of the year, but now that everybody is writing one, why shouldn’t I write my own?! Collecting this list, I could realize some interesting facts that completely changed


Omar
Oct 26, 2009 4:57 AM
#
Can you repair the link for the source code? I m so interested in this sample for the university pls.

SourceLinkPwnd
Nov 02, 2009 10:16 AM
#
Please fix the link for the source code sample.

shailesh
Nov 20, 2009 5:37 AM
#

Please reset download link I m not able to download it.

Leave a Comment





Ads Powered by Lake Quincy Media Network