介绍
ASP.NET拥有一套自己的扩展名比如.aspx .ascx and .asmx.,你是否想创建字定义的扩展名(处理)资源?Http处理器就允许你那样做。在这篇文章中我们会创建两个字定义的扩展(处理)——.rss和.atom —— 让他们可以被Http处理器处理。为了简化配置,我们将进一步创建Http处理工厂,以决定哪个处理器被调用。
什么是Http处理器?(HTTP Handlers)
HTTP处理器只是一个类,一个处理自定义的扩展文件类型的类。和ISAPI很相似。他们在内部实现IHttpHandler接口。HTTP处理器通常在这种情况下被使用,当你创建了高度自定义的资源或者web窗体不能提出一种整洁的解决方案。举个例子,假设你想把你的网站日志的RSS和ATOM呈现给外界。当然你可以用正常的web窗体就能做到。但是,既然你不使用任何的用户界面,为什么还要导致页面级事件的开销呢?你可以用一个自定义的处理器极佳的完成这个任务,而且它会将RSS或ATOM种子直接附着到原始输出流上。使用这种方法你可以避免上述的开销,同时你也会设计出一个更易读、更有意义的扩展类型(也就是说.rss是RSS内容,.atom是ATOM内容)。
什么是HTTP处理器工厂?(HTTP Handler Factory)
HTTP处理器工厂只是一个实现了IHttpHandlerFactory接口的类。当有许多的HTTP处理器的时候,处理器工厂将变得容易(简单),而且你不知道具体的HTTP处理器使用直到(程序)运行时。处理器工程同样会减轻你的配置管理(在IIS里就是Web.Config),因为你需要做的所有事情就是配置工厂集而不是个别的处理器。
IHttpHandler和IHttpHandlerFactory接口
IHttpHandler接口是所有(HTTP)处理器都要实现的接口。该接口包含一个属性"IsReusable"。IsReusable属性返回一个值,以标示其他的请求是否可以使用IHttpHandler实例。该接口还包含一个方法"ProcessRequest()",这个方法允许你处理当前的请求。这里是你代码的核心地点。这个方法接受一个HttpContext类型的变量参数,你可以通过像Request和Response的内部对象来使用它。
IHttpHandlerFactory接口包含两个方法:GetHandler方法和ReleaseHandler方法。GetHandler方法按照条件实例化具体请求的处理器,并且将这个处理器返回给ASP.NET。ReleaseHandler允许工厂重复使用已存在的处理器。
创建一个例子数据库
首先,我们创建基于IIS的web站点,站点名称为"HandlerFactoryWeb"。加入一个新的SQL Server数据库,名字为"Database.mdf"。创建一个表"Articles",表结构如下:
创建RSS种子发生器
加入一个新的类库项目,名字是"FeedHandlerLib"。在项目中加入一个类,名字为"RSSFeedGenerator"。在该类中加入如下代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Xml;
using System.IO;
namespace FeedHandlerLib
{
public class RSSFeedGenerator
{
public static string GetRSS()
{
MemoryStream ms = new MemoryStream();
XmlTextWriter writer = new XmlTextWriter(ms, null);
SqlConnection cnn = new SqlConnection
(ConfigurationManager.ConnectionStrings["connstr"].
ConnectionString);
SqlCommand cmd = new SqlCommand("select * from
articles order by pubdate desc", cnn);
cnn.Open();
SqlDataReader reader = cmd.ExecuteReader();
writer.WriteStartElement("rss");
writer.WriteAttributeString("version", "2.0");
writer.WriteStartElement("channel");
writer.WriteElementString("title", "MyWebSite.com");
writer.WriteElementString("link", "http://mywebsite.com");
writer.WriteElementString("description", "Cool articles...");
writer.WriteElementString("copyright", "Copyright (C) 2006");
writer.WriteElementString("generator",
"DotNetBips.com RSS Generator");
while (reader.Read())
{
writer.WriteStartElement("item");
writer.WriteElementString("title",
reader.GetString(reader.GetOrdinal("title")));
writer.WriteElementString("link",
reader.GetString(reader.GetOrdinal("url")));
writer.WriteElementString("description",
reader.GetString(reader.GetOrdinal("description")));
writer.WriteElementString("pubDate",
reader.GetDateTime(reader.GetOrdinal("pubdate")).
ToString(@"ddd, dd MMM yyyy 12:00:00 tt G\MT"));
writer.WriteEndElement();
}
writer.WriteEndElement();
writer.WriteEndElement();
reader.Close();
cnn.Close();
writer.BaseStream.Flush();
writer.Flush();
ms.Flush();
byte[] data = new byte[ms.Length];
ms.Seek(0, SeekOrigin.Begin);
ms.Read(data, 0, data.Length);
ms.Close();
return ASCIIEncoding.ASCII.GetString(data);
}
}
}
这里我们没有讨论RSS的详细格式。你可以阅读为你的站点创建RSS种子和加强你站点的RSS种子来了解详细的RSS文件的格式。
RSSFeedGenerator类有一个静态方法GetRSS。GetRSS方法从数据库选择所有的文章,并以此产生一个外部RSS种子。首先,它在XmlTextWriter类的帮助,下在一个MemoryStream重序列了所有数据。
下面的图形显示了由这个类生成的RSS种子的样本。
创建RSS处理器
现在,我们已经准备好了“RSS种子发生器”类,接下来我们将创建RSS处理器用来处理.rss文件。在项目中加入一个类,名字为"RSSHandler"。在该类中加入如下代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Xml;
using System.IO;
namespace FeedHandlerLib
{
public class RSSHandler:IHttpHandler
{
public bool IsReusable
{
get
{
return false;
}
}
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/xml";
string str = RSSFeedGenerator.GetRSS();
context.Response.Write(str);
}
}
}
这个类实现了IHttpHandler借口。IsReusable属性返回false表示我们不想重复使用处理器实例。ProcessRequest方法将输出流的格式设置成text/xml。然后执行RSSFeedGenerator类(RSS种子发生器类)的GetRSS()方法,这个方法返回的字符串(RSS种子)被写入输出流。注意要使用HttpContent参数的内在对象。
创建ATOM种子发生器
现在让我们继续创建ATOM种子。在项目中加入一个类,名字为"ATOMFeedGenerator"。在该类中加入如下代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Xml;
using System.IO;
namespace FeedHandlerLib
{
public class ATOMFeedGenerator
{
public static string GetATOM()
{
MemoryStream ms = new MemoryStream();
XmlTextWriter writer = new XmlTextWriter(ms, null);
SqlConnection cnn = new SqlConnection(
ConfigurationManager.ConnectionStrings["connstr"].
ConnectionString);
SqlCommand cmd = new SqlCommand("select * from
articles order by pubdate desc", cnn);
cnn.Open();
SqlDataReader reader = cmd.ExecuteReader();
writer.WriteStartElement("feed");
writer.WriteAttributeString("xmlns",
"http://www.w3.org/2005/Atom");
writer.WriteElementString("id",
"www.somedomain.com");
writer.WriteElementString("title",
"MyWebSite.com");
writer.WriteElementString("link",
"http://mywebsite.com");
writer.WriteElementString("updated",
DateTime.Now.ToString("yyyy-MM-ddThh:mm:ssZ"));
writer.WriteStartElement("author");
writer.WriteElementString("name", "Mr.Abcd");
writer.WriteElementString("email",
"someemail@somedomain.com");
writer.WriteEndElement();
while (reader.Read())
{
writer.WriteStartElement("entry");
writer.WriteElementString("title",
reader.GetString(reader.GetOrdinal("title")));
writer.WriteElementString("id",
"www.somedomain.com");
writer.WriteElementString("updated",
reader.GetDateTime(reader.GetOrdinal("pubdate"))
.ToString("yyyy-MM-ddThh:mm:ssZ"));
writer.WriteElementString("link",
reader.GetString(reader.GetOrdinal("url")));
writer.WriteElementString("summary", reader
.GetString(reader.GetOrdinal("description")));
writer.WriteEndElement();
}
writer.WriteEndElement();
reader.Close();
cnn.Close();
writer.BaseStream.Flush();
writer.Flush();
ms.Flush();
byte[] data = new byte[ms.Length];
ms.Seek(0, SeekOrigin.Begin);
ms.Read(data, 0, data.Length);
ms.Close();
return ASCIIEncoding.ASCII.GetString(data);
}
}
}
这段代码和我们先前写的非常相似。总之,它生成ATOM种子来代替RSS。下面的图形显示了由这个类生成的ATOM种子的样本。
创建ATOM处理器
创建ATOM处理器和创建RSS处理器类似。在项目中加入一个类,名字为"ATOMHandler"。在该类中加入如下代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
namespace FeedHandlerLib
{
public class ATOMHandler : IHttpHandler
{
public bool IsReusable
{
get
{
return false;
}
}
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/xml";
string str = ATOMFeedGenerator.GetATOM();
context.Response.Write(str);
}
}
}
就像上面的例子,ATOM处理器类实现了IHttpHandler接口。这次,ProcessReqest()方法调用了ATOMFeedGenerator类的GetATOM方法,并将返回的结果写入输出流。
创建种子处理器工厂
现在我们已经准备好了这两个处理器,接下来,让我们创建可以实例化并返回适当处理器的工厂类了,在项目中加入一个类,名字为"HandlerFactory"。在该类中加入如下代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.IO;
namespace FeedHandlerLib
{
class HandlerFactory:IHttpHandlerFactory
{
public IHttpHandler GetHandler(HttpContext context,
string requestType, string url,
string pathTranslated)
{
string path = context.Request.PhysicalPath;
if (Path.GetExtension(path) == ".rss")
{
return new RSSHandler();
}
if (Path.GetExtension(path) == ".atom")
{
return new ATOMHandler();
}
return null;
}
public void ReleaseHandler(IHttpHandler handler)
{
}
}
}
这里,我们创建了一个类,名字叫做“HandlerFactory”,这个类实现了IHttpHandlerFactory接口。在GetHandler方法里,我们检测了来路请求的扩展名。如果扩展名是.rss那么我们就返回一个新的RSSHandler类的实例(RSS处理器类);如果扩展名是.atom那么我们就返回一个ATOMHandler类的实例(ATOM处理器类)。
在Web.config中配置处理器工厂
现在,我们已经准备好了处理器和工厂,让我们做点什么,好让我们的web站点能够使用它们。将刚刚编译好的FeedHandlerLib.dll放入到网站BIN文件夹中。打开网站的web.config文件,加入下面的标签:
<httpHandlers> <add path="*.rss,*.atom" type="FeedHandlerLib.HandlerFactory" verb="GET" /> </httpHandlers>
<httpHandlers>标签通常用于配置一个或多个HTTP处理器。path属性用来指定一个或多个扩展名(在我们的例子中是.rss和.atom),type属性用来指定作为处理器类的完整限定名。需要注意的是,事实上RSSHandler类和ATOMHandler类才是真诚的.rss和.atom的处理器。我们已经在工厂类中指定了这点,这样在运行时,根据请求的扩展名,工厂就会实例适当的处理器。
在IIS中配置处理器工厂
前面,我们已经在web.config中配置了处理器并了解了怎样处理它们。可是,IIS对于它们是没办法的,而且不知道怎样处理它们。所以,下一步就是在IIS中配置你的web站点。打开IIS目标站点的属性对话框,在主目录选项卡中找到并单击配置按钮,打开下面的对话框:

然后单击Add(中文版中是“添加D”)

在可执行文件文本框中选择aspnet_isapi.dll(你可以在.net框架的安装目录中找到这个文件)。在扩展名文本框中填入.rss。在动作部分将动作“限定为”:GET。最后,去掉“确认文件是否存在”选择(即不选择“确认文件是否存在”复选框),然后关闭对话框。重复这个过程建立.atom配置。
现在,当有人请求.rss和.atom,IIS知道怎样去做了。IIS将简单的转寄这些请求给ASP.NET,进而ASP.NET将转寄给处理器工厂(因为我们已经在web.config文件中作了配置)。
ok,就这些。现在你已经可以测试我们的处理器了。浏览你的默认web页,在地址栏里输入articles.rss在敲回车。你将会看到在浏览器窗口里的RSS种子。
总结
使用HTTP处理器,可以灵活的处理你的自定义扩展名。处理器工厂可以根据一些条件实例处理器。它们能够减轻您的web站点整体的必须配置。使用HTTP处理器可以将我们从不必要的页面级事件处理中解脱出来从而提要效率。
| About the author | ||
|
译者注:费了好大劲,用了好长时间,断断续续的才把这篇文章对付出来,转载注出处,thanks
另,文中提到的RSS种子和ATOM种子是译者在本文的规定,原文为:RSS and ATOM Feeds,就为了这个称呼,译者找了好多地方,翻烂了n多字典,也没找到太合适的,后来无意中在一篇文章中看到"feed"称为种子,觉得比较贴切,立即使用了这个版本的翻译。不当之处,还请见谅
原文地址
http://www.dotnetbips.com/articles/displayarticledetails.aspx?articleid=513



