I'm building a custom CodeAccessSecurityAttribute to handle authorization for my WCF services. I built class A as such:
public class A : CodeAccessSecurityAttribute
{
public A() : base(SecurityAction.Demand)
{
// Constructor Code
}
public override IPermission CreatePermission()
{
// Permission Creation Code
}
}
And on compilation it produces this error.
Error emitting 'A' attribute -- 'Serialized security custom attribute is
truncated or incorrectly formed.'
After playing with it a little I came up with the next sample that does compile without error:
public class B : CodeAccessSecurityAttribute
{
public B(SecurityAction Action) : base(Action)
{
// Constructor Code
}
public override IPermission CreatePermission()
{
// Permission Creation Code
}
}
I know it's because the SecurityAction enum isn't directly referenced to public side of Class A, but what I can't figure out is how to make it so that I can do it the Class A method instead of the Class B.
I don’t know the exact reason for the requirement, but the MSDN documentation on CodeAccessSecurityAttribute clearly states
Amended: The reason for this requirement is that
CodeAccessSecurityAttribute
is, from a low-level view, quite different from other custom attributes. Generally, custom attributes are stored in the compiled metadata in theCustomAttribute
table. But the security attributes, deriving fromSecurityAttribute
, are stored separately in theDeclSecurity
table. And this table does not contain the general data like the CustomAttribute table, this table contains the value ofAction
, the name of the attribute type, plus a set of the properties (named arguments) like in the custom attribute case. So, the compiler needs to convert a general custom attribute syntax to an entry in this metadata table, so it needs it to follow the fixed form noted above. (See also this blog post, or Partition II, section 22.11 DeclSecurity : 0x0E of the Common Language Infrastructure (CLI) standard.)