惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Threat Research - Cisco Blogs
博客园 - 聂微东
小众软件
小众软件
P
Proofpoint News Feed
Security Archives - TechRepublic
Security Archives - TechRepublic
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
TaoSecurity Blog
TaoSecurity Blog
博客园 - 司徒正美
罗磊的独立博客
N
News and Events Feed by Topic
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
S
Security Affairs
S
Security @ Cisco Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
The GitHub Blog
The GitHub Blog
月光博客
月光博客
S
Secure Thoughts
P
Proofpoint News Feed
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Forbes - Security
Forbes - Security
H
Heimdal Security Blog
W
WeLiveSecurity
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
L
LangChain Blog
T
The Blog of Author Tim Ferriss
NISL@THU
NISL@THU
Google DeepMind News
Google DeepMind News
Cloudbric
Cloudbric
H
Hacker News: Front Page
The Last Watchdog
The Last Watchdog
Hacker News - Newest:
Hacker News - Newest: "LLM"
C
Cisco Blogs
博客园 - 三生石上(FineUI控件)
博客园_首页
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
S
Schneier on Security
Project Zero
Project Zero
SecWiki News
SecWiki News
爱范儿
爱范儿
The Register - Security
The Register - Security
AI
AI
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Y
Y Combinator Blog
L
Lohrmann on Cybersecurity
Application and Cybersecurity Blog
Application and Cybersecurity Blog
P
Privacy International News Feed
J
Java Code Geeks
S
Securelist
C
Cyber Attacks, Cyber Crime and Cyber Security
V
Visual Studio Blog

博客园 - JerryShi

使用流模式传输大型数据 对象序列化之 替换(Surrogate) 使用 IExtensibleDataObject 进行往返式序列化 使用 NetDataContractSerializer 共享类型 WCF可序列化方式 序列化 VS 编码 自定义 Behavior 操作行为 之 事务 服务行为 之 元数据 服务行为 之 并发与实例化 基本的WCF编程(实例) WCF Behaviors(行为) WCF 体系结构 WCF服务 使用netTcpBinding 无法打开默认数据库 SharePoint 创建SSP时出现找不到 Windows NT 用户或组 的异常 SQL Server 2008 Mirror 泛型(一) 自定义属性Attribute(二)
自定义属性Attribute(三)
JerryShi · 2009-12-02 · via 博客园 - JerryShi

检测自定义属性的应用而不创建自定义属性的实例

   在调用GetCustomAttirbute及GetCustomAttirbutes方法时,都会调用属性类的构造器方法,同时也有可能调用property的get或set访问器。并且,首次访问一个类型会让CLR调用类型的类型构造器。而在构造器、访问器、类型构造器中,可能包含每次查找一个属性都会执行的代码,我们使用属性时并不知道这些代码,这样会允许未知的代码在AppDomain中运行,造成潜在的安全隐患。

         System.Reflection.CustomAttributeData类允许我们在查找自定义属性的同时禁止执行属性类的代码。其实现原理是 Assembly类的静态方法ReflectionOnlyLoad以一种特殊的方式加载程序集,期间会禁止CLR执行程序集中的任何代码,包括类型构造器。而CustomAttirbuteData类则对其加载的程序集进行分析。

         CustomAttributeData的GetCustomAttribute方法相当于一个Factory方法,它会返回IList<CustomAttirbuteData>集合。对于集合中的CustomAttributeData对象,可以访问其三个只读字段获取参数:

  1. Constructor 返回一个ConstructorInfo对象,表示构造函数“要”如何调用。
  2. ConstructorArguments  返回IList<CustomAttributeTypedArgument>集合,表示“要”传给构造函数的参数列表。
  3. NamedArguments 返回IList<CustomAttributeNamedArgument>集合,返回“要”设置的字段。

这里的构造函数、参数列表以及字段的设置不会实际的调用构造器和set访问器,这样才会增加安全性。

代码示例:

CustomAttributeDataAdapter

[Serializable]
[DefaultMember(
"ShowAttribute")]
[DebuggerDisplay(
"Shi",Name="Jerry",Target=typeof(CustomAttributeDataAdapter))]
public class CustomAttributeDataAdapter
{
public CustomAttributeDataAdapter()
{ }

[Conditional(

"Debug")]
[Conditional(
"Release")]
public void DoSomething()
{ }

[CLSCompliant(

true)]
[STAThread]
public static void ShowAttribute()
{
ShowAttribute(
typeof(CustomAttributeDataAdapter));

MemberInfo[] members

= typeof(CustomAttributeDataAdapter).FindMembers(
MemberTypes.Constructor
| MemberTypes.Method,
BindingFlags.DeclaredOnly
| BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static,
Type.FilterName,
"*");
foreach (MemberInfo member in members)
{
ShowAttribute(member);
}
}
private static void ShowAttribute(MemberInfo attributeTarget)
{
IList
<CustomAttributeData> attributes = CustomAttributeData.GetCustomAttributes(attributeTarget);

Console.WriteLine(

"Attributes applied to {0}:{1}", attributeTarget.Name, (attributes.Count == 0 ? "None" : string.Empty));foreach (CustomAttributeData attribute in attributes)
{
Type t
= attribute.Constructor.DeclaringType;
Console.WriteLine(
" {0}", t.ToString());
Console.WriteLine(
" Constructor called={0}", attribute.Constructor);

IList

<CustomAttributeTypedArgument> posArgs = attribute.ConstructorArguments;
Console.WriteLine(
" Positional arguments passed to constructor:{0}", (posArgs.Count == 0) ? "None" : string.Empty);
foreach (CustomAttributeTypedArgument pa in posArgs)
{
Console.WriteLine(
" Type={0}, Value={1}", pa.ArgumentType, pa.Value);
}

IList

<CustomAttributeNamedArgument> namedArgs = attribute.NamedArguments;
Console.WriteLine(
" Named arguments set after contruction:{0}", (namedArgs.Count == 0 ? "None" : string.Empty));
foreach (CustomAttributeNamedArgument na in namedArgs)
{
Console.WriteLine(
" Name={0}, Type={1}, Value={2}", na.MemberInfo.Name, na.TypedValue.ArgumentType, na.TypedValue.Value);
}
Console.WriteLine();
}
}

条件属性类

自定义属性的目的及方便之处在于其反射或者晚期绑定中的应用,但过多的向目标定义属性会造成元数据不断扩大,并会影响程序的性能。因此.Net引出了条件属性类(ConditionalAttribute)来解决此问题。

ConditionalAttribute 仅对自定义属性有效,并且根据编译时 csc /define:condtionalParam 参数来判断是否将自定义属性生成到元数据。

ConditionalAttribute

[Conditional("Debug")]
internal class DebugAttribute : Attribute
{

}

[Conditional(

"Release")]
internal class ReleaseAttribute : Attribute
{

}

[Debug]

internal class DebugApp
{
internal static void ShowAttribute()
{
//IList<CustomAttributeData> attributes = CustomAttributeData.GetCustomAttributes(typeof(DebugApp));//foreach (CustomAttributeData attribute in attributes)
//{
// Console.WriteLine("{0} is applied to DebugApp", attribute.ToString());
//}

Console.WriteLine(
"Debug attribute is {0} applied to DebugApp", Attribute.IsDefined(typeof(DebugApp), typeof(DebugAttribute)) ? "" : "not");
}
}

[Release]

internal class ReleaseApp
{
internal static void ShowAttribute()
{
//IList<CustomAttributeData> attributes = CustomAttributeData.GetCustomAttributes(typeof(ReleaseApp));//foreach (CustomAttributeData attribute in attributes)
//{
// Console.WriteLine("{0} is applied to ReleaseApp", attribute.ToString());
//}
Console.WriteLine("Release attribute is {0} applied to ReleaseApp", Attribute.IsDefined(typeof(ReleaseApp), typeof(ReleaseAttribute)) ? "" : "not");
}
}