views:

563

answers:

1

I wish to set an attribute on a public property in .NET, however I do not have access to the explicit property itself, as this has been code generated in another file.

I have this field:

public virtual string Name { get; set; }

I wish to set this:

[ValidateNonEmpty("Name is required", ExecutionOrder = 1)]
public virtual string Name { get; set; }

My class is marked as partial, but you cannot have partial properties. I thought I was on to something with the MetadataType class which is a new feature of Dynamic Data and DataAnnotations, but alas I feel it can only be used with Dynamic Data, is this true?

Citations: http://blogs.oosterkamp.nl/blogs/jowen/archive/2008/10/16/metadatatype-attribute.aspx http://blogs.msdn.com/davidebb/archive/2008/06/16/dynamic-data-and-the-associated-metadata-class.aspx

Is there any way I can set this attributes (even through web.config!) without touching the code generated class?

Thanks in advance, Graham

+7  A: 

This is a known nuisance; you simply can't add metadata to the generated members.

There are 6 options here (in order of increasing effort):

  • if you own the attribute, make it possible to declare it against the class, for example: [ValidateNonEmpty("Name", "Name is required", ExecutionOrder = 1)] - then add multiple attributes to the partial class definition
  • use a virtual / interface / etc method to query this, rather than via attributes
  • sublass the generated type; override or re-declare the member, adding the metadata (really messy)
  • use a custom TypeDescriptionProvider to provide dynamic metadata (lots and lots of work) - assuming that the consumer respects TypeDescriptor; most binding-related consumers do, but for example, Expression (used by many LINQ providers) doesn't
  • change the code-generator / write your own
  • try to extend something like PostSharp to do the work (I haven't found a way to do this, but I've love to hear if you find a way!)

I usually have success with the first option, unless it is a system-defined attribute ([DisplayName], etc). If [ValidateNonEmpty] is defined by dynamic data, then you might not be able to do this.

Marc Gravell
Thanks Marc,I thought this might be the case. I've managed to iterate through the properties of my "MetadataType" declared class, at the point I wished to enquire on the attributes, and I simply compare the name of the "meta" property against the real property.
GONeale
It is not the same as inquisting the true attributes, I understand, but for what I need it looks like it will serve the purpose in this case. Which is great.
GONeale
Hopefully this makes sense. I can now see if a validation attribute was declared and work accordingly. I now just hope there is no overhead with me utilising the `MetadataType` attribute class rather than making my own that simply tells it what class to look at properties on.
GONeale