为什么有时候全限定程序集名称需要空格?

11

今天我偶然发现了这个问题,但是我找不到任何相关信息。所以我在这里提问。也许有人知道为什么。

我向我的web.config中添加了一个自定义的WCF行为扩展。它看起来像这样:

<behaviorExtensions>
    <add name="errorBehavior" type="MyNs.TracingErrorBehaviorElement,MyNs, 
         Version=1.0.6.0, Culture=neutral, PublicKeyToken=null" />
</behaviorExtensions>

(这里没有空格:MyNs.TracingErrorBehaviorElement,MyNs

在我的开发机器、我们的暂存服务器和我们的生产服务器等等上,它都能完美运行。

今天我们在一个客户服务器上安装产品时出现了以下异常:

System.Configuration.ConfigurationErrorsException:创建用于system.serviceModel/behaviors的配置部分处理程序时出错:无法向此元素添加扩展元素“errorBehavior”。请确认扩展已在system.serviceModel/extensions/behaviorExtensions扩展集合中注册...

在花费半小时搜索可能原因后,我给完全限定的程序集名称添加了空格。所以我把它改成了:

<behaviorExtensions>
    <add name="errorBehavior" type="MyNs.TracingErrorBehaviorElement, MyNs, 
         Version=1.0.6.0, Culture=neutral, PublicKeyToken=null" />
</behaviorExtensions>

(看空格:MyNs.TracingErrorBehaviorElement,MyNs)

它有效了。

有人知道为什么一些机器上没有空格就能工作,而另一些机器不能吗? 我检查了.Net版本。他们匹配。这可能是由于区域设置引起的吗?

编辑说:

我在所有机器上检查了使用的 .Net 版本,它们都相同:.Net 4.0 但我发现一个区别,即在我遇到缺少空格错误的机器和其他正常运行的机器之间存在差异: 所有没有空格可以正常工作的机器都安装了 .Net Framework 4.5。那么这可能是那些在 4.0 中修复并部署在 4.5 中的 bug 之一,对吧?


1
http://blogs.msdn.com/b/scicoria/archive/2010/06/10/spaces-in-type-attribute-for-behavior-extension-configuration-issues.aspx - Hans Passant
2个回答

5
这是一个已知的bug,在Shawn Cicoria的博客帖子中有记录。它没有详细说明错误何时被修复,WCF配置类非常复杂,很难缩小范围。考虑到这篇文章的发布时间,我猜测这是.NET 4.5的修复版本。如果客户端安装了4.0,则会出现故障。您需要根据项目目标来做出更好的判断。否则,这是微软难以修复漏洞的一个很好的示例。

3

根据MSDN的说明:

在程序集名称以外,各种类型名称组件中都可以包含空格。在程序集名称中,逗号分隔符之前的空格是相关的,但逗号分隔符之后的空格将被忽略。

测试结果表明,这确实是事实 - GetType和其他类型解析方法确实忽略, 分隔符之后的空格。

然而,WCF却使这个问题变得更加复杂,因为它实际上要求完全限定的类型名称正好是您从Type.AssemblyQualifiedName获取的值。也许它在某个地方保留了类型的高速缓存,我不知道。

至于为什么只有一些机器会出现这种情况,我会把赌注放在GAC或其他轻微修改程序集/类型解析系统的地方。由于您没有使用snk,GAC不在考虑范围内,但也许有一些配置可以改变这种情况,可能是在machine.config中或者如果它在IIS配置中的Web应用程序中。

看起来这是.NET 3.5中的一个配置问题。NET 4.0+没有同样的问题。你确定应用程序正在运行相同版本的.NET吗?如果你正在使用Web应用程序(客户的服务器很可能被配置为使用.NET 3.5),实际上,你应该指定system.web.compilation[targetFramework]httpRuntime以针对正确的框架版本。我想添加一个链接到这个错误,但虽然它在许多地方被引用,但是由于某种原因,文章似乎已经从MS Connect中删除了 :)


感谢您的回复。我编辑了我的答案并添加了 .Net 版本信息。因此,尽管使用相同的 .Net 版本,在这些机器上安装的版本存在差异。这可能是一个“悄悄”修复并包含在安装了 4.5 的 4.0 版本中的错误吗?如果我可以标记两个答案,我会这样做,因为这也是一个合理的答案 ;) - CrazyChief
@CrazyChief 有趣(实际上并不是)的是,.NET 4.5并不是一个独立的.NET版本。它会覆盖4.0版本。因此,即使您的项目针对4.0,一旦安装了4.5,您也不再运行在4.0上(当尝试调试内存转储时特别令人恼火,因为4.5对调试接口引入了破坏性的变化)。所以是的,如果修复只存在于4.5中,这就很好地解释了这个谜团 :) - Luaan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接