破宝

我是一块破破烂烂的宝贝石头。
随笔 - 94, 评论 - 1281, 引用 - 52

导航

关于

自选精华版 RECOMMENDATIONS
留言板 GUESTBOOK

本人 blog 文章、图片及其他资源等,除另有声明外,均遵循以下原则向全球(当然包括朝鲜、古巴、利比亚等国)共享:

1。欢迎转载、复制、传播、引用,但转载、复制(包括但不仅限于作为参考资料复制到本地)、传播、引用同时必须在显著位置注明作者(破宝/percyboy)和文章原始 URL 地址等信息。但商业转载、复制、传播(尤指用于图书、光盘等媒体的部分或全部),须事先征得本人的许可。

2。文章以“现状”提供,不为由于使用本站资源而造成的任何损失而负责,仅提供力所能及的咨询和参考意见。

3。关于修改:允许您将本 blog 中的资源作为参考资料复制时的一定修改,但仍须保留作者和出处信息;其他情况下的修改(包括修改后再发布),须和本人确认许可。
 

标签

每月存档

最新留言

广告

又一个疑似Bug: XmlDataSource 控件的 Data 属性动态改变时,缓存不会自动失效

最近似乎不太顺利,总是一钻进 Reflector 就 N 久时间找不到问题所在,一点一点琢磨那些可疑的、没有头绪的、没有注释的 BCL (.net 的基础类库)源代码,以确认到底是我错了,还是微软错了。

这不,又发现一个疑似bug,如标题所写。

XmlDataSource 控件一般是和 TreeView 组合使用的,如果是静态的 XML 数据是不会碰到什么问题的,但一变成动态数据,就总碰到一些怪异的现象。(虽然大部分最终还是被克服了。)

想让 TreeView 显示动态数据,第一条,可以不用绑定,直接一个 TreeNode 一个 TreeNode 的添加,保证 100% 符合要求。

第二条,在画面上放上多个 XmlDataSource 控件,根据情况将 TreeView 的 DataSourceID 属性指到相应的 XmlDataSource 控件。但局限也很明显,总不能一下子放上 100个,1000个 XmlDataSource 控件吧?

第三条,XmlDataSource 只用一个,但改变它的 DataFile 或者 Data 属性,以改变数据。

改变 DataFile 属性的方案,经试验是可行的。不过相对于 Data 属性,局限就是必须有硬盘上存在的 XML 文件做源。虽然你可以选择动态生成 XML 文件,然后绑上去,但还是有些麻烦,还得考虑考虑这些临时文件的废弃处理措施。

Data 属性相对就比较合我的口味,不过,我就在这个方案上栽了跟斗:我发现无论怎么改变 Data 值,TreeView 的显示总是不变。(只有页面初始化那一次有效。)

先是怀疑是不是 TreeView 没有自动去 XmlDataSource 去取最新数据?对 BCL 的 debug 是有点麻烦的,好像是有办法下载微软公开的源代码,然后进行 debug 的,不过我这会儿没功夫去调。就用 Reflection 将我看到的那些 private 变量的值弄出来看,结果没发现 TreeView 有“偷工”的迹象。

然后把矛头掉转到 XmlDataSource,看看是不是它有问题。一钻去,首先就发现这个家伙跟其他的 DataSource 控件相比,有一点很与众不同,它默认的 Cache.Enabled = true。这个默认设置,也算可以理解,毕竟 XML 文件相对于数据库那些数据源来说,还是很稳定的,而且加载很多节点的 XML 文档也是很费劲的。

进一步的追踪发现,问题的原因应该就是出在缓存上。Data 属性变化后,缓存没有自动失效,导致了问题。

下面是我使用 Reflection 的 Hack:

    public static void XmlDataSourceCacheHack(XmlDataSource dataSource)
    {
        try
        {
            Type t = typeof(XmlDataSource);
            MethodInfo m = t.GetMethod("CreateCacheKey", 
                BindingFlags.Instance | BindingFlags.NonPublic);
            string key = (string)m.Invoke(dataSource, null);
            PropertyInfo p = t.GetProperty("Cache",
                BindingFlags.Instance | BindingFlags.NonPublic);
            object cache = p.GetValue(dataSource, null);

            Type t2 = t.Assembly.GetType("System.Web.UI.DataSourceCache");
            MethodInfo m2 = t2.GetMethod("Invalidate", 
                BindingFlags.Instance | BindingFlags.Public);
            m2.Invoke(cache, new object[] { key });
        }
        catch
        {
        }
    }

如果你有不使用 Reflection 就能解决的方法,敬请不吝赐教,那就多谢了!

如果你希望看点示例代码,请到 codeproject 下面的页面去下载:

http://www.codeproject.com/KB/webforms/XmlDataSource_Cache_Hack.aspx

补充:

当然,还有个简单的做法,就是直接禁用 XmlDataSource 的 cache 功能。不过,像我的实际情况中,切换数据源的可能性要远远低于其他 PostBack 的几率,缓存要比 reflection 更重要一些。你可以根据你的实际情况决定。

posted on 2008-06-16 20:15:48 by percyboy  评论(0) 阅读(2589)

立此存照:System.Net.Mail 的 bug

痛苦了debug了一个多钟头,后来终于在网络上找到了这篇“救星”文章:

http://columns.chicken-house.net/blogs/chicken/archive/2007/04/06/system-net-mail-bug.aspx

立此存照,如果您也碰到同样问题,希望能够能比我更幸运些,更早找到问题所在。

症状是:调用 SmtpClient.Send 方法后,出现 System.FormatException,

英文消息为“An invalid character was found in header value.

中文消息是:“邮件标头中找到无效字符”。

原因是在 SmtpClient.Send 之前曾经调用过该 MailMessage 对象的 From, To, Cc 等字段的 ToString 方法。很有可能的情形是,你尝试在发信前留下日志时,“无意间”调用到了。而微软的工程师在此处出现了一些失误,最终产生了该错误消息,具体情况请参看上面链接中的文章。

P.S. 当然还会有其他原因可能导致此问题,比如微软知识库里给出的一种原因是因为收件人显示名称中包含有引号

posted on 2008-06-10 18:25:15 by percyboy  评论(0) 阅读(3254)

Powered by: Joycode.MVC引擎 0.5.2.0