Создание пользовательского CodeAccessSecurityAttribute приводит к исключению при компиляции - PullRequest
5 голосов
/ 14 февраля 2011

Я создаю пользовательский атрибут CodeAccessSecurityAttribute для обработки авторизации для моих служб WCF. Я построил класс A как таковой:

public class A : CodeAccessSecurityAttribute
{
    public A() : base(SecurityAction.Demand)
    {
        // Constructor Code
    }

    public override IPermission CreatePermission()
    {
        // Permission Creation Code
    }

}

И при компиляции выдает эту ошибку.

Error emitting 'A' attribute -- 'Serialized security custom attribute is 
truncated or incorrectly formed.'

Немного поиграв с ним, я придумал следующий пример, который компилируется без ошибок:

public class B : CodeAccessSecurityAttribute
{
    public B(SecurityAction Action) : base(Action)
    {
        // Constructor Code
    }

    public override IPermission CreatePermission()
    {
        // Permission Creation Code
    }

}

Я знаю, это потому, что перечисление SecurityAction не имеет прямой ссылки на открытую часть класса A, но я не могу понять, как сделать это так, чтобы я мог сделать это методом класса A вместо класса B .

Ответы [ 2 ]

11 голосов
/ 14 февраля 2011

Я не знаю точную причину требования, но в документации MSDN по CodeAccessSecurityAttribute четко указано

Примечания для наследников

Все атрибуты разрешений, полученные из этого класса, должны иметь только один конструктор, который принимает SecurityAction в качестве единственного параметра.

Изменено : причина этого требования в том, что CodeAccessSecurityAttribute, с точки зрения низкого уровня, весьма отличается от других пользовательских атрибутов. Обычно пользовательские атрибуты хранятся в скомпилированных метаданных в таблице CustomAttribute. Но атрибуты безопасности, полученные из SecurityAttribute, хранятся отдельно в таблице DeclSecurity. И эта таблица не содержит общих данных, таких как таблица CustomAttribute, эта таблица содержит значение Action, имя типа атрибута, а также набор свойств (именованных аргументов), как в случае с пользовательским атрибутом. Таким образом, компилятору необходимо преобразовать общий синтаксис настраиваемых атрибутов в запись в этой таблице метаданных, поэтому он должен следовать фиксированной форме, указанной выше. (См. Также это сообщение в блоге , или Раздел II, раздел 22.11. DeclSecurity: 0x0E * * * * * * * * * * * * * стандарта *1023*.)

3 голосов
/ 28 марта 2012

Если вы предоставляете конструктору значение по умолчанию, вам не нужно указывать его в атрибуте.

public class B : CodeAccessSecurityAttribute 
{ 
    public B(SecurityAction Action = SecurityAction.Demand) : base(Action) 
    { 
        // Constructor Code 
    } 

    public override IPermission CreatePermission() 
    { 
        // Permission Creation Code 
    } 
} 
...