WCF RIA Service adding extra Required attribute on generated classes

Few days back, I upgraded a Silverlight 3 RIA application to Silveright 4 bits. Once I fixed all the errors, it appeared that RIA generated entities were “over-validating” themselves. I noticed that all the string entities that were marked not-nullable in database were giving validation errors saying "Field XYZ is required". I looked through the attribute metadata classes and those field were not marked Required. However, the generated RIA classes had Required and StringLength attributes automatically applied on such fields. It looks RIA code generation is over-efficient and it automatically adds Required attributes for all non-nullable database fields. This doesn’t seem much problematic since we can easily write an implementation of the partial method OnCreated for our generated entities where we can assign default values to all fields. As a generic approach, we can write a reflective method that assign default values like this:

public static void SetDefaults(object obj)
    DateTime defaultDate = new DateTime(1753, 1, 1);
    PropertyInfo[] infos = obj.GetType().GetProperties();
    foreach (PropertyInfo info in infos)
        if (info.CanWrite)
            //numeric fields (int, double etc) are already defaulted to 0
            if (info.PropertyType == typeof(string)) 
                info.SetValue(obj, string.Empty, null);
            //date fields
            else if (info.PropertyType == typeof(DateTime))
                info.SetValue(obj, defaultDate, null);

            else if (info.PropertyType == typeof(byte[]))
                info.SetValue(obj, new byte[1], null);

The above method needs to be called from the partial implementation of OnCreated for our generated data classes. However, things will still not work normally as there’s still a small point left: The Required attribute on string fields does not allow empty string. To tackle this, we need to decorate all our string fields in the metadata class (located in server project) with [Required(AllowEmptyString = true)]. That’s all.

5 Responses to “WCF RIA Service adding extra Required attribute on generated classes”

  1. DotNetShoutout Says:

    WCF RIA Service adding extra Required attribute on generated classes « Mehroz’s Experiments…

    Thank you for submitting this cool story – Trackback from DotNetShoutout…

  2. Shimmy Says:

    I don’t think it’s over efficient, I think it’s super efficient, and this is how it should work.
    I just think they have to make it more obvious and even more efficient (for example managing the string length according to the one in the database etc.).

  3. Shimmy Says:

    And BTW, for value types (non-nullable types), you gain the default value in a more generic way: default(DateTime).

  4. jjds Says:

    What if column is a computed column such as timestamp? It will throw required validation error, and you won’t be able to assign default value because it is computed and readonly.

  5. jjds Says:

    Then if you set Nullable = False in EF designer then you will get an error 3301: non-nullable column mapped to a nullable column.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: