views:

1232

answers:

4

Hi,

I have an attribute and i want to load text to the attribute from a resource file.

[IntegerValidation(1, 70, ErrorMessage = Data.Messages.Speed)] private int i_Speed;

But i keep getting "An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type"

It works perfectly if i add a string instead of Data.Messages.Text, like: [IntegerValidation(1, 70, ErrorMessage = "Invalid max speed")]

Any ideas?

+1  A: 

Use a string which is the name of the resource. .NET does this with some internal attributes.

John Saunders
+6  A: 

Attribute values are hard-coded into the assembly when you compile. If you want to do anything at execution time, you'll need to use a constant as the key, then put some code into the attribute class itself to load the resource.

Jon Skeet
A: 

The nature if attributes is such that the data you put in attribute properties must be constants. These values will be stored within an assembly, but will never result in compiled code that is executed. Thus you cannot have attribute values that relies on being executed in order to calculate the results.

Peter Lillevold
+4  A: 

Here is my solution. I've added resourceName and resourceType properties to attribute, like microsoft has done in DataAnnotations.

public class CustomAttribute : Attribute
{

    public CustomAttribute(Type resourceType, string resourceName)
    {
      Message = ResourceHelper.GetResourceLookup(resourceType, resourceName);
    }

    public string Message { get; set; }
}

public class ResourceHelper
{
    public static  string GetResourceLookup(Type resourceType, string resourceName)
    {
     if ((resourceType != null) && (resourceName != null))
     {
      PropertyInfo property = resourceType.GetProperty(resourceName, BindingFlags.Public | BindingFlags.Static);
      if (property == null)
      {
       throw new InvalidOperationException(string.Format("Resource Type Does Not Have Property"));
      }
      if (property.PropertyType != typeof(string))
      {
       throw new InvalidOperationException(string.Format("Resource Property is Not String Type"));
      }
      return (string)property.GetValue(null, null);
     }
     return null; 
 }
}
Peter Starbek