Thow to use the AspnetUpload control 2.1(2)
(接上文Thow to use the AspnetUpload control 2.1 http://computer.mblogger.cn/wucountry/posts/46076.aspx )
如果直接使用它的演示版,可能不会有什么问题。但如果仔细查看一下它的web.config文件,或许会发现很多新的东西。我们来看看。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="aspnetUploadSettings" type="System.Configuration.NameValueFileSectionHandler,System, Version=1.0.5000.0, Culture=neutral,PublicKeyToken=b77a5c561934e089" />
</configSections>
<aspnetUploadSettings>
<!--
Key Name: lisenceKey
Valid Value: Purchased lisence key from the control author.
-->
<add key="lisenceKey" value="Lisence key purchase from www.aspnetupload.net" />
<!--
Key Name: maxRequestLength
Valid Value: KBytes size of maximum upload file length to accept
-->
<add key="maxRequestLength" value="2048000"/>
</aspnetUploadSettings>
<system.web>
<compilation
defaultLanguage="c#"
debug="true"/>
<customErrors
mode="Off"/>
<authentication mode="Windows"/>
<authorization>
<allow users="*"/>
</authorization>
<trace
enabled="false"
requestLimit="10"
pageOutput="false"
traceMode="SortByTime"
localOnly="true"/>
<sessionState
mode="InProc"
stateConnectionString="tcpip=127.0.0.1:42424"
sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes"
cookieless="false"
timeout="20"
/>
<httpModules>
<add name="UploadModule" type="Bestcomy.Web.Controls.Upload.UploadModule,Bestcomy.Web.Controls.Upload" />
</httpModules>
<httpHandlers>
<add verb="*" path="download.aspx" type="AspnetUploadDemo.DownloadHandler,UploadDemo"/>
</httpHandlers>
<globalization
requestEncoding="utf-8"
responseEncoding="utf-8" />
</system.web>
</configuration>
关于configurations的设定可以查看MSDN的帮助:
ms-help://MS.MSDNQTR.2003FEB.1033/cpgenref/html/gngrfconfigsectionselementcontainertag.htm
关键的两个,httpHandlers处理器和httpModules处理模块。
httpHandlers是一个处理页面请求的特殊设置,它可以将一个请求映射到一个处理DLL上,这样可以根据实际情况处理请求。其中我们可以看的出来:
<add verb="*" path="download.aspx" type="AspnetUploadDemo.DownloadHandler,UploadDemo"/>
这里就是说:当我们请求download.aspx的时候,会先将请求映射到UploadDemo名字空间内的AspnetUploadDemo.DownloadHandler类上,这样可以先处理一些参数然后返回,这样的方法会使HTTP请求成为特殊的程序来处理。
显然,因为上传大文件不是简单的HTTP请求,所以这里还用到了一个httpModules的处理模块,它来处理上传请求。与httpHandlers不同的是,httpModules模块可以让程序员来处理每一个请求的过程,这也就是为什么可以实现上传时的进度处理了(这真是一个不错的想法)。
更多的httpModules说明,可以查看MSDN帮助:
ms-help://MS.MSDNQTR.2003FEB.1033/cpguide/html/cpconhttpmodules.htm
一个标准的例子(载自MSDN):
using System;
using System.Web;
using System.Collections;
public class HelloWorldModule : IHttpModule {
public String ModuleName {
get { return "HelloWorldModule"; }
}
// In the Init function, register for HttpApplication
// events by adding your handlers.
public void Init(HttpApplication application) {
application.BeginRequest += (new EventHandler(this.Application_BeginRequest));
application.EndRequest += (new EventHandler(this.Application_EndRequest));
}
// Your BeginRequest event handler.
private void Application_BeginRequest(Object source, EventArgs e) {
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
context.Response.Write("<h1><font color=red>HelloWorldModule: Beginning of Request</font></h1><hr>");
}
// Your EndRequest event handler.
private void Application_EndRequest(Object source, EventArgs e) {
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
context.Response.Write("<hr><h1><font color=red>HelloWorldModule: End of Request</font></h1>");
}
public void Dispose()
{
}
}
Register the module as follows:
<configuration>
<system.web>
<httpModules>
<!-- <add name="HelloWorldModule"
type="HelloWorldModule, HelloWorldModule" /> -->
</httpModules>
</system.web>
</configuration>
ms-help://MS.MSDNQTR.2003FEB.1033/cpguide/html/cpconcustomhttpmodules.htm
好了,我们这样的加载这个类:
<httpModules>
<add name="HelloWorldModule" type="UploadDemo.HelloWorldModule,UploadDemo" />
</httpModules>
可以看到结果了,不管是在哪个请求里,都会加上我们前面的内容。问题是,可以和上面的AspnetUpload请求一起用吗?当然可以:看这样的做法:
<httpModules>
<add name="UploadModule" type="Bestcomy.Web.Controls.Upload.UploadModule,Bestcomy.Web.Controls.Upload" />
<add name="HelloWorldModule" type="UploadDemo.HelloWorldModule,UploadDemo" />
</httpModules>
好了,这样就会使ASP.net应用程序先加载UploadModuld模块,然后加载HelloWorldModule模块。
最后发现一个小问题:我们的HelloWorldModule与FreeTextBox有一点点冲突,使得FTB不能正常工作,当然这个没关系,删除HelloWorldModule模块就行了。确切的说是破坏了JS代码。
我们再来看看httpHanlers的一些内容。没有比这更有意思的了。想想,如果我申请网站里的一个页面,而实际上网站里根本就没有这个页面,而我得到的不是一个错误的页面。而正是我想要的结果,这可能吗?用httpHandlers来重新定义httpHeadler是完成可以的。看这样的一个例子:
using System;
using System.Web;
namespace UploadDemo
{
/// <summary>
/// Summary description for Handlers.
/// </summary>
public class MyFactory : IHttpHandlerFactory
{
public virtual IHttpHandler GetHandler(HttpContext context,
String requestType,
String url,
String pathTranslated)
{
String fname = url.Substring(url.LastIndexOf('/')+1);
String cname = fname.Substring(0, fname.IndexOf('.'));
String className = "UploadDemo." + cname;
Object h = null;
// Try to create the handler object.
try
{
// Create the handler by calling class abc or class xyz.
h = Activator.CreateInstance(Type.GetType(className));
}
catch(Exception e)
{
throw new HttpException("Factory couldn't create instance " +
"of type " + className, e);
}
return (IHttpHandler)h;
}
// This is a must override method.
public virtual void ReleaseHandler(IHttpHandler handler)
{
}
}
// Class definition for abc.aspx handler.
public class abc : IHttpHandler
{
public virtual void ProcessRequest(HttpContext context)
{
context.Response.Write("<html><body>");
context.Response.Write("<p>ABC Handler</p>\n");
context.Response.Write("</body></html>");
}
public virtual bool IsReusable
{
get { return true; }
}
}
// Class definition for xyz.aspx handler.
public class xyz : IHttpHandler
{
public virtual void ProcessRequest(HttpContext context)
{
context.Response.Write("<html><body>");
context.Response.Write("<p>XYZ Handler</p>\n");
context.Response.Write("</body></html>");
}
public virtual bool IsReusable
{
get { return true; }
}
}
}
这里,我们重新定义了一个类:MyFactory,它现实了 IHttpHandlerFactory接口。因此它可以处理一个http请求。而它处理一个http请求的时候,是取得请求的文件名,然后根据不同的文件名来实现不同的内容返回。
这里只定义了两个类,一个abc和一个xyz,也就是说,当我们请求的文件名为abc或者xyz的时候(扩展名先不管,稍后将说明如何处理扩展名),那么我们可以得到两个类的返回结果。也就是ABC Handler或者XYZ Handler.
那么ASP.net Server 是如何知道我请求的文件就是我想要请求的那个类的对应结果呢?这里就要对web.config进行一些配置了,看这里的一个简单的配置:
<configuration>
<system.web>
<httpHandlers>
<add verb="*" path="abc.aspx" type="UploadDemo.MyFactory,UploadDemo" />
<add verb="*" path="xyz.aspx" type="UploadDemo.MyFactory,UploadDemo" />
</httpHandlers>
</system.web>
</configuration>
这里的配置说明:当我不管用什么方法(POST/Get)来请求abc.aspx页面的时候,就会映射到UploadDemo名字空间里的UploadDemo.MyFactory类的处理器上,这样实际就是在请求这个类里的一些方法。当然必须要这个类实现了IHttpHandlerFactory接口(还好,前几天刚刚学完COM里接口的说明)。
那么我们可以这样的改一下:
<add verb="*" path="abc.*" type="UploadDemo.MyFactory,UploadDemo" />
这样,不管我们请求以什么扩展名结尾的abc文件,都会映射到UploadDemo.MyFactory处理器上,当然也就会得到ABC Handler的结果。这是最好不过的了,不是吗?
呵呵,,可能自己去试,发现我请求abc.aspxx页面的时候,结果是出现错误,页面找不到。不是说所有的abc.*文件都映射到UploadDemo.MyFactory处理器上吗?为什么错误呢?这里还要说明一下的就是:IIS的配置问题了。只要IIS把一些扩展名的文件映射到aspnet_isapi.dll上就行了。当然一般情况下我们是不能直接控制IIS服务器的,但我们知道有一些文件已经是映射到了这个DLL上的。(主要有:.aspx,asax,ascx,asmx,axd,cdx,config,cs,csproj,idc,java,jsl,licx,rem,resources,resx,soap,.vb,vbproj,vjsproj,vsdisco,webinfo),但要注意语法的优先关系。因为出于安全的因素,一些扩展名的文件是不能请求的,如config,cs等一些系统相关的文件,是请求不到的。
好了,这些东西本来只能在C语言里用ISAPI来实现的,现在简单多了,而且CV++.net也或以很轻松的实现ISAPI的扩展,所以呢,.net的前景应该是很好的哦。
文章来源:http://computer.mblogger.cn/wucountry/posts/46144.aspx