发表评论
#1楼 [
楼主]2006-03-07 22:34 |
在写这篇文章的时候,我想了一下写博客的好处:
1、记录想法
2、理清理路
3、加深理解
4、共享知识
5、交流学习
6、提高自己
大概看懂了意思了.那在博客园程序里不是要定义比较多的HttpHandler,并且实现UrlRewrite.
之前在2.0中使用UrlRewrite也出现了一些问题,也是与虚拟目录有关的问题.是这样的:
在同一级目录下有a.aspx,b.aspx页面都有同一菜单,在没有Url重写的情况下它的链接地址比如是:
/Security/c.aspx
而如果用URL重写访问一个b页面比如重写的地址是:b/1.aspx
这样在这个页面的链接地址就变为了:
/Security/b/c.aspx
多出了上面那个假的虚拟路径了.看来有时间要好好分析了.
不知道采用cs里使用的HttpModule实现urlrewrite,在asp.net 2.0下是否有问题
我用MS的urlrewriter,反倒是在asp.net1.1模式下运行会发生问题
运行在asp.net2.0下是正常的~
@补丁
2.0的程序在1.1下可以运行?
@鑫爷
我使用的就是cs的那种模式,在HttpModule的BeginRequest事件里重定向
深有同感,本来想基于asp.net2.0做目前这个项目的呢,可是最终还是放弃了,原有的一些模块和组件要升级,总是问题重重啊。
由于项目时间紧迫,不能怠懈。所以,只能先做1.1版本的啦,等做好了再慢慢改版升级吧。
要不把地址Mapping那里把PageParser.GetCompiledPageInstance改成UrlRewrite来实现?
#11楼 [
楼主]2006-03-08 09:21 |
@阿不
不需要定义很多的HttpHandler,UrlReWriteHandlerFactory的作用就是创建HttpHandler来处理请求。
这里并没采用通常的UrlRewrite, 因为UrlRewrite是重定向到另外一个实际的虚拟地址,而博客园的程序中是直接创建一个页面的实例去处理请求。
我从来就不用MS不成熟的东西,大家是被它的易用及华丽的外表骗了吧???
要反对我的暂停!!!我不回复的
@dudu
是啊,.Text的UrlReWriteHandlerFactory类原来是用PageParser来做的,但现在asp.net2.0出现这种Bug,可能设计者本身就是希望大家用URLRewrite方法吧,而且我觉得改用Rewrite应对原有程序影响不是太大,因为Rewirte后,Request中的一些路径信息是不变的,Entry/Blog/Config等类(这里我记得不太清楚了)还是可以跟据Request分析出实际的Blog、Entry啊,不知正不正确,呵呵?
#14楼 [
楼主]2006-03-08 10:35 |
@THIN
谢谢你的建议! 正在研究URLRewrite。
你的代码是如何发的,它的格式跟Visual Studio中的一样。
还有就是如何在blog里发一个钟表呢?(纯属好奇,请帮我)
我的博客为zklxj.cnblogs.com,请在我的随笔里发表一个评论的方式告诉我。谢谢!
我自认为ASP.NET水平应该已经入门, 可是看了五、六遍实在看不明白楼主到底要说明什么问题,如果想说ASP.NET2.0有BUG ,那就请用最简单的代码来重现错误,让我们水平低的人看个明白。如果想说你的ASP.NET1.1程序升级到ASP.NET2.0 遇到问题,那就贴出代码让大家讨论讨论。
asp_lha@msn.com
首先申明,我替微软抱不平!!!
这片文章我居然还在Yesky里面看到了,而且是3月7日这里发出来,3月8日就在Yesky里面。如果说自己写写Blog,总结总结经验无可厚非,但是帖到yesky去误导别人就不对了。
对于你说到的PageParser.GetCompiledPageInstance,我已经在你上面那篇Blog上面写了回复。这里看到实在忍不住,还想说几句。关于IIS的问题,你想想看,对于IIS来说,当路径最后是"/"的时候,你认为是直接加个default.aspx? 没有这么简单,IIS是根据原先设置的默认文档的顺序来判断是否存在相应的文件,如果都不存在则提示错误。注意这是个处理过程,不是直接给你的"/"添加上default.aspx。如果要你要自己代替IIS做这个操作,请记得去做控制,不要什么都不做,就说是BUG。 还有微软都说了一般不要自己去搞PageParser.GetCompiledPageInstance,你就不要去搞好了 干嘛喜欢搞这个东西。
下面这几句我差点看晕过去 :
“这样编译效率实在太低了!为什么要根据虚拟路径创建缓键,设计者设计时根本没考虑到通配符映射的问题,真是糟糕的设计!如果按照ASP.NET 1.1那样根据实际访问的页面文件名创建缓存键,就可以轻松地避免这个问题。ASP.NET 2.0新的页面编译模型在这里似乎是一个败笔。更糟糕的是连让开发人员弥补这个Bug的机会都没有,...”
你以为微软吃素的? 照你这么说,微软自己用.NET开发的网站每天都要挂掉N次?
通配符映射是一种方式,你会不会用就看你自己了,你自己要控制编译,就好好的控制它。就像一辆车,你如果不会手动档 就直接开自动档,不要挂在两、三档一路向北。
#20楼 [
楼主]2006-03-10 21:54 |
@Activer
在你告诉我之前,我自己都不知道这篇文章被子转贴到yesky。
我本来就是自己写写Blog,也只在自己的Blog上发表过。
“IIS是根据原先设置的默认文档的顺序来判断是否存在相应的文件,如果都不存在则提示错误。注意这是个处理过程,不是直接给你的"/"添加上default.aspx。如果要你要自己代替IIS做这个操作,请记得去做控制,不要什么都不做,就说是BUG。”
我本来就不想替IIS做什么操作,正因为IIS“判断是否存在相应的文件”,才让我被迫选择使用通配符映射(也可以用UrlRewrite), 因为博客园程序中很多地址都是实际上不存在的,我只想IIS原封不动把地址传给ASP.NET运行时,然后我在程序中对地址进行分析,根据一定规则创建相应的.aspx文件的实例。而要想这样做,只能选择PageParser.GetCompiledPageInstance,PageParser.GetCompiledPageInstance也不是很特别的东西,如果不用PageParser.GetCompiledPageInstance,实际上就是用PageHandlerFactory,它们都是调用BuildManager.GetVPathBuildResultWithNoAssert或 BuildManager.GetVPathBuildResultWithAssert得到.aspx文件编译后的类型,只不过PageParser.GetCompiledPageInstance能将不存在的虚拟路径映射到实际的.aspx文件,但PageParser.GetCompiledPageInstance却在编译时没能考虑这个问题(与PageHandlerFactory调用了同样的编译代码),根据虚拟目录建立页面编译缓存。我觉得PageParser.GetCompiledPageInstance主要就是为了解决通配符映射这样的特殊处理方式,却没有解决好,让PageParser.GetCompiledPageInstance却成了没用的东西,如果微软不让用PageParser.GetCompiledPageInstance,我觉得可能就是因为这个Bug。
“照你这么说,微软自己用.NET开发的网站每天都要挂掉N次?”,这篇文章本来就是针对通配符映射这种特殊情况, 并没有说所有.NET开发的网站都存在这个问题。
“通配符映射是一种方式,你会不会用就看你自己了,你自己要控制编译,就好好的控制它。就像一辆车,你如果不会手动档 就直接开自动档,不要挂在两、三档一路向北。”
由于PageParser.GetCompiledPageInstance存在问题, 要想用这样的方法解决这个问题, 只能选择自己控制编译, 我想自己控制编译, 可微软不让,
System.Web.Compilation中很多有用的东西不能调用更不能修改,要想自己控制编译,只能自己写代码处理页面编译,一项很艰巨的任务。也就是说:如果我想开手动档, 就得自己造一辆手动档的车。
哎 你已经误入歧途了,从一开始 方向就发生错误
"我本来就不想替IIS做什么操作,正因为IIS“判断是否存在相应的文件”,才让我被迫选择使用通配符映射(也可以用UrlRewrite), 因为博客园程序中很多地址都是实际上不存在的,我只想IIS原封不动把地址传给ASP.NET运行时,然后我在程序中对地址进行分析,根据一定规则创建相应的.aspx文件的实例。"
那么你想实现的东西就是 友好的URL吧
要实现友好的URL:
1. 对于原有的参数形式的路径, 通过URL的rewrite实现友好的URL
2. 对友好URL的访问,需要通过reverse 这个URL
这无论在ASP.NET 1.1 Or 2.0 里面都无需调用PageParser之类的。
在HttpModule里面控制 然后在页面里面配合就可以了
原先还以为你调用HttpHandlerFactory要搞什么动态的加载 或者替换 HttpHandler,也就是说不需修改web.config来达到更改httpHandler
而且我也想不出 自己对ASP.NET的页面进行编译控制有什么好处。因为你的页面就是标准的.NET,没有什么自己特别的格式、语法。
ASP.NET 2.0里面对页面的编译与1.1不同,不是直接给PageParser,中间有不少过程。首先是让BuildManager来管理,让它来调用BuildProvider, 这样可以自己添加对各种文件(脚本、程序)的编译控制。夸张一点来说 也就是自己可以按自己的方式 定义自己的语言然后指定自己的编译程序来编译它
请你上网的时候 注意一下现在很多网站其实都是使用虚拟的页面路径与名称,而且很多都是.NET包括.NET2.0, 没有你想象那么多问题的
@Activer
这里我想补充一下,可能你对.Text程序并不了解。
对于URL友好,一般的应用都是做到2005/10/23/blogentry.html这样子的路径,而.Text要处理2005/10/23/这样的路径,请注意,这个路径没有文件名,所以,必须使用通配符才能使IIS把像这样的路径都转给asp.net来处理。
至于缓存是根据用户请求的URL还是真正处理的文件更好,我的意见和DUDU是一致的,为什么?因为2005/10/12/blogentry.html和2005/10/12/blogentry.aspx和2005/10/12/blogentry.php甚至05/10/12/12345.aspx这样的路径不同,但最终的处理是一个页面文件,同一个过程,为什么要被缓存成四份呢?
技术讨论而已,不必搞得义愤填膺的吧?
@THIN
对 我对.Text程序不了解。如果有.Text的Source 我就能直接写出问题的解决方案了。
对于通配符的处理 我并没有说不好,而是说处理通配符要自己好好处理。
好像我们都没有点到问题的实质。你们始终都是说.NET2.0没有处理好 什么 什么问题,
其实是自己没有去处理,注意如果自己做好了处理 就不会有这样的问题。
友好URL怎么处理呢? 早就有人写了专门的组件来处理,你看看 根本不需要搞什么页面编译。
“至于缓存是根据用户请求的URL还是真正处理的文件更好,我的意见和DUDU是一致的,为什么?因为2005/10/12/blogentry.html 和2005/10/12/blogentry.aspx和2005/10/12/blogentry.php甚至05/10/12/12345.aspx 这样的路径不同,但最终的处理是一个页面文件,同一个过程,为什么要被缓存成四份呢? ”
这个就要问你自己了, 注意是你自己写的程序控制这个过程。
“但最终的处理是一个页面文件,同一个过程,为什么要被缓存成四份呢?”
为什么要被缓存成四份呢? 如果说是同一个,你就处理成同一个就是了。
#25楼 [
楼主]2006-03-11 11:05 |
@Activer
“哎 你已经误入歧途了,从一开始 方向就发生错误”,方向没有错,我需要的就是这个方向,这种方式可以很好地解决友好URL的问题,而且这种方式在ASP.NET 1.1中工作的很好,而我遇到的问题,是由于升级到ASP.NET 2.0带来的,不管怎么样, 这个问题属于ASP.NET 2.0,至少是兼容性问题。
URL ReWrite也是解决友好URL的方法之一, 但它带来了更多复杂性,需要考虑两种虚拟地址带来的问题。
“原先还以为你调用HttpHandlerFactory要搞什么动态的加载 或者替换 HttpHandler,也就是说不需修改web.config来达到更改httpHandler ”,PageParser.GetCompiledPageInstance就是动态加载HttpHandler。
“而且我也想不出 自己对ASP.NET的页面进行编译控制有什么好处”,不自己进行编译,就没法解决ASP.NET 2.0中通过虚拟路径建立缓存键的问题,不是我想要这么做,而是不得不这样做。
“ASP.NET 2.0里面对页面的编译与1.1不同,不是直接给PageParser,中间有不少过程。首先是让BuildManager来管理,让它来调用BuildProvider, 这样可以自己添加对各种文件(脚本、程序)的编译控制。”,建议你分析一下PageParser的源代码,然后你就会明白这样说是否合适。之前的回复中已经说过PageParser与PageHandlerFactory是调用同样的代码进行页面编译的。
在我们讨论时,我是一边看着PageParser的源代码,一边与你讨论,而你却凭借自己对PageParser的主观理解。
“请你上网的时候 注意一下现在很多网站其实都是使用虚拟的页面路径与名称,而且很多都是.NET包括.NET2.0, 没有你想象那么多问题的”,第三次告诉你:我说的问题是针对通配符映射这样的情况。
@Activer
对于一个已有项目的改造不同于开发一个新项目,所以,你不要单单说为什么不这样、那样设计?如果能这样那样设计,你为什么去说国家为什么不一开始就搞市场经济,为什么不现在马上把所有的市场都开放了(我这里只是举个例子,不意政治)。
至于上面提到的缓存,请看清楚我的DUDU都是表达的PageParser对页面编译结果的缓存,不是说你自己控制的System.Web.Caching.Cache,所以,这个不是问我自己的问题。
关于自己好好处理,这里DUDU也只是提出Asp.net1.1项目迁移到2.0会遇到的问题,结大家一个借鉴,我觉得这样很好啊,也很有价值啊,比如下次我在做URL友好相关的项目时,我就会提前考虑到这个问题,做好设计,而不是碰到了问题去改设计。好好处理是要好好处理啊,未必DUDU现在就没有却解决这个问题,我上面提到用UrlRewrite代替PageParser,也是提出一个解决的思路啊,大家都是要解决问题来提高的嘛。
哎,不一定文人相轻,搞技术的都相轻,别人的东西,要不是搞出一个比.net更牛的产品来,就不是什么了不起的东西,都是不值一提浪费大家时间的狗屁东西。
@dudu
发现一个Bug,比如我在你这个Archive选了有回复通知,会把我自己的回复发邮件这来,而你(贴的主人)发的不会发邮件过来。
#27楼 [
楼主]2006-03-11 11:25 |
@Activer
“对于通配符的处理 我并没有说不好,而是说处理通配符要自己好好处理。”
如果要好好处理,就要重写System.Web.UI.PageParser中的代码。
如果照你这样说,对任何Bug, 微软都可以说“自己好好处理”。
对于操作系统的问题, 微软可以说“你可以自己重写一个操作系统啊”。
我再说明一下文章中讲述的问题: 正是由于ASP.NET 2.0中页面编译时,通过虚拟路径建立缓存键的问题,从而造成PageParser在通配符映射程序中无法使用。如果通过物理路径建立缓存键,就不存在这个问题。微软可以轻松地解决这个问题,而我要想解决这个问题,就要重写页面编译代码。
#28楼 [
楼主]2006-03-11 11:26 |
@THIN
谢谢你发现这个问题, 我会尽快解决。
@dudu
非常抱歉,这两天一直都把注意力 集中在BUG这个字眼 还有页面编译上面 没有注意到dudu已经想明白一个问题:
“[2006年3月6日修改]已经找到一种解决方法:在PageParser.GetCompiledPageInstance之前进行RewritePath处理,示例代码如下:”
我原先所说的需要自己处理 就是说的这个意思, 却没有发现dudu已经在上面的文章中做了改动。
还有上面文章中有个概念 值得商榷 虚拟路径。
像BuildManager.GetCacheKeyFromVirtualPath,这个虚拟路径是指IIS中的那个虚拟路径的意思(虚拟路径 相与对真实的路径而言)。而像2005/10/12/blogentry.html 应该算虚拟的URL,相对与真实的URL而言。
如果说很明确虚拟路径这个概念 我想你就没有上面那篇充满曲折的文章了,因为一看PageParser.GetCompiledPageInstance就知道它需要的参数是虚拟路径 而非一个虚拟的URL。
#30楼 [
楼主]2006-03-12 11:43 |
到此为止 问题讨论的很激烈 终于大家有些共识。 讨论的目的也达到了。
dudu对问题的深入探索,不断钻研的精神实在可贵。
让偶很佩服,偶向来都是浅尝辄止。不想深入,以后也要好好学习学习,有空多写点文章与大家一起研讨技术。
-----------
题外话:既然说到VirtualPath,还要加几句。ASP.NET中对于页面或者其它文件的路径使用,一般都是依赖VirtualPath,所以需要好好理解这个VirtualPath,千万注意这个VirtualPath,它也可以不必真实映射到实际的物理路径。比如说可以映射到DataSet,呵呵放到SQL Server里面!?有意思吧。下次有空 我就写篇关于使用非物理路径VirtualPath的文章与大家一起学习学习.NET中各种新技术。
#32楼 [
楼主]2006-03-12 14:41 |
@Activer
欢迎你来博客园注册,与大家一起交流!
在我研究ASP.NET 2.0的源代码时,经常看到VirtualPath的身影,上面所讨论的问题中,VirtualPath是个重要角色,编译缓存键也是通过调用System.Web.VirtualPath.GetCacheKey()生成的,但VirtualPath被internal保护,不能直接调用。
对VirtualPath还不熟悉,继续研究。
期待你的文章!
不知道 dudu 有没有测试过: ASP.NET 2.0 内置的 URL Mapping 功能是否存在同样的问题?
#35楼 [
楼主]2006-08-14 17:03 |
我知道 wildcard mapping,我是说已经加了 * 映射之后,ASP.NET 2.0 内置的 URL Mapping 功能是否也存在文中所说的问题?
.Text 的 URL Rewriting 因为不是微软自己写的,Framework 升级可能会考虑不到,微软自己写的 URL Mapping 应该考虑到这些问题吧?否则就可以算 bug 了。:(
如果在2.0的环境里运行1.1的component?
#38楼 [
楼主]2006-10-05 09:41 |
@嘻哈呵嘿
直接运行。
学到不少东西,我也正需要做1.122.0的升级,幸好是要准备在升级后再做url友好.
向dudu THIN 和Activer学习~
架吵得很火热,是非也分辨的很明白~
我已经增加了
<buildProviders >
<add extension=".*" type="System.Web.Compilation.PageBuildProvider"/>
</buildProviders>
这个代码,可为什么还是提示“没有为扩展名“”注册的生成提供程序。可以在 machine.config 或 web.config 中的 <compilation><buildProviders> 节注册一个。请确保所注册的提供程序具有包含值“Web”或“All”的 BuildProviderAppliesToAttribute 属性。”这样的错误?
<compilation debug="true">
<!--解决通配符映射为伪静态FCKeditor不正常显示问题-->
<buildProviders>
<add extension=".html" type="System.Web.Compilation.PageBuildProvider"/>
</buildProviders>
<!--/////////////////////////////////////-->
</compilation>
这个代码要加在<compilation>中...我刚刚也是同样的错误,,改了以后就可以了...