11

I have used the Entity Framework with VS2010 to create a simple person class with properties, firstName, lastName, and email. If I want to attach DataAnnotations like as is done in this blog post I have a small problem because my person class is dynamically generated. I could edit the dynamically generated code directly but any time I have to update my model all my validation code would get wiped out.

First instinct was to create a partial class and try to attach annotations but it complains that I'm trying to redefine the property. I'm not sure if you can make property declarations in C# like function declarations in C++. If you could that might be the answer. Here's a snippet of what I tried:

namespace PersonWeb.Models
{
  public partial class Person
  {
    [RegularExpression(@"(\w|\.)+@(\w|\.)+", ErrorMessage = "Email is invalid")]
    public string Email { get; set; } 
    /* ERROR: The type 'Person' already contains a definition for 'Email' */
  }
}
dcompiled
  • 4,762
  • 6
  • 33
  • 36
  • i'm really disappointed you can't define a partial class and decorate it with Data Annotations as you show in your code sample. That was my first instinct; then I came across this post and don't see any solutions which seem appealing to me. The ef team should provide a mapping mechanism to circumvent this rather annoying idiosyncrasy. – Shawn J. Molloy Aug 21 '14 at 03:37

2 Answers2

25

A buddy class is more or less the direction your code snippet is journeying, except your manually coded partial Person class would have an inner class, like:

[MetadataType(typeof(Person.Metadata))]
public partial class Person {
    private sealed class MetaData {
        [RegularExpression(...)]
        public string Email { get; set; }
    }
}

Or you could have your manually partial Person class and a separate Meta class like:

[MetadataType(typeof(PersonMetaData))]
public partial class Person { }

public class PersonMetaData {
[RegularExpression(...)]
public string Email;
}

These are workarounds and having a mapped Presentation class may be more suitable.

Michael Finger
  • 1,110
  • 9
  • 9
  • Would you be so kind to elaborate on the 'mapped Presentation class' you mentioned? – Rosdi Kasim Feb 21 '13 at 08:49
  • Sure. I probably should have said View Model rather than presentation class. The link in Craig Stuntz's comment below has an example. Also: http://stackoverflow.com/questions/2859618/should-i-map-a-domain-object-to-a-view-model-using-an-optional-constructor http://stackoverflow.com/questions/8298401/patterns-for-mapping-data-between-domain-models – Michael Finger Feb 25 '13 at 14:33
3

You need to either use a metadata "buddy" class or (my preference) project onto a presentation model instead of binding views directly to entities.

Craig Stuntz
  • 125,891
  • 12
  • 252
  • 273
  • Can you give some more detail on your approach to metadata "buddy" classes. I'd prefer if the presentational code and validation had a separation of concerns. – dcompiled Jun 08 '10 at 19:10
  • "My approach" to "buddy" classes is to not use them. Like I said, I use presentation models. If you want *real* separation of concerns, that's the way to go. – Craig Stuntz Jun 08 '10 at 20:28
  • Its just a matter of style, I think all the validation code and associated metadata should solely remain in the model. It seems you prefer to have validation code mixed with the presentation model. – dcompiled Jun 09 '10 at 23:37
  • No, that completely misunderstands what I said. Data integrity validations, which belong in the model, are not the same thing as presentation model metadata. In MVC, this distinction is illustrated by the difference between read-only properties in the model and associated metadata providers in the presentation. Model rules should surface in the presentation automatically; manually decorating via attributes should only be necessary when the rules for a particular scenario are more restrictive than the model on general. – Craig Stuntz Jun 09 '10 at 23:55