Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add an attribute to a property at runtime

Tags:

c#

attributes

//Get PropertyDescriptor object for the given property name var propDesc = TypeDescriptor.GetProperties(typeof(T))[propName];  //Get FillAttributes methodinfo delegate var methodInfo = propDesc.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public |                                                       BindingFlags.NonPublic)     .FirstOrDefault(m => m.IsFamily || m.IsPublic && m.Name == "FillAttributes");  //Create Validation attribute var attribute = new RequiredAttribute(); var  attributes= new ValidationAttribute[]{attribute};  //Invoke FillAttribute method methodInfo.Invoke(propDesc, new object[] { attributes }); 

Hi I am trying to add Validation attribute at runtime using the above code. However I am getting the below exception:

Collection was of a fixed size

like image 216
Thiru kumaran Avatar asked Feb 02 '13 16:02

Thiru kumaran


People also ask

Is it possible to modify object properties run time?

You can't.

What is an attribute C#?

Advertisements. An attribute is a declarative tag that is used to convey information to runtime about the behaviors of various elements like classes, methods, structures, enumerators, assemblies etc. in your program. You can add declarative information to a program by using an attribute.


2 Answers

Don't let someone tell you that you can't do it. You can run for president if you want :-)

For your convenience, this is a fully working example

public class SomeAttribute : Attribute {     public SomeAttribute(string value)     {         this.Value = value;     }      public string Value { get; set; } }  public class SomeClass {     public string Value = "Test"; }  [TestMethod] public void CanAddAttribute() {     var type = typeof(SomeClass);      var aName = new System.Reflection.AssemblyName("SomeNamespace");     var ab = AppDomain.CurrentDomain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.Run);     var mb = ab.DefineDynamicModule(aName.Name);     var tb = mb.DefineType(type.Name + "Proxy", System.Reflection.TypeAttributes.Public, type);      var attrCtorParams = new Type[] { typeof(string) };     var attrCtorInfo = typeof(SomeAttribute).GetConstructor(attrCtorParams);     var attrBuilder = new CustomAttributeBuilder(attrCtorInfo, new object[] { "Some Value" });     tb.SetCustomAttribute(attrBuilder);      var newType = tb.CreateType();     var instance = (SomeClass)Activator.CreateInstance(newType);      Assert.AreEqual("Test", instance.Value);     var attr = (SomeAttribute)instance.GetType()         .GetCustomAttributes(typeof(SomeAttribute), false)         .SingleOrDefault();     Assert.IsNotNull(attr);     Assert.AreEqual(attr.Value, "Some Value"); } 
like image 117
Jürgen Steinblock Avatar answered Oct 02 '22 09:10

Jürgen Steinblock


Use FastDeepCloner which I developed.

public class test{     public string Name{ get; set; } }  var prop = DeepCloner.GetFastDeepClonerProperties(typeof(test)).First(); prop.Attributes.Add(new JsonIgnoreAttribute()); // now test and se if exist  prop = DeepCloner.GetFastDeepClonerProperties(typeof(test)).First(); bool containAttr = prop.ContainAttribute<JsonIgnoreAttribute>() // or  JsonIgnoreAttribute myAttr = prop.GetCustomAttribute<JsonIgnoreAttribute>(); 
like image 23
Alen.Toma Avatar answered Oct 02 '22 07:10

Alen.Toma