代码改变世界

鸡肋烹制出的美味——真正可调试的ASP.NET AJAX

2007-02-06 07:23 Jeffrey Zhao 阅读(...) 评论(...) 编辑 收藏

鸡肋般的源码

ASP.NET AJAX的源代码的确发布了,并且提供了pdb文件,也就是说,我们现在可以用它来调试了。

但是它真的够用吗?不知道各位朋友们有没有真的用它跟踪到代码中去,至少我用下来之后非常的不满意。

  • 代码分散在每个文件中,IDE的Go to Definition等功能无法使用。
  • 代码文件不能有丝毫修改,否则pdb里面记录的行号就无法与源代码对应。
  • 在调试时查看对象的属性或成员时,经常会遇到如下的提示:“Cannot evaluate expression because the code of the current method is optimized.”,而无法查看属性或成员地值。

其中最后一个问题最为关键,它严重阻碍了调试过程。可是这又有什么办法呢?在编译好的程序集里MSIL都得到了优化,它已经不是元文件直接编译的结果了。

现在的源代码真是鸡肋。

 

鸡肋也能烹制美味

谁说鸡肋不能烹制美味?

官方给出了源代码,我们为什么不设法把它恢复成C#工程呢?于是我新建了一个C# Class Library,把源代码复制到工程中去。然后通过比较编译错误、运行错误以及使用.NET Reflector查看ASP.NET AJAX程序集,一点点补充丢失的资源和代码,费了九牛二虎之力总算比较完美地恢复了ASP.NET AJAX的程序集。

享用这道美食的方法也非常简单,您只需要做以下几步就可以了:

  1. 点击这里下载工程文件和Web.config文件。
  2. 将压缩包解开,将System.Web.Extensions工程引入到您的解决方案中去。
  3. 为解决方案里必要的工程添加一个刚才新增的System.Web.Exetensions工程的引用,并删除对GAC里System.Web.Extensions.dll的引用。
  4. 修改Web.config,将所有的“, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”去除,您可以对照着压缩包里的Web.config文件进行编辑,或者直接使用这个文件。
  5. 重新编译。

现在,ASP.NET AJAX已经成为您解决方案中的一个工程了,您可以任意修改它,任意对它进行调试。当调试完毕后,去除对于这个工程的引用,并且重新添加GAC里System.Web.Extensions.dll的引用即可。

 

享受美味时的注意事项

目前这个工程有些问题可能需要注意一下:

1、调试工程与GAC里的System.Web.Extensions.dll不能同时引用

为了调试时不修改您的任何代码,我保留了调试工程里所有源代码不变,这导致了如果一个工程里同时引用了GAC里的System.Web.Extensions.dll和调试工程,则在编译时会出现命名空间冲突的错误。这似乎是一个无法解决的问题,不过调试工程和GAC里的程序集几乎完全一样,您也可以完全使用调试工程进行开发,发布时重新编译一次,并将Web.config改回来即可。

2、资源文件名称以及相关代码有轻微改变

由于使用了VS进行编译(使用命令行编译可以解决这个问题,但是就不容易调试使用了),因此资源文件的名称不得不进行了改变,例如MicrosoftAjax.js改成了System.Web.MicrosoftAjax.js。相应的,由于源文件中hard-coded了这个文件名,因此我也对它进行了修改。这导致了如果您的程序需要识别这些文件名时,在使用调试工程时也需要修改一下您的代码。例如在我之前的文章《ScriptManager的ResolveScriptReference事件的重要作用》中,我会判断程序集是否引用了程序集里名为MicrosoftAjax.js的文件,现在就要判断是否引用了名为System.Web.MicrosoftAjax.js。

另外,System.Web.UI.WebResourceUtil类的私有方法SystemWebExtensionsContainsWebResource会用来教验资源文件是否存在,我现在把它改为直接return true,将判断的逻辑短路。这段代码是为了在开发人员恶意访问System.Web.Extensions.dll程序集里不存在的资源时抛出合理的异常,我们正常使用ASP.NET AJAX时不会受到这个修改的影响。

在几乎所有情况下,这些轻微改变都不会造成使用上的问题。

3、控件的图标没有编译进程序集

控件的图标没有编译进入程序集,这样调试用工程里的控件,如UpdatePanel在工具栏中不会出现图标。这不会对使用有任何影响,反而可以与GAC里的UpdatePanel进行区分。

4、使用Ajax Control Toolkit时需要重新编译

如果您需要把Ajax Control Toolkit和调试工程同时使用时,您也需要把Ajax Control Toolkit的源文件引入到您的解决方案中,并修改它的引用,使它使用我们调试用的工程。最后需要重新编译,生成新的程序集。

5、调试工程的UpdatePanel没有设计期支持

要有设计期的支持似乎还需要配合Design源码,我会尽快解决这个问题。