Archive Browser
Download cyotek.web.trackback.zip, last updated 22/09/2010 (6.50 KB)
Download- md5: 1e2d47df8c24030e01a8c1c979e60e41
using System;
using System.Collections.Specialized;
using System.IO;
using System.Net;
using System.Text;
using System.Web;
using System.Xml;
using HtmlAgilityPack;
namespace Cyotek.Web.Trackback
{
/// <summary>
/// A helper class for implementing trackback requests in an ASP.NET application.
/// </summary>
public static class TrackbackHandler
{
#region Public Class Methods
/// <summary>
/// Gets the trackback XML for the given request.
/// </summary>
/// <param name="form">The data used to build the request.</param>
/// <param name="saveTrackbackDelegate">A delegate for saving trackbacks into an application specific format.</param>
/// <param name="getTrackbackUrlDelegate">A delegate for returning a fully qualified URI from a given ID.</param>
/// <returns>A string containing formatted XML describing the result of the trackback.</returns>
/// <remarks>HttpRequest.Params or a MVC FormCollection can be used for the form parameter.</remarks>
public static string GetTrackback(NameValueCollection form, SaveTrackbackDelegate saveTrackbackDelegate, GetTrackbackUrlDelegate getTrackbackUrlDelegate)
{
string url;
if (form == null)
throw new ArgumentNullException("form");
if (saveTrackbackDelegate == null)
throw new ArgumentNullException("saveTrackbackDelegate");
if (getTrackbackUrlDelegate == null)
throw new ArgumentNullException("getTrackbackUrlDelegate");
url = form["url"];
if (!string.IsNullOrEmpty(url) && url.Contains(","))
url = url.Split(',')[0];
return TrackbackHandler.GetTrackback(saveTrackbackDelegate, getTrackbackUrlDelegate, form["id"], url, form["title"], form["excerpt"], form["blog_name"]);
}
#endregion Public Class Methods
#region Private Class Methods
/// <summary>
/// Checks to see if the given source URI can be found in a destination URI.
/// </summary>
/// <param name="lookingFor">The URI to be matched.</param>
/// <param name="lookingIn">The URI to be searched.</param>
/// <param name="pageTitle">The title of the searched URI.</param>
/// <returns><c>true</c> if lookinFor was found at the searched URI; otherwise <c>false</c>.</returns>
private static bool CheckSourceLinkExists(Uri lookingFor, Uri lookingIn, out string pageTitle)
{
bool result;
pageTitle = null;
try
{
string html;
html = GetPageHtml(lookingIn);
if (string.IsNullOrEmpty(html.Trim()) | html.IndexOf(lookingFor.ToString(), StringComparison.InvariantCultureIgnoreCase) < 0)
result = false;
else
{
HtmlDocument document;
document = new HtmlDocument();
document.LoadHtml(html);
pageTitle = document.GetDocumentTitle();
result = true;
}
}
catch
{
result = false;
}
return result;
}
/// <summary>
/// Gets the title of a HTML document.
/// </summary>
/// <param name="document">The document.</param>
/// <returns>The title of the document if available, otherwise an empty string.</returns>
private static string GetDocumentTitle(this HtmlDocument document)
{
HtmlNode titleNode;
string title;
titleNode = document.DocumentNode.SelectSingleNode("//head/title");
if (titleNode != null)
title = titleNode.InnerText;
else
title = string.Empty;
title = title.Replace("\n", "");
title = title.Replace("\r", "");
while (title.Contains(" "))
title = title.Replace(" ", " ");
return title.Trim();
}
/// <summary>
/// Gets the HTML at the destination URL.
/// </summary>
/// <param name="uri">The URI to download.</param>
/// <returns>The content downloaded from the given URI</returns>
private static string GetPageHtml(Uri uri)
{
WebRequest request;
HttpWebResponse response;
string encodingName;
Encoding encoding;
string result;
request = WebRequest.Create(uri);
response = (HttpWebResponse)request.GetResponse();
encodingName = response.ContentEncoding.Trim();
if (string.IsNullOrEmpty(encodingName))
encodingName = "utf-8";
encoding = Encoding.GetEncoding(encodingName);
using (Stream stream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(stream, encoding))
result = reader.ReadToEnd();
}
return result;
}
/// <summary>
/// Gets the trackback XML for the given request.
/// </summary>
/// <param name="saveTrackbackDelegate">A delegate for saving trackbacks into an application specific format.</param>
/// <param name="getTrackbackUrlDelegate">A delegate for returning a fully qualified URI from a given ID.</param>
/// <param name="id">The ID of the item being tracked.</param>
/// <param name="url">The URL of the page making the request.</param>
/// <param name="title">The title of the page making the request.</param>
/// <param name="excerpt">An excerpt from the page making the request.</param>
/// <param name="blogName">Name of the blog or site making the request.</param>
/// <returns>A string containing formatted XML describing the result of the trackback.</returns>
private static string GetTrackback(SaveTrackbackDelegate saveTrackbackDelegate, GetTrackbackUrlDelegate getTrackbackUrlDelegate, string id, string url, string title, string excerpt, string blogName)
{
string result;
try
{
HttpRequest request;
request = HttpContext.Current.Request;
if (string.IsNullOrEmpty(id))
result = GetTrackbackResponse(TrackbackErrorCode.Error, "The entry ID is missing");
else if (request.HttpMethod != "POST")
result = GetTrackbackResponse(TrackbackErrorCode.Error, "An invalid request was made.");
else if (string.IsNullOrEmpty(url))
result = TrackbackHandler.GetTrackbackResponse(TrackbackErrorCode.Error, "Trackback URI not specified.");
else
{
TrackbackInfo trackbackInfo;
string trackbackTitle;
Uri targetUri;
trackbackInfo = new TrackbackInfo()
{
Id = id,
Title = title,
BlogName = blogName,
Excerpt = excerpt,
Uri = new Uri(url)
};
targetUri = getTrackbackUrlDelegate.Invoke(trackbackInfo);
if (targetUri == null)
result = GetTrackbackResponse(TrackbackErrorCode.Error, "The entry ID could not be matched.");
else if (!TrackbackHandler.CheckSourceLinkExists(targetUri, trackbackInfo.Uri, out trackbackTitle))
result = GetTrackbackResponse(TrackbackErrorCode.Error, string.Format("Sorry couldn't find a link for \"{0}\" in \"{1}\"", targetUri.ToString(), trackbackInfo.Uri.ToString()));
else
{
if (string.IsNullOrEmpty(blogName))
trackbackInfo.BlogName = trackbackTitle;
saveTrackbackDelegate.Invoke(trackbackInfo);
result = TrackbackHandler.GetTrackbackResponse(TrackbackErrorCode.Success, string.Empty);
}
}
}
catch (Exception ex)
{
//handle the error.
result = TrackbackHandler.GetTrackbackResponse(TrackbackErrorCode.Error, ex.Message);
}
return result;
}
/// <summary>
/// Gets the response XML for a trackback request.
/// </summary>
/// <param name="errorCode">The error code.</param>
/// <param name="errorText">The error text.</param>
/// <returns>A string containing formatted XML describing the result of the trackback.</returns>
private static string GetTrackbackResponse(TrackbackErrorCode errorCode, string errorText)
{
StringBuilder builder;
builder = new StringBuilder();
using (StringWriter writer = new StringWriter(builder))
{
XmlWriterSettings settings;
XmlWriter xmlWriter;
settings = new XmlWriterSettings();
settings.Indent = true;
settings.Encoding = Encoding.UTF8;
xmlWriter = XmlWriter.Create(writer, settings);
xmlWriter.WriteStartDocument(true);
xmlWriter.WriteStartElement("response");
xmlWriter.WriteElementString("response", ((int)errorCode).ToString());
if (!string.IsNullOrEmpty(errorText))
xmlWriter.WriteElementString("message", errorText);
xmlWriter.WriteEndElement();
xmlWriter.WriteEndDocument();
xmlWriter.Close();
}
return builder.ToString();
}
#endregion Private Class Methods
}
}
Donate
This software may be used free of charge, but as with all free software there are costs involved to develop and maintain.
If this site or its services have saved you time, please consider a donation to help with running costs and timely updates.
Donate