12

I'm trying implement Data Annotation to my Linq to SQL objects. The .dbml file is generated and I'm not sure how to add data annotation to the objects without touching the generated source code.

I tried to add data annotations to the a separate partial class of the object, but its not recognizing it, no Intelli sense either.

4 Answers 4

22

As I said in my original answer to this question, you should use an interface. The answer posted after mine (which was marked as Accepted) said to use a class. This is not as good. An interface is a better option for the following reasons:

  • If there is a mismatch between the name in your LINQ class and the name in your interface, the compiler will flag it for you
  • An interface can not be instantiated, so this protects class users from accidentally instatntiating the metadata type
  • If you use Resharper (or similar), the interface can be automatically extracted from the LINQ class
  • An interface is less verbose than an empty class
  • If you program against interfaces rather than classes (which is a good practice), then you've already got an interface you can use as your metadata type

For a class called, say "User", create an interface for it (say 'IUser'), and then update the definition of your partial User class as follows:

[MetadataType(typeof(IUser))]
public class User : IUser

Then, in your IUser interface, add appropriate Data Annotation attributes to the properties:

[Required]       
[StringLength(50, ErrorMessage = "Username cannot exceed 50 characters")]
string Username { get; set; }
Sign up to request clarification or add additional context in comments.

4 Comments

I really like this approach, except I can't add a [Bind(Exclude = "ID")] attribute to the interface, so I had to put it on the class. That works, but the metadata is now split between the class and the interface.
But what should I do, if I have some extra field in my model? For instance, I have additional Confirm Password field. If I put this field in interface compiler won't pass this out because there's no such field in base Linq to SQL class.
But how do I generate these attributes automatically? The dbml has everything it needs to generate them. I have 20 tables with dozens of columns in each... I'm not going to try to maintain that manually. Anybody have a solution?
I tried this approach with no luck in a WCF project :(
9

For a class called, say "User", create an interface for it (say 'IUser'), and then update the definition of your partial User class as follows:

[MetadataType(typeof(IUser))]
public class User : IUser

Then, in your IUser interface, add appropriate Data Annotation attributes to the properties:

[Required]       
[StringLength(50, ErrorMessage = "Username cannot exceed 50 characters")]
string Username { get; set; }

Comments

6

Linq to SQL generates object classes as partial. An easy way to implement data annotations is to create your own partial class of the object, place the [MetadataType(typeof(YourDataAnnotationClass))] on the partial class you created.

Example:

// Linq to SQL Class
public partial class Article 
{
   public string Title { get; set; }
   ...... etc
}

Create your own MetaData class with Metadata for each field you want to validate

public class MyMetaDataClass
{
    [Required]
    [Range(5,20)]
    public string Title { get; set; }
}

Create a Partial Class for the Object class you want to add metadata to, in this case Articles class:

[MetadataType(typeof(MyMetaDataClass))]
public partial class Article { }

Note: you don't need to specify anything in the class, just the metadata type.

Comments

3

Thanks,but the problem is MS define the prototype of MetadataTypeAttrubute as

[AttributeUsageAttribute(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public sealed class MetadataTypeAttribute : Attribute

So, you had to use class but not interface


From China Forest Lee: 李晓强 [email protected] (MSN) [email protected]

2 Comments

It works even with the interface regardless of what the definition says.
I can't make it work neither interface nor class :( Im trying to add IgnoreDataMember to some of the auto-generated Properties of my partial classes in a WCF project

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.