编译asp.net文件为dll文件
Asp.net不是asp的简单升级,而是微软.Net计划中的一个重要组成部分,它依托.Net的多语言与强大的库支持,引进了服务端 HTML控件与WEB控件,自动处理控件的客户端与服务端的 交互,为开发人员提供了似Windows下窗口编程的界面,为开发大型网络应用程序功能提 供了良好的编程接口,也能够极大地提高开发人员的工作效率。

然而,"一次转换,两次编译"过程使得aspx文件在首次执行(或更 新后首次运行)时显得略有不足,特别是在拥有大量aspx及codebehind的代码文件的应用环境中,把aspx文件编译DLL(在.Net中,被 称为应用程序集)后再发布,省去"一次转换、一次编译"的时间及CPU占用率,对提高WEB服务的整体性能会有较大的提升。当然,编译DLL后,对源代 码的保密性也有一定程度的提高。

本文通过对Asp.Net的基本处理流程及一个偶然发现的秘密的分析,介绍了在Asp.Net中 如何建立aspx到DLL的映射,如何开发一个可以处理HTTP请求/响应的DLL,以及如何设置"陷阱",把现成的单个aspx文件与 codebehind的aspx文件编译DLL的过程,文章最后,还介绍了一个在实际操作过程的小技巧。

由于本文要涉及Asp.Net应用程序、命令行编译、web.config配置文件等概念,为了使读者能更好地理解本文内容,也为了使本文看上去不显累赘,先就本文相对应的系统环境作一介绍:

系统环境:
Win2000(SP3)+ IIS5 + .Net Framework 1.0(中文版)。
服务器名称:
由于本文的例子均在本机上测试,服务器名称为localhost。
IIS设置:
建立虚拟目录dlltest(真实路径为w:wwwrootdlltest),并把它设为应用程序,在dlltest下建立bin目录。所有源文件将放在dlltest目录下,而所有dll文件将放在dlltestin目录下。

Asp.Net应用程序配置文件--web.config
在dlltest目录下建立一个web.config文件,初始时该文件内容如下:

<?xml version="1.0"?>
<configuration>
<system.web />
</configuration>

命令窗口(DOS窗口)
打开命令窗口,并用cd命令使当前目录为w:wwwrootdlltest。

(一)建立aspx到dll的映射

首先让我们来看看一般情况下aspx文件是如何被Asp.Net处理的:

当一个HTTP请求(例如"http://webserver/webapp/webpage.aspx") 从客户端发送到IIS服务器时,IIS捕获并分析这个请求,

当它分析到这个请求是一个aspx页面时,立即以 "/webapp/webpage.aspx"为参数调用Asp.Net运行环境(aspnet_wp.exe),

Asp.Net环境启动后,检查 "/webapp/webpage.aspx"是否存在,若不存在,则向客户端返回HTTP 404(File not found)错误,

否则在 Asp.Net 的临时目录中查找相应的dll文件,若不存在或者该dll比aspx源文件"旧",则调用csc编译器(若aspx的服务端脚本语言是 VB或JScript,则调用相应的vbc编译器, jsc编译器)把aspx文件编译dll

然后Asp.Net再调用该dll来处理具体的客户请 求,返回服务器响应。

从这个处理流程可以看出,一般情况下,Asp.Net运行环境会自动识别、检查、更新与aspx相对应dll。那么有没有其它办法可以强制把对一个aspx文件的处理"路由"到一个已编译存在的DLL呢?方法就是在Asp.Net应用程序配置文件 web.config的system.web节的httpHandlers节添加aspx到dll的映射项,语法如下:

<add verb="*" path="aspx文件名" type="名,dll文件" />
aspx文件:需要被"路由"的虚拟名称,扩展名必须是aspx,否则IIS会先于Asp.Net运行环境处理该文件。
dll文件: dll文件(应用程序集)的名称,不必输入".dll"。ASP.NET 首先在应用程序的专用 in 目录中搜索程序集 DLL,然后在系统程序集缓存中搜索程序集 DLL
名: 由于一个dll可能会有多个名称空间或多个,因此必须指明当dll调用时自动加载哪个

例如,某一Asp.Net应用程序的web.config文件如下:

<?xml version="1.0"?>
<configuration>
<system.web>
<httpHandlers>
<add verb="*" path="index.aspx" type="BBS.IndexPage, bbs" />
</httpHandlers>
</system.web>
</configuration>

该配置文件告诉Asp.Net,在客户端请求本应用程序的index.aspx文件时,直接调用应用程序bin目录下的bbs.dll,并自动加载其中的BBS.IndexPage

(二)开发能处理HTML页面的DLL

应该指出的是,并不是所有的应用程序集DLL都能实现HTTP请求/响应模式。还是来看一下Microsoft Asp.Net快速入门教程(http://chs.gotdotnet.com/quickstart/aspplus/)中关于"Http 处理程序和工厂"的描述:

ASP.NET 提供低级别的请求/响应 API,使开发人员能够使用 .NET 框架为传入的 HTTP 请求提供服务。为此,开发人员需创作支持 System.Web.IHTTPHandler 接口和实现 ProcessRequest() 方法的。当处理 HTTP 请求不需要由高级别的 页框架抽象化提供的服务时,处理程序通常很有用。处理程序的常用用途包括筛选器和似 CGI 的应用程序,尤其是那些返回二进制数据的应用程序。

ASP.NET 收到的每个传入 HTTP 请求最终由实现 IHTTPHandler 的的特定实例来处理。IHttpHandlerFactory 提供了处理 IHttpHandler 实例 URL 请求的实际解析的结构。除了 ASP.NET 提供的默认 IHttpHandlerFactory 外, 开发人员还可以选择创建和注册工厂以支持大量的请求解析和激活方案。

从这段文字可以看出,当aspx页面不涉及.net框架提 供的高级界面技术(如数据缓存、状态保持、Web窗体控件引用等等)时,且向客户端输出的不是复杂的HTML文本,特别是只向客户端返回二进制数据(如图 片,声音等)时,可以用一个.cs应用程序文件(本文使用c#语言,如果是用VB或JScript,...)来替代,而该应用程序必须有一个实现 System.Web.IHTTPHandler 接口和并实现 ProcessRequest() 方法的。一个简单的例子如下:

1
2 /**//* 源文件:ex1.cs 开始 */
3 using System.Web;
4 namespace DllTest
5 {
6 /**//*必须实现IHttpHandler接口。如果程序将访问会话状态(Session),则必须实现 IRequiresSessionState 接口(不包含任何方法的标记接口)。*/
7
8
9 public class Ex1Page : IHttpHandler
10 {
11 /**//*IsReusable属性告诉.Net框架,本程序是否可以被多个线程同时使用。
12 true对应是;false对应否。*/
13
14 public bool IsReusable
15 {
16 get { return true; }
17 }
18
19
20
21 /**//*实现ProcessRequest方法,向客户端返回响应数据。
22 本例中向客户端返回一个简单的HTML页*/
23
24 public void ProcessRequest(HttpContext context)
25 {
26 HttpResponse res = context.Response;
27
28 res.Write("<html><body>");
29 res.Write("<h1>DllTest - Ex1(例1)</h1><hr>");
30 res.Write("本页面直接由DLL处理");
31 res.Write("</html></body>");
32 }}}
33

/* 源文件:ex1.cs 结束 */
命令行状态,用如下的编译命令把ex1.cs编译成ex1.dll,并把它存放在bin目录下。

csc /t:library /out:binex1.dll ex1.cs
可以但要写全路径

csc /t:library /out:j:WebSiteWebTestinex1.dll

J:WebSiteWebTestApp_Codeex1.cs

在配置文件web.config中添加aspx->dll映射,添加后,web.config应该是这样子的:

<?xml version="1.0"?>
<configuration>
<system.web>
<httpHandlers>
<add verb="*" path="dlltest1.aspx" type="DllTest.ex1Page,ex1" />
</httpHandlers>
</system.web>
</configuration>

现在当浏览器访问http://localhost/dlltest/dlltest1.aspx时,实际上就是调用了ex1.dll中DllTest.Ex1Page的ProcessRequest方法,在浏览中应该可以看到一个简单的页面。

(三)把单个aspx文件编译DLL

从 上一节微软公开描述的"言外之意"来看,微软是不支持让开发人员直接把aspx文件编译DLL的。然而,Asp.Net高级界面技术(服务端HTML控 件,WEB控件等等)都是需要通过aspx文件才能展现出来的,如果为了DLL的运行效率而放弃aspx的高级特性,则显然是得不尝失的。

现在静下心来分析一下:
csc编译器只是一个c#语言的编译器,它只能对符合C#语言规范的文件进行编译,而aspx文件的格式显然不符合c#语言规范,所以csc编译器是无法对aspx源文件进行编译的。

因 此,要想把aspx文件编译dll文件,必然要先把aspx文件转化成csc编译器能识别的cs源文件。那么用什么工具来进行转换呢?虽然我深信这个工 具一定是隐藏在.Net Framework里面,但在查阅了大量的Asp.Net及.Net的公开文档及参考手册,资料之后,仍找不到相关资料。

呵呵,天无绝人之路,一个偶然的机会,还是让我发现了这个秘密。
来看看源文件ex2.aspx:

/* 源文件:ex2.aspx 开始 */
<% @ Page Language="c#" %>
<script runat="server">
/**//*你没看错,下一行就是"abcdefg",正是这一行,才让我有机会写出本篇文章^_^;
在文中,我把这一行称作"代码陷阱"*/

abcdefg // 代码陷阱

void Page_Load(Object src, EventArgs args)
{
if( !IsPostBack ) NoteLabel.Text = "请输入您的姓名:";
}

void OnNameSubmit(Object src, EventArgs args)
{
string name = f_Name.Value;
NoteLabel.Text = (name=="http://www.blog.edu.cn/") ? "姓名不能为空" : name +",您好。欢迎光临!";
}
</script>
<html>
<body>
<form runat="server">
<h1>DllTest - Ex2(例2)</h1>
<hr>
<asp:label runat="server" id="NoteLabel" style="color:red; font-weight:bold" />
<input runat="server" id="f_Name" size="8">
<button runat="server" onserverclick="OnNameSubmit">确定</button>
</form>
</body>
</html>

/* 源文件:ex2.aspx 结束 */

如果把"代码陷阱"注释掉或删掉,那么ex2.aspx就是一个简单的Asp.Net文件,

用IE浏览此页面可以发现它能正常工作。

现在让我们打开"陷阱",来看看Asp.Net到底返回了什么?

返 回的是一个"编译错误"的页面,报告源文件无法通过编译。让我们感兴趣的是该页面最下方的一个名为"显示完整的编译源"的超链接,点击些链接,就能看到这 个由ex2.aspx转换而来的cs源文件("完整的编译源")的完整内容。把这部分"完整的编译源"去掉前面的行号信息和其它的一些编译开关(主要是 #line编译命令),并关闭那个可爱的"代码陷阱"(用//把它注释掉或直接把它delete也行),整理后保存为ex2_aspx.cs:

/**//* 源文件:ex2_aspx.cs 开始 */

/**//*

从下面的说明可以看出,确实有一个未公开的工具来完成把aspx文件转化成cs源文件

*/

//------------------------------------------------------------------------------

// <autogenerated>

// This code was generated by a tool.

// Runtime Version:1.0.3705.0

//

// Changes to this file may cause incorrect behavior and will be lost if

// the code is regenerated.

// </autogenerated>

//------------------------------------------------------------------------------

/**//*

奇怪的是:命名空间居然是ASP而不是ASPX

建议把该名称改成适合应用程序的名称,防止命名冲突,例如针对本文,可以改成DllTest

这里没改是为了让大家看清它的原貌

*/

namespace ASP

{

using System;

using System.Collections;

using System.Collections.Specialized;

using System.Configuration;

using System.Text;

using System.Text.RegularExpressions;

using System.Web;

using System.Web.Caching;

using System.Web.SessionState;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.HtmlControls;

/**//*

1、注意一下名的构成,如果必要,可以把它改成有意义的名称,例如针对本文,可以改成Ex2Page

2、注意它的基。Syste.Web.UI.Page实现了IHttpHandler接口,由于要访问Session,所以也实现了IRequiresSessionState接口。

*/

public class ex2_aspx : System.Web.UI.Page, System.Web.SessionState.IRequiresSessionState

{

private static int __autoHandlers;

protected System.Web.UI.WebControls.Label NoteLabel;

protected System.Web.UI.HtmlControls.HtmlInputText f_Name;

protected System.Web.UI.HtmlControls.HtmlButton __control3;

protected System.Web.UI.HtmlControls.HtmlForm __control2;

private static bool __intialized = false;

private static System.Collections.ArrayList __fileDependencies;

/**//* 现在可以关掉"陷阱"了 */

// abcdefg

void Page_Load(Object src, EventArgs args)

{

if( !IsPostBack ) NoteLabel.Text = "请输入您的姓名: ";

}

void OnNameSubmit(Object src, EventArgs args)

{

string name = f_Name.Value;

NoteLabel.Text = (name=="http://www.blog.edu.cn/") ? "姓名不能为空" : name +",您好。欢迎光临!";

}

/**//* 构造函数 */

public ex2_aspx()

{

System.Collections.ArrayList dependencies;

if ((ASP.ex2_aspx.__intialized == false))

{

dependencies = new System.Collections.ArrayList();

/**//*

应该把下面这行注释掉,让DLL成为一个无依赖的独立文件

防止在DLL运行时再次去查找、比较它的"依赖"文件的新旧

*/

//dependencies.Add("W:\wwwroot\dlltest\ex2.aspx");

ASP.ex2_aspx.__fileDependencies= dependencies;

ASP.ex2_aspx.__intialized = true;

}

}

protected override int AutoHandlers

{

get {

return ASP.ex2_aspx.__autoHandlers;

}

set {

ASP.ex2_aspx.__autoHandlers = value;

}

}

protected System.Web.HttpApplication ApplicationInstance

{

get

{

return ((System.Web.HttpApplication)(this.Context.ApplicationInstance));

}

}

public override string TemplateSourceDirectory

{

get

{

return "/dlltest";

}

}

private System.Web.UI.Control __BuildControlNoteLabel()

{

System.Web.UI.WebControls.Label __ctrl;

__ctrl = new System.Web.UI.WebControls.Label();

this.NoteLabel = __ctrl;

__ctrl.ID = "NoteLabel";

((System.Web.UI.IAttributeAccessor)(__ctrl)).SetAttribute("style", "color:red; font-weight:bold");

return __ctrl;

}

private System.Web.UI.Control __BuildControlf_Name()

{

System.Web.UI.HtmlControls.HtmlInputText __ctrl;

__ctrl = new System.Web.UI.HtmlControls.HtmlInputText();

this.f_Name = __ctrl;

__ctrl.ID = "f_Name";

__ctrl.Size = 8;

return __ctrl;

}

private System.Web.UI.Control __BuildControl__control3()

{

System.Web.UI.HtmlControls.HtmlButton __ctrl;

__ctrl = new System.Web.UI.HtmlControls.HtmlButton();

this.__control3= __ctrl;

System.Web.UI.IParserAccessor __parser = ((System.Web.UI.IParserAccessor)(__ctrl));

__parser.AddParsedSubObject(new System.Web.UI.LiteralControl("确定"));

__ctrl.ServerClick += new System.EventHandler(this.OnNameSubmit);

return __ctrl;

}

private System.Web.UI.Control __BuildControl__control2()

{

System.Web.UI.HtmlControls.HtmlForm __ctrl;

__ctrl = new System.Web.UI.HtmlControls.HtmlForm();

this.__control2= __ctrl;

System.Web.UI.IParserAccessor __parser = ((System.Web.UI.IParserAccessor)(__ctrl));

__parser.AddParsedSubObject (new System.Web.UI.LiteralControl(" <h1>DllTest - Ex2(例2)< /h1> <hr> "));

this.__BuildControlNoteLabel();

__parser.AddParsedSubObject(this.NoteLabel);

__parser.AddParsedSubObject(new System.Web.UI.LiteralControl(" "));

this.__BuildControlf_Name();

__parser.AddParsedSubObject(this.f_Name);

__parser.AddParsedSubObject(new System.Web.UI.LiteralControl(" "));

this.__BuildControl__control3();

__parser.AddParsedSubObject(this.__control3);

__parser.AddParsedSubObject(new System.Web.UI.LiteralControl(" "));

return __ctrl;

}

private void __BuildControlTree(System.Web.UI.Control __ctrl)

{

System.Web.UI.IParserAccessor __parser = ((System.Web.UI.IParserAccessor)(__ctrl));

__parser.AddParsedSubObject(new System.Web.UI.LiteralControl(" <html> <body> "));

this.__BuildControl__control2();

__parser.AddParsedSubObject(this.__control2);

__parser.AddParsedSubObject(new System.Web.UI.LiteralControl(" </body> </html> "));

}

protected override void FrameworkInitialize()

{

this.__BuildControlTree(this);

this.FileDependencies = ASP.ex2_aspx.__fileDependencies;

this.EnableViewStateMac = true;

}

public override int GetTypeHashCode()

{

return -11574299;

}

}

}

/**//* 源文件:ex2_aspx.cs 结束 */

相信大家在分析了这个文件之后,会对Asp.Net运行原理有更进一步的认识(与本文无关,不详述)。

命令行状态,用如下的编译命令把ex2_aspx.cs编译成ex2.dll,并把它存放在bin目录下。
csc /t:library /out:binex2.dll ex2_aspx.cs

在配置文件web.config中添加aspx->dll映射,即在system.web节的httpHandlers添加下面一行:
<add verb="*" path="dlltest2.aspx" type="ASP.ex2_aspx, ex2" />

现在当浏览器访问http://localhost/dlltest/dlltest2.aspx时,就如同访问ex2.aspx一样。当然,现在即使ex2.aspx不存在,或者已经更新过,也不会对页面访问有任何影响,除非重新生成binex2.dll

(四)把codebehind的aspx文件编译dll

对 于把codebehind的aspx文件编译dll,其中把aspx文件转化成cs源文件的原理同上,也是先设置一个"代码陷阱",然后把"完整的编译 源"进行适当整理,保存为cs源文件。区别是在编译dll时的步骤:(为叙述方便,假设界面文件为ex3.aspx,codebehind文件为 ex3.aspx.cs,ex3.aspx的"完整编译源"保存为ex3_aspx.cs)

第一步:先用如下命令把ex3.aspx.cs编译成binex3.aspx.cs.dll
csc /t:library /out:binex3.aspx.cs.dll ex3.aspx.cs

第二步:再用如下命令把ex3_aspx.cs编译成binex3.dll
csc /t:library /r:binex3.aspx.cs.dll /out:binex3.dll ex3_aspx.cs

然后在配置文件web.config中添加aspx->dll映射,即在system.web节的httpHandlers添加下面一行:
<add verb="*" path="dlltest3.aspx" type="ASP.ex3_aspx, ex3" />

现在打开浏览器,访问http://localhost/dlltest/dlltest3.aspx试试。

posted on 2008-01-23 13:47 畅想.net 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/gostthink/archive/2008/01/23/1049999.html

编译asp.net文件为dll文件相关推荐

  1. .CS文件编译生成.DLL文件 .EXE文件(C#网络搜集)(转)

    如果没有VS用下面的办法 搜索csc.exe 打开cmd 转到csc.exe的文件夹 运行 csc /t:library N:\NET\cs\*.cs   N:\NET\cs\*.cs  是你的cs文 ...

  2. .CS文件编译生成.DLL文件 .EXE文件

    如果没有VS用下面的办法 搜索csc.exe 打开cmd 转到csc.exe的文件夹 运行 csc /t:library N:\NET\cs\*.cs   N:\NET\cs\*.cs  是你的cs文 ...

  3. python:.py文件转.dll文件(.pyd文件)

    基于python,把python文件转为.dll文件,我查了很多方法,没有能把python文件直接转.dll文件的..py要转dll文件都是先转成.pyd文件,然后再把.pyd这个后缀改成.dll,如 ...

  4. 系统中的obj文件、dll文件、so文件、lib文件、exe文件、vcproj文件、sln文件

    1. 源代码(.c等)要经过编译器的编译得到目标代码(.obj),再经过链接器使目标代码和库函数及启动代码合并成一个文件,即可执行文件exe. 2. 生成可执行文件时的链接过程又可根据链接库(动态链接 ...

  5. [MATLAB]将.m文件生成dll文件

    环境:VS2017+MATLAB R2017a ①配置编译环境 在命令行窗口中输入"mbuild -setup"(横线前有一个空格),如果出现如下图所示的提示信息即为成功. 如果提 ...

  6. linux 没有dll文件,找不到dll文件或dll文件丢失该怎么办? 看完就明白

    dll文件是一个经常使用的文件类型,很多游戏或者应用程序都需要调用不同的dll文件才可以运行,因此我们在日常工作学习时,很容易看到系统提示找不到某dll文件. 下面,我们就来看看找不到dll文件或者d ...

  7. 在windows下编译erlang内建函数(nif)的dll文件

    1. 准备软件 python2.7X64安装包; gyp工具包; vs2013;python和gyp下载地址:链接: https://pan.baidu.com/s/1xXkkYi7HEgaUR_Mm ...

  8. .dll文件(DLL文件)

    动态链接库英文为DLL,是Dynamic Link Library的缩写.DLL是一个包含可由多个程序,同时使用的代码和数据的库.例如,在 Windows 操作系统中,Comdlg32.dll 执行与 ...

  9. windows 环境下,可执行 exe 文件和 .dll 文件在不同目录下的处理办法

    在 Windows 操作系统中,当可执行 exe 文件需要使用某个.dll 文件时,它会在以下几个地方寻找该文件: 首先,它会在与可执行文件相同的目录中查找该文件. 如果找不到该文件,则会在系统搜索路 ...

最新文章

  1. 给定 2 个正整数 a, b,a 和 b 最多可能有 40 位,求出 a + b 的和(C语言实现)
  2. A组包含的前导码数( sizeOfRA-PreamblesGroupA)
  3. DCMTK:创建,编写和读取细分对象
  4. nextcloud icon_吉利ICON,我信任的好伙伴,感谢有你的陪伴
  5. C#控件常用设计整理大全
  6. 韦东山 IMX6ULL和正点原子_GPIO和Pinctrl子系统的使用在100ASK_IMX6ULL上机实验
  7. 中科大 计算机网络8 协议层次和服务模型
  8. apt get php mysql_Ubuntu10用apt-get配置apache+php+mysql(轉)
  9. android 开发 目标绑定,Hippy: Hippy 是一个新生的跨端开发框架,目标是使开发者可以只写一套代码就直接运行于三个平台(iOS、Android 和 Web)...
  10. Zend Framework学习之验证ing
  11. kali字典暴力破解教程
  12. word,excel转pdf
  13. kitti数据集格式
  14. C++MFC画图工具
  15. 计算机快捷键大全列表6,快捷键大全excel
  16. html设置带边框九宫格,CSS九宫格带边框的多种实现
  17. 个人网站引入B站视频播放,个人博客播放B站视频。【1080P】
  18. 多可知识管理系统三大特色
  19. 万兴剪刀手去水印教程_万兴神剪手怎么去水印教程_赶快收藏吧
  20. 【深度学习】常见优化算法

热门文章

  1. LinuxQt工作笔记-查看程序工作目录
  2. Java笔记-Log4j在Spring Boot中的使用
  3. Qt工作笔记-依赖于QAbstractTableModel实现自定义TableModel
  4. Qt5.7+Opencv2.4.9人脸识别(二)人脸采集
  5. 多路查找树之2-3树(理论)
  6. linux指令解压rpm,dpkg rpm apt yum 的常用指令 +linux 各种解压缩方法.docx
  7. 不用空格怎么打两个空格_和平精英:苹果手机怎么打空格 空白名使用教程
  8. python动态添加类方法_Python 动态添加类方法
  9. 橘子游戏平台_apex英雄_游戏快速下载_雷神加速器全网最快
  10. matlab读取图片的频率,获得时域图之后,也获得了频域图,但是如何查看频率呢......