For my application (ASP.NET MVC 3.0 RTM, Razor View Engine), I would like to use DataAnnotations for my models. If I keep the model classes within the web project, I can have resx resources in App_GlobalResources or App_LocalResources without embedding the .resx
into .resources
files.
Ignoring newly spawned AppDomains and other considerations, this is ideal because changing something minor in a localized resource like a typo or incorrect translation doesn't require compilation.
However, after moving my models to a class library I don't see any way to keep .resx
files as the output and still use DataAnnotations attributes. Am I missing something?
The problem lies in the way the attributes find resources. For instance, a "Name" property might look like this:
[Display(Name = "MyEntity_Name", ResourceType = typeof(Validations))]
[Required(ErrorMessageResourceName="MyEntity_Name_Required",
ErrorMessageResourceType = typeof(Validations))]
[StringLength(150, MinimumLength = 2)]
public string Name { get; set; }
This requirement for a strongly-typed resource wrapper has become the bane of my existence over the past 24 hours.
I've tried to genericize the wrapper, but it seems like the validation attributes specifically look for a property on the wrapper called MyEntity_Name
for the DisplayAttribute and MyEntity_Name_Required
for the RequiredAttribute. I haven't dug any deeper into the DataAnnotations code to see if there is some magic I can pull off. I was hoping someone else encountered this and had any ideas.
The Question
Is it possible to use DataAnnotations ValidationAttributes (including DisplayAttribute) in a class library without embedding the resx files into .resources
files?
The Gotchas :(
In the future, I'd like to move from resx to database-driven resources with very minimal coding effort. I can't do that right now because of limited resources (no pun intended). So, I want to avoid bypassing the ResourceProvider. Also, I want to avoid rewriting or wrapping all of the attributes in the System.ComponentModel.DataAnnotations namespace.
Am I missing something?
Yes, you are missing View Models. Controller actions take/pass view models from/to views and not models. View models are classes which are specifically tailored to the needs of a given view. They contain the only the required properties and the proper formatting for the given view. A view model could be a subset of a model or an aggregation of multiple models (it depends on the requirements of the view). View models are always defined in the web project because they are very tightly coupled to views. So it is view models that you should localize/globalize with resources.
Example of workflow:
Conclusion: models should not be formatted/localized or they become more difficult to reuse.