先来分析asp.net处理一个web请求的过程。学习asp.net技术,除了翻看人家的文档(这是最基本的,知识就是知识,不懂的基本知识无法深入学习),还应当自己学会琢磨,动手实习。
当我们从客户端发出一个web请求后,到达web服务器,由web服务器处理或者转给asp.net框架处理。如果不存在web服务器(采用asp.net的缺省web处理),那你可以参鄙人的《CASSINI源代码分析》http://blog.csdn.net/shanhe/archive/2004/11/10/176422.aspx和 《实现自己的ASP.NET宿主系统》http://blog.csdn.net/shanhe/archive/2004/05/27/5429.aspx。
假设请求到了asp.net的框架,系统回怎么处理呢?
Asp.net系统框架自身有一个http处理的逻辑。这个逻辑由machine.config的 名为httpRuntime的节指定
<httpHandlers>。。。</httpHandlers>
告诉asp.net框架一个应用程序的http处理程序缺省情况下该如何决定处理逻辑。所谓如何处理是指http 谓词(Verb)和资源的位置(Path)组合决定的请求的处理。
例如:
<add
verb="*"
path="*.aspx"
type="System.Web.UI.PageHandlerFactory" />
告诉asp.net在处理任何”.aspx”的文件的任何请求(post/get/head/put)时候都应该使用System.Web.UI.PageHandlerFactory类处理请求。这个类是系统框架缺省类,遵循System.Web.IhttpHandler接口(但是由MS官方实现)。如果你在研究透aspx页框架后,你可以自己写一个aspx页工厂处理程序,签名后加入全局应用程序,再修改此处即可让aspx页面没处理时是按照自己实现的逻辑进行(你甚至可以不遵循页面控件实现逻辑,虽然那样并无太大意义)。
我们来做个实验:我们利用浏览器发出对.config文件的请求(譬如web.config),却省情况下asp.net会报告错误,但是假若我们删除machine.config中的
<add
verb="*"
path="*.config"
type="System.Web.HttpForbiddenHandler" />
并保存。重新请求该文件后,那么会看到浏览器可以读取到此文件并可显示。重新加上该节,重新请求会看到系统报告错误。这充分说明了http处理工厂是根据配置文件进行处理的。据此类推,我们可以阅读machine.config的其他相关配直节,充分理解系统缺省处理逻辑是如何处理web请求(具体为合法的http请求)的。另外,web.config也可以据此增加/删除指定http处理程序。参考MSDN,我们发现,任何一个HTTP处理程序实际上是实现了System.Web.IhttpHandler接口的asp.net类。接口应当实现一个属性和一个借口方法:
公共属性
IsReusable 获取一个值,该值指示其他请求是否可以使用 IHttpHandler 实例。决定了此处理程序是否可以重用(通常克服用意味着系统性能的提高)
公共方法
ProcessRequest 通过实现 IHttpHandler 接口的自定义 HttpHandler 启用 HTTP Web 请求的处理。也就是处理实现。
假设我们写好了一个http处理程序,如何让他发挥作用呢?譬如,我们需要禁止asp.net下载.info文件,我们应该进行如下处理:
第一步,在web服务器上增加指示,让asp.net处理此扩展名。具体为:
打开IIS(假设web服务器是IIS),找到应用程序,配置,应用程序映射,添加映射,在可执行文件中输入当前.net版本的aspnet_isapi.dll(如C:/WINNT/Microsoft.NET/Framework/v1.0.3705/aspnet_isapi.dll),扩展名输入.info,谓词全部,检查文件是否存在。经过这些步骤,确保IIS不会自作多情处理.info文件,而让给aspnet_isapi.dll处理,后者则会将请求交给asp.net进行处理。
第二步,在machine.config或者web.config中加入相映配置节。都是在<System.Web〉中的加入<httphandler>子节,按照格式指定,譬如:
<httphandlers>
…
<add verb=”*” path=”*.info” type=” System.Web.HttpForbiddenHandler”>
…
</httphandlers>
经过上述节配置,.info文件会被保护起来,任何企图访问都会被告知“无法提供此类型的页。”;如果换成你自己的类,则被asp.net框架所调用来处理.info请求。
下面来实现一个http处理程序例子,我们增加一个扩展名.img,img文件根据参数生成一个图片,譬如我们向asp.net框架请求 abc.img,那么系统返回content为image/jpg格式的图片,图片内容为abc
源代码如下:
using System;
using System.Web ;
using System.Drawing;
using System.Drawing.Drawing2D ;
using System.Drawing.Imaging ;
namespace ImyWeb
{
public class IMG : System.Web.IHttpHandler
{
public IMG()
{}
public bool IsReusable
{
get{ return true;}
}
public void ProcessRequest(HttpContext context)
{
string vstr=_getViewString(context);
context.Response.ContentType ="image/jpeg";
Image img=new Bitmap(128,128,PixelFormat.Format32bppArgb );
Graphics g=Graphics.FromImage(img);
Brush backBrush=new SolidBrush(Color.Gray ); //灰色
Brush textBrush=new SolidBrush(Color.Black );
g.FillRectangle(backBrush,0,0,128,128);
Font ft=new Font( "Arial",32);
g.DrawString(vstr,ft,textBrush,new RectangleF(0,0,128,128),new StringFormat(StringFormatFlags.NoWrap ));
img.Save(context.Response.OutputStream,ImageFormat.Jpeg );
context.Response .Flush();
backBrush.Dispose();
textBrush.Dispose();
g.Dispose();
img.Dispose();
return ;
}
//************//
private string _getViewString(HttpContext context)
{
string str= context.Request.RawUrl ;
int l1=str.LastIndexOf("/");
int l2=str.LastIndexOf(".");
return str.Substring(l1+1,l2-l1-1);
}
}
}
编译后,得到应用程序为myHttpHandler.dll。
现在,我们需要告诉asp.net应用程序(假设我们的web应用程序在localHost/webApp1下),如何处理.img文件了:
第一步,在web服务器上增加指示,让asp.net处理此.img的扩展名(让IIS歇着吧,不要插手asp.net的事了,让asp.net处理*.img了)
第二,在web.config中的<system.web>节中增加:
<httpHndlers>
<add verb="*" path="*.img" type="IBuySpy.IMG,IMGHttphandler" />
</httpHndlers>
为了能够让asp.net程序能够定位到应用程序集,将myHttpHandler.dll拷贝到web应用程序的bin目录
接下来,我们测试:在测试的web应用程序WebApp1下随意请求一个.img的资源,将会得到一个jpg图片。http://localhost/WebApp1/test.img
以上为一个简单的httpHandler处理程序的设计、安装过程。实际上,假设你对asp.net缺省的*。aspx 的HttpHandler处理不满,你可以自己进行设计,替换覆盖掉machine.config中关于*.aspx的缺省处理类 "System.Web.UI.PageHandlerFactory”。你要明白,ms设计了一个服务框架,而这个框架内具有了基本的处理能力,但是优秀的是这个框架的部分落及是可以根据自己的意愿进行替换的(我们看到大量的接口使用,我们应当意识到那是使用了大量的现代软件设计技术和思想)。学习asp.net技术要站在全局来了解框架各个组成部分间如何执行、调用、发生关系、县户作用,这比实现了一个花哨的datagrid要更有意义。