我希望引入一种新的服务器脚本语言, 想在页面中加入自己的标示符,在IIS中处理时先把aspx的标示符替换掉,然后把我的标示符替换成对应的aspx标示符,如:<asp:button runat="server" >  替换为 {asp:button ruant="server"} ;而我自己的标示符 [myb:repeater runat="server"] 替换为 <asp:repeater runat="server">。经过IIS得到相应结果,
这样再把响应的结果再次处理把aspx标示符替换回去,存为aspx页面就可以正常运行。 我的想法是在 ASP.NET ISAPI 扩展 处理请求之前先用自己的dll进行上诉的预处理,是否可以使用HttpModule 与IIS中的ISAPI过滤器。但不知具体该如何做,请各位大虾指点!

解决方案 »

  1.   

    重新排版如下:      我希望引入一种新的服务器脚本语言, 想在页面中加入自己的标示符,在IIS中处理时先把aspx的标示符替换掉,然后把我的标示符替换成对应的aspx标示符,如:<asp:button runat="server" >  替换为 {asp:button ruant="server"} ;而我自己的标示符 [myb:repeater runat="server"] 替换为 <asp:repeater runat="server">。经过IIS得到相应结果,这样再把响应的结果再次处理把aspx标示符替换回去,存为aspx页面就可以正常运行。 我的想法是在 ASP.NET ISAPI 扩展 处理请求之前先用自己的dll进行上诉的预处理,是否可以使用HttpModule 与IIS中的ISAPI过滤器。但不知具体该如何做,请各位大虾指点!
      

  2.   

    至少在ASP.NET这个是impossible的,HttpModule也无法完成
    aspx和aspx.cs最终都要编译成程序集的出现这种需求,往往是因为设计不当
      

  3.   

    仔细研究了一下Http运行时,感觉用HttpModule实现困难很大。
    那么还有其他方式可以达到目的吗?出现这种设想的背景是想把静态页面生成与动态需求相结合起来。
      

  4.   

    除非你的页面是完全Code-Beside的,否则不行!对于Code-Behind的代码,时运行前编译的。对于Code-Beside的代码,以及TemplateControl,时运行时解释/编译的(我并不确认真的是编译),这个工作是由PageHandlerFactory来做的。如果你确保你全部是Code-Beside代码,那么你可以编写自己的HttpHandler,先做自己的工作,做好后再交给Page.ProcessMain()处理(你无法调用PageHandlerFactory,因为它是internal的,而且它也仅仅是调用了对应的Page.ProcessMain())。当然,以上提供的仅仅是一个设想,你要做就需要使用Reflector浏览大量System.Web下面的类,追踪它们的调用关系,我并不确保这个设想一定能实现。我不是很明白楼主为什么要这样做,或许你是允许用户写自己的script,然后你又想让这些script转换成ASP.NET代码然后用回原有的ASP.NET引擎处理从而避免了自己写script解释引擎?
      

  5.   

    另外我很好奇一样东西,不知道可否用.NET编写真正的ISAPI Filter?或者主要部分用.NET编写。如果可以这样,或许会更简单。
      

  6.   

    cat_hsfz()  猜得很对,就是为了借用ASP.NET引擎处理从而避免自己写script解释引擎 而产生的这个设想。对于Code-Behind的代码,倒是可以通过替换 Codebehind 来 选择需要的dll ,所以可以与Code-Beside 的代码一样处理。对于ISAPI Filter ,可能要用C++才能实现
      

  7.   

    我暂时只能说,你的目标有希望实现,但因为我没有仔细研究过PageParser类是如何工作的,所以我还不敢说一定能成功。我之前就尝试过用自己的HttpHandler取代原有的PageHandlerFactory,然而我并不是想写一个全新的服务,我还是想用回Page等一大堆WebControl来堆砌页面。当时我用Reflector去看System.Web,通过Call/Callee Graph找到了Page.ProcessMain()入口,发现可以直接用它来调用一个Page(不过我当时没发现这个入口的名字多么眼熟)。后来我发现了一个更好的方法,原来Page.ProcessMain()就是IHttpHandler.ProcessMain(),在PageHandlerFactory里面就是把一个Page当作一个IHttpHandler那样return出去的,那么我也只需要这样做就行了。但我没有仔细研究过PageParser(它继承自TemplateParser,而Page继承自TemplateControl),但从我暂时所看到的情况来说,并非PageHandlerFactory调用PageParser,然后PageParser调用Page。事实是PageHandlerFactory仅仅把Page当作IHttpHandler扔给ASP.NET ISAPI,然后在Page.ProcessMain()被调用后Page才主动找PageParser来分析自己的HTML(包括Code-Beside)部分。而你的目标的希望就在于此,你要在把Page交给ASP.NET ISAPI之前,完成你要做的代码转换工作,然后如何让PageParser不是去读取真正的aspx文件而是获取你转换后的代码,这就需要你好好研究PageParser类了。因为我是研究纯dll的ASP.NET实现,所以很少去碰PageParser,如果你研究到什么了不方法上来分享一下。
      

  8.   

    例如建一个ascx文件里面就封装一个repeater,各类属性方法等完全继承过来或者才用控件做个DLL,也是从repeater继承
      

  9.   

    我开始稍稍同意楼上 Sunmast(速马/MVP) 的“设计不当”的说法了。想一想在WinForm方面的事情,免费的C#和VB.NET编译器,甚至还有CodeDom,你可以轻松得在你的程序里面加入类似VBA这样的功能(这个轻松当然是指相对以前来说),编译时可以有详尽的信息反馈,你可以处理好这些信息反馈并根据你的实际情况调整后以更适合的方式提供给开发者。按照这个方式去思考,你没必要自己弄新的标签方式,你应该支持用户直接用C#或者VB.NET来书写。例如让他们书写一个UserControl,然后你的页面动态嵌入这个UserControl就是了。当然,你还要控制用户输入的内容,避免例如Cross Site Script Attack等。
      

  10.   

    动态嵌入这个UserControl, 如果不用新的标签方式,在生成静态页面的时候UserControl也会变成普通HTML语句融合在页面中,失去交互能力
      

  11.   

    另外最近看别人的Blog,又看到新东西了。你看看这个,他说可以把自定义Tag解释为某样东西:
    http://www.cnblogs.com/RChen/archive/2005/03/22/123190.html是论坛上 inelm(莫依马甲第n号) 的Blog。
      

  12.   

    写个iis的isapi。先替换所请求文件的内容生成一个新文件再重新向到这个文件上,这只是实际基本的需求,但其中仍然有N多问题。不过我一直认为没必要做自已的脚本调用人家的编译器
      

  13.   

    to  cat_hsfz() 
    http://www.cnblogs.com/RChen/archive/2005/03/22/123190.html
    我上去看了一下,木野狐 写的还可以,但是似乎在这不起什么作用。to  gxboy(Blin 小学生学.NET) 
    使用临时文件我也试过,只是生成、删除文件很费时,速度要慢十倍,数据多时有点熬人
      

  14.   

    这个是可以的。首先,微软提供了ParseControl方法,给我们提供了非常大的便利。Page.ParseControl方法可以把任何一个aspx文件编译成为一个Page对象(需要强制类型转换)。
    但是这个方法并不是静态的,不过这并不影响,因为为了实现IHttpHandler,Page有一个默认的构造函数。所以我们可以很简单的利用new Page().ParseControl来编译aspx文件。然后,又是因为要实现IHttpHandler接口,所以Page的ProcessRequest方法是public的(显示实现接口)。我们可以通过这样来令一个Page对象生成页面((IHttpHandler) page).ProcessRequest( Context );
      

  15.   

    Page并不是第一个被调用的IHttpHandler,而HttpApplication才是主IHttpHandler,由它生成了Page然后再调用Page的ProcessRequest方法。
      

  16.   

    to  Ivony() 
    在http请求的处理过程中,只能调用一个HTTP处理程序,然而可以调用多个HTTP模块
    我的替换放在哪里执行呢?
      

  17.   

    注册一个IHttpHandler,然后在它的ProcessRequest方法里面通过context.Request.PhysicalPath获取aspx文件的路径,读取aspx文件、篡改,然后生成Page对象,调用Page的ProcessRequest方法,应该能行,虽然我还没试过。
      

  18.   

    PageParser.GetCompiledPageInstance也能够得到Page实例
      

  19.   

    isapi得用vc++,delphi对程序员来说得有一定的底的中国第一代程序员用过isapi
      

  20.   

    HttpModule+HttpHandler应该可以实现
    ProcessRequest() 在这个函数里实现
      

  21.   

    to Ivony() 
    试了一下
    执行到 Page newPage = (Page)(new Page().ParseControl(pageContent)); 这句时出错,显示如下:
    分析器错误 
    说明: 在分析向此请求提供服务所需资源时出错。请检查下列特定分析错误详细信息并适当地修改源文件。 分析器错误信息: 未知指令“Page”。源错误: 
    行 1:  <%@ Page language="c#" Codebehind="ConfigControl.aspx.cs" AutoEventWireup="false" Inherits="TTL.ConfigControl.ConfigControl" %>
    行 2:  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
    行 3:  <HTML>
     源文件: 无    行: 1 
    --------------------------------------------------------------------------------
    版本信息: Microsoft .NET Framework 版本:1.1.4322.573; ASP.NET 版本:1.1.4322.573 另外 PageParser.GetCompiledPageInstance 怎么使用啊?
    请指点,谢谢!
      

  22.   

    抱歉,我没试过含有Page指令的页面。的确棘手,,,,,这是GetCompiledPageInstance的函数签名
    public static IHttpHandler GetCompiledPageInstance(string virtualPath, string inputFile, HttpContext context)如果用它,看起来得先要生成另一个aspx文件先。
      

  23.   

    我想知道楼主除了允许用户在页面放置Control还允许什么?安全如何保证?
      

  24.   

    to cat_hsfz() 
    安全和普通ASP.NET页面一样。
    我想做的是内网的数据生成静态页面,再通过外网发布,而有些动态交互的功能是其他公司定制的,就希望能在他们的动态页面中嵌入我的脚本语言,发布到外网时不影响已做好动态交互功能。
    也许在页面放置Control是最简单的办法了,但我还想试试有无其他更灵活的办法。
      

  25.   

    和普通ASP.NET一样?那么客户在代码中写<script language="javascript">alert('hello!');</script>那么真的会弹出"hello!"吗?这样可能造成Cross Site Script Attack的哦,除非你和你的客户之间有比较强的信任关系。
      

  26.   

    to cat_hsfz() 
    是的,真的会弹出"hello!"。因为客户是产品的使用者,是网站的拥有者。
      

  27.   

    用HttpModule 与IIS中的ISAPI过滤器 可以实现
      

  28.   

    楼主可以参考以下Sharepoint2003。在Sharepoint里面,所有的文件都是存放在SQL Server里面的,然后应该是由HttpModule影射为Web路径。即使是/Default.aspx也是保存在数据库的,只有在访问时它才被调用出来然后经过ASP.NET引擎处理。这里可以看得到的事,HttpModule仅仅把数据库里面的aspx读取出来,然后没有保存到物理路径就能够交给接下来的ASP.NET引擎处理,例如编译为dll,那么楼主应该也可以这样做到。
      

  29.   

    To cat_hsfz() :
    如果Sharepoint2003开源的话我就可以知道怎么实现了,可惜不开源,也很贵.
      

  30.   

    如果能够调用到.NET Framework里面的那些internal的方法,那就很简单了。最主要的是那些关键的东西都是internal的…………
      

  31.   

    这些东西不仅是internal的,而起回随framework版本改变的
      

  32.   

    用Reflector可以看看Sharepoint.dll啊,你要的话我找找,或许能发一个给你。不过Sharepoint.dll经过了混淆,所有纯内部使用的东西都混淆了。
      

  33.   

    to cat_hsfz() 
    请帮忙找找Sharepoint.dll,万分感谢
    [email protected]
      

  34.   

    to cat_hsfz() 
    你发的邮件已收到,谢谢!
    可惜本人水平有限,未能找到,遗憾!
      

  35.   

    不管你想做的是什么新奇的东西,把自己喜欢的格式所保存的文档一次性地自动转换为asp.net格式的带控件(<asp:...>、<mycontrol:....>格式)或者绑定(<%# ...>或者<%=...>格式)文档总之比你的要求要简单。
      

  36.   

    原来这贴还在up啊?呵呵……实际上能否用Reflection来强制调用某些internal的方法?如果可以的话,那就好办了。
      

  37.   

    啊……对了,有没有听说过Cassini这东西?能够脱离IIS的ASP.NET运行环境,在www.asp.net就有,可以下载源代码。有了这个东西,应该足够研究ASP.NET的整个运行过程以及如何override掉其中任何一个步骤。
      

  38.   

    to sp1234:
        你说的方法也早就试过,使用中间过渡文件,但速度却差一个数量级,数据量大时就很慢了。to cat_hsfz() :
        你说的我来找找
      

  39.   

    to cat_hsfz() :
        我研究了一下Cassini,发现它只是个宿主,调用了相关程序而已,并没有具体细节体现。看来只有把希望寄托在ASP。NET2.0了。
      

  40.   

    哇……这贴又顶上来啦?呵呵……Cassini既然是一个宿主,而且又开源,应该可以通过修改Cassini从中插入你要实现的处理吧?也就是在Cassini调用Framework功能之前,先进行你的处理。
      

  41.   

    to cat_hsfz() 
      首先感谢您的关心!
      Cassini也是调用相关API,它的调用还是太粗,没有具体价值
      

  42.   

    Cassini确实仅仅是做了IIS的工作和实现了System.Web.Hosting中的功能,不过既然它能够区分对待不同文件(例如是列目录、静态文件下载还是ASP.NET页面),那么你就可以考虑按照它的方式对于你的文件先进行预处理然后再按照ASP.NET页面方式进行处理。因为Cassini属于IIS替代品,那么在Cassini内部预先对文件进行处理,再交给ASP.NET处理程序,理论效果和IIS中插入一个前置的ISAPI Extension是一样的。