The answer from @Slauma is really great but I found that it didnt't work when a ComplexType property was invalid.
For example, say you have a property Phone
of the complex type PhoneNumber
. If the AreaCode
property is invalid, the property name in ve.PropertyNames
is "Phone.AreaCode". This causes the call to eve.Entry.CurrentValues
to fail.
To fix this, you can split the property name at each .
, then recurse through the resulting array of property names. Finally, when you arrive at the bottom of the chain, you can simply return the value of the property.
Below is @Slauma's FormattedDbEntityValidationException
class with support for ComplexTypes.
Enjoy!
[Serializable]
public class FormattedDbEntityValidationException : Exception
{
public FormattedDbEntityValidationException(DbEntityValidationException innerException) :
base(null, innerException)
{
}
public override string Message
{
get
{
var innerException = InnerException as DbEntityValidationException;
if (innerException == null) return base.Message;
var sb = new StringBuilder();
sb.AppendLine();
sb.AppendLine();
foreach (var eve in innerException.EntityValidationErrors)
{
sb.AppendLine(string.Format("- Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
eve.Entry.Entity.GetType().FullName, eve.Entry.State));
foreach (var ve in eve.ValidationErrors)
{
object value;
if (ve.PropertyName.Contains("."))
{
var propertyChain = ve.PropertyName.Split('.');
var complexProperty = eve.Entry.CurrentValues.GetValue(propertyChain.First());
value = GetComplexPropertyValue(complexProperty, propertyChain.Skip(1).ToArray());
}
else
{
value = eve.Entry.CurrentValues.GetValue