16

I have a model classes that has a description property with a data annotation attribute of StringLength and length is set to 100 characters. When this property is more than 100 characters and Entity Framework tries to save this property I get the following error.

 [StringLength(100, ErrorMessage = "Description Max Length is 100")]
        public string Description { get; set; }

Error:
"Validation failed for one or more entities. See 'EntityValidationErrors' property for more details"

I'm not sure if this helps in forming a solution, but I'm using Entity Framework CTP5 and Code First.

What I want to do, is if description is more than 100 characters, then remove characters that are more than 100 characters so that description can be stored and no error will be raised.

I believe I should be able to use the DataAnnotation attribute StringLength manually to help me identify the valid length of description and then use SubString to remove any characters over the valid amount.

Does anyone know how to use DataAnnotation in this situation? Or is there another options that is available?


Update I did what BrokenGlass suggested and here my implementation if:

public static class DataAnnotation
{
    public static int? GetMaxLengthFromStringLengthAttribute(Type modelClass, string propertyName)
    {
        int? maxLength = null;
        var attribute = modelClass.GetProperties()
                        .Where(p => p.Name == propertyName)
                        .Single()
                        .GetCustomAttributes(typeof(StringLengthAttribute), true)
                        .Single() as StringLengthAttribute;

        if (attribute != null)
            maxLength = attribute.MaximumLength;

        return maxLength;
    }
}


int? maxLength = DataAnnotation.GetMaxLengthFromStringLengthAttribute(typeof(Car), "Description");

if(maxLength != null && car.Description.Length > maxLength)
    car.Description = car.Description.Substring(0, maxLength.Value);

BarDev

Mike Barlow - BarDev
  • 11,087
  • 17
  • 62
  • 83
  • Are there any other tags that I should add for this question? – Mike Barlow - BarDev Mar 13 '11 at 05:48
  • Don't know much about DataAnnotation. As for other options, you could just implement the getters/setters, and do a check/truncation in the setter. – Rob Mar 13 '11 at 05:55
  • Thanks for the suggestion. I just did that as a work around. I'm probably over complicating the issue. But, I can see different situations where I would like to have Validation and other situations where I would like to remove extra characters. In my WCF application, I would want the remove the extra character and not raise an error, but in a data entry application such ASP.NET or Win Forms I would like to trigger an validation message to the user. – Mike Barlow - BarDev Mar 13 '11 at 06:10
  • 1
    Good solution, I don't see the point in returning the Nullable. Default is zero, so you may as well just return Int zero if the DataAnnotation isn't set. – Paul Talbot Nov 14 '13 at 13:05

3 Answers3

11

You could always check the attribute value using reflection, though that approach is not the best if you can get around it - it's not pretty:

var attribute = typeof(ModelClass).GetProperties()
                                  .Where(p => p.Name == "Description")
                                  .Single()
                                  .GetCustomAttributes(typeof(StringLengthAttribute), true) 
                                  .Single() as StringLengthAttribute;

Console.WriteLine("Maximum Length: {0}", attribute.MaximumLength);    
BrokenGlass
  • 158,293
  • 28
  • 286
  • 335
  • I might use this. I could encapsulate this and call it from any part of my code. I'm going to wait a little longer and see if I get any additional answers. Thanks for the answer. – Mike Barlow - BarDev Mar 13 '11 at 07:58
11

Why all the hassle? Why not

private string _description = string.Empty;

[StringLength(100, ErrorMessage = "Description Max Length is 100")]
public string Description 
{  
    get { return _description; }
    set { _description = value.Substring(0,100); };  // or something equivalent
} 
Raymond
  • 3,382
  • 5
  • 43
  • 67
  • 12
    Your `set` is completely defeating validation, just silently truncating. That's nonsensical. Either validate, or truncate. But truncating silently is a horrible, horrible idea. – ErikE Sep 03 '15 at 17:41
2

Create a view model that doesn't have a data annotation for the length, then you can map it to the entity model and truncate the value if it's longer than 100.

Derek Beattie
  • 9,429
  • 4
  • 30
  • 44
  • I should have mentioned that I need the data annotation for valiation in my MVC3 application, so that I do not have to repeat code. – Mike Barlow - BarDev Mar 13 '11 at 07:39
  • It all depends on where you want to enforce constraints. I tend to keep my "data" model clean and force the ViewModel to validate so my ViewModel has the annotations. – Derek Beattie Mar 13 '11 at 16:02