У меня есть библиотека классов [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, наследуемый от ValidationAttribute в сборке AllowPartiallyTrustedCallers, не помечая ее SecurityCritical, все еще используя новую модель безопасности .NET 4 level 2 и , по-прежнему работающую на отладочном хосте VS.NET (или других хостах ) ??
Большое спасибо!
Rudi