Custom Validation Error message not displayed

 

A customer pointed out that his Spanish validation error messages were not being displayed; the default Error message was shown instead.  I'll use the Products table from the NorthWind Db to reproduce the problem and show a work-around.

Create a partial class for the Products entity:

  [MetadataType(typeof(ProductsMD))]
    public partial class Products {
        public class ProductsMD {
            [DataType("dummy", ErrorMessage = "El campo debe ser un entero positivo")]
            [DisplayName("En la acción")]
            public object UnitsInStock { get; set; }
        }
    }
 VB
     <MetadataType(GetType(ProductsMD))> _
Public Class Products
        Public Class ProductsMD
            <DataType("dummy", ErrorMessage:="El campo debe ser un entero positivo"), _
             DisplayName("En la acción")> _
            Public Property UnitsInStock() As Object
            End Property
        End Class
    End Class

Navigate to the Products table, edit a row, and change the UnitsInStock to a letter. Select update and you will get a default error message, not the message applied with the DataType attribute.

The example above was doomed to failure as the DataType attribute above does not match the DataType enum or have a matching field template.

There are a couple of possible solutions for displaying custom validation errors on integer conversion failure. You can add the compare validator message that will be displayed for any validation error. The code should be added as the last statement of the Page_Load method in the DynamicData\FieldTemplates\Integer_Edit.ascx.cs  (or .vb) file.

CompareValidator1.ErrorMessage = String.Format("El campo {0} debe ser un entero", Column.DisplayName);

or for VB

CompareValidator1.ErrorMessage = String.Format("El campo {0} debe ser un entero", Column.DisplayName)

Entering a non-integer such as Z to the units in stock field now yields the following error message:

El campo En la acción debe ser un entero

Adding the CompareValidator1.ErrorMessage to the integer template works for every scaffolded integer.

For more flexibility, you can extract the custom message from the data model partial class. Replace the CompareValidator1.ErrorMessage  line above with the following in the Page_Load method.

  var dataTypeAttribute = MetadataAttributes.OfType<DataTypeAttribute>().SingleOrDefault();

 if (dataTypeAttribute != null) {
    CompareValidator1.ErrorMessage = dataTypeAttribute.FormatErrorMessage(Column.DisplayName);
 }

VB

 Dim dataTypeAttribute = MetadataAttributes.OfType(Of DataTypeAttribute)().SingleOrDefault() 

If dataTypeAttribute IsNot Nothing Then 
    CompareValidator1.ErrorMessage = dataTypeAttribute.FormatErrorMessage(Column.DisplayName) 
End If 

Even simpler than adding a dummy attribute and extracting the error message;  use the RegularExpression attribute and allow only positive integers. The following snippet fixes the error message problem without requiring you to extract the error message in the Page_Load method.

   [MetadataType(typeof(ProductsMD))]
    public partial class Products {
        public class ProductsMD {
  //          [DataType("dummy", ErrorMessage = "El campo debe ser un entero positivo")]
            [RegularExpression(@"^0*[1-9][0-9]*$", ErrorMessage = "Must be a entero positivo")]
            [DisplayName("En la acción")]
            public object UnitsInStock { get; set; }
        }
    }
 VB
 <MetadataType(GetType(ProductsMD))> _ 
Public Partial Class Products 
    Public Class ProductsMD 
Private _UnitsInStock As Object 
        ' [DataType("dummy", ErrorMessage = "El campo debe ser un entero positivo")] 
        <RegularExpression("^0*[1-9][0-9]*$", ErrorMessage := "Must be a entero positivo")> _ 
        <DisplayName("En la acción")> _ 
        Public Property UnitsInStock() As Object 
            Get 
                Return _UnitsInStock 
            End Get 
            Set(ByVal value As Object) 
                _UnitsInStock = value 
            End Set 
        End Property 
    End Class 
End Class 

Notes:

  1. We are using the DataType attribute as a dummy attribute so we can extract our custom error message when a validation error occurs.
  2. This is a known bug that should be fixed in the next release.