HEADLINE: edmProperty.TypeUsage.Facets[“MaxLength”].Value comes in handy.
I don’t make a habit of making a post when someone else has done some work… I might point it out, and in that spirit here is the post that finally sent me in the right direction: http://soci.hu/blog/. However, the post is not in English (fortunately, C# is spoken internationally :-)) and it doesn’t solve the problem but provided the hint I needed to break through.
The Problem
Here is my problem. I’m working on an MVC application and I don’t want to have to manually write code that will check that user input has not exceeded the maximum length. Now you can use various annotation approaches for this, but I choose to use an approach that is more easily tested.
I throw an exception that I then catch and turn into an error that is exposed via the IDataErrorInfo interface so my MVC user knows that they’ve input a string that exceeds the maximum. (And this pattern was from Steven Sanderson’s book on MVC).
My Solution
Here’s what the final code looks like in a class of mine:
- try
- {
- if (value.Length > 10) // Added so we don't need to write code manually to verify the length of string properties. This will bubble up as message to user.
- {
- throw new ArgumentException(String.Format(Properties.Resources.EntityFrameworkStringMaxLengthError, "Abbr", "10"));
- }
- _abbr = value;
- OnPropertyChanged("Abbr");
- }
How I Did It
I’m using the Entity Framework (EF) Self Tracking Entities (STEs) templates with a fair number of modifications. Here is one more modification I made. Inside the setter in the .tt file for the types (Model.tt) I added the following:
- if (<#=code.FieldName(edmProperty)#> != value)
- <#
- }
- #>
- {
- try
- {
- <# if (code.Escape(edmProperty.TypeUsage) == "string")
- {
- string facetName = "MaxLength";
- int maxLength = 0;
- if (Int32.TryParse(edmProperty.TypeUsage.Facets[facetName].Value.ToString(), out maxLength))
- {
- #>
- if (value.Length > <#= maxLength.ToString() #>) // Added so we don't need to write code manually to verify the length of string properties. This will bubble up as message to user.
- {
- throw new ArgumentException(String.Format(Properties.Resources.EntityFrameworkStringMaxLengthError, "<#= code.Escape(edmProperty) #>", "<#= maxLength.ToString() #>"));
- }
- <#
- }
- }
- #>
The key element which I got from that important post I mentioned earlier is the the property that contains the MaxLength value from your .edmx file. That is: edmProperty.TypeUsage.Facets[“MaxLength”].Value.
Since I work to eliminate all the code warnings Microsoft so kindly provides me I place the errors in the resources file. Here is what that looks like in my Resources.resx file:
- Name: EntityFrameworkStringMaxLengthError
- Value: {0} must be {1} characters or less.
- Comment: Where {0} is the name of the property and {1} is the MaxLength for the string.
So now if someone inputs a value that is too long, here is what they will see in my user interface:
So as my requirements change, I don’t really have to do too much in my code to communicate effectively with my users.
The Entity Framework, MVC 2, .NET 4.0 and Visual Studio 2010 are coming along nicely.