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
Notes to Inheritors
All permission attributes derived from this class must have only a single constructor that takes a SecurityAction as its only parameter.
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 the CustomAttribute
table. But the security attributes, deriving from SecurityAttribute
, are stored separately in the DeclSecurity
table. And this table does not contain the general data like the CustomAttribute table, this table contains the value of Action
, 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.)
If you supply the constructor with a default value you don't have to specify it in the attribute.
public class B : CodeAccessSecurityAttribute
{
public B(SecurityAction Action = SecurityAction.Demand) : base(Action)
{
// Constructor Code
}
public override IPermission CreatePermission()
{
// Permission Creation Code
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With