我有一个 [AllowPartiallyTrustedCallers] 类库,其中包含 System.DataAnnotations.ValidationAttribute 的子类型。该库用于合同类型的 WCF 服务。
在 .NET 2/3.5 中,这很好用。但是,由于 .NET 4.0,在 Visual Studio 调试器中运行服务的客户端会导致异常“类型违反继承安全规则:'(我的 ValidationAttribute 子类型)'。派生类型必须与基类型的安全可访问性相匹配或者更难访问。 ” (System.TypeLoadException)
仅当满足以下所有条件时,才会出现错误:
- ValidationAttribute 的子类在 AllowPartiallyTrustedCallers 程序集中
- 反射用于检查属性
- 启用 Visual Studio 托管进程(项目属性、调试选项卡上的复选框)
所以基本上,在 Visual Studio.NET 2010 中:
- 创建一个新的控制台项目,
- 添加对“System.ComponentModel.DataAnnotations”4.0.0.0 的引用,
- 编写以下代码:
.
using System;
[assembly: System.Security.AllowPartiallyTrustedCallers()]
namespace TestingVaidationAttributeSecurity
{
public class MyValidationAttribute : System.ComponentModel.DataAnnotations.ValidationAttribute
{ }
[MyValidation]
public class FooBar
{ }
class Program
{
static void Main(string[] args)
{
Console.WriteLine("ValidationAttribute IsCritical: {0}",
typeof(System.ComponentModel.DataAnnotations.ValidationAttribute).IsSecurityCritical);
FooBar fb = new FooBar();
fb.GetType().GetCustomAttributes(true);
Console.WriteLine("Press enter to end.");
Console.ReadLine();
}
}
}
- 按 F5 会出现异常!
按 Ctrl-F5 (不调试就开始),一切正常,无一例外......
奇怪的是,ValidationAttribute 是否对安全至关重要,具体取决于您运行程序的方式(F5 或 Ctrl+F5)。如上面代码中的 Console.WriteLine 所示。但是话又说回来,这似乎也发生在其他属性(和类型?)上。
现在问题...
为什么从 ValidationAttribute 继承时会有这种行为,但从 System.Attribute 继承时却没有?(使用 Reflector 我没有在 ValidationAttribute 类或其程序集中找到特殊设置)
我能做些什么来解决这个问题?如何保持 MyValidationAttribute 从 AllowPartiallyTrustedCallers 程序集中的 ValidationAttribute 继承而不将其标记为 SecurityCritical,仍然使用新的 .NET 4 2 级安全模型,并且仍然可以使用 VS.NET 调试主机(或其他主机)工作?
非常感谢!鲁迪