Data Access has been discontinued. Please refer to this page for more information.

How to: Implement the IDataErrorInfo Interface

This article is relevant to entity models that utilize the deprecated Visual Studio integration of Telerik Data Access. The current documentation of the Data Access framework is available here.

The IDataErrorInfo interface defines members which can help you if you need to offer custom validation rules and to provide client-friendly validation results to the users. With Telerik Data Access you can implement it for your domain classes with just a few mouse clicks during either the creation of your domain model or on a later stage when you modify it.

This topic will demonstrate to you how to control the implementation of IDataErrorInfo. The necessary settings can be found on the Code Generation Settings page in either the Advanced Options dialogue of the Create Model wizard or the Code Generation Settings tab in the Model Settings dialogue.

The process is as follows:

  1. Navigate to the Advanced Options dialogue of the Create Model wizard or open the Code Generation Settings tab in Model Settings.
  2. In the Code Generation Options section check the Implement IDataErrorInfor Interface check-box

The Implement IDataErrorInfo option is available only in Visual Studio 2010 and Visual Studio 2012.

  1. Click Finish if you are using the wizard or OK for Model Settings
  2. Save the domain model if you are using the Model Settings dialogue - In both cases, your domain classes will look similar to the Category class from the SofiaCarRental sample database:
public partial class Category : IDataErrorInfo
{
    private int _categoryID;
    public virtual int CategoryID
    {
        get
        {
            return this._categoryID;
        }
        set
        {
            this._categoryID = value;
        }
    }

    private string _categoryName;
    public virtual string CategoryName
    {
        get
        {
            return this._categoryName;
        }
        set
        {
            this._categoryName = value;
        }
    }

    private IList<Car> _cars = new List<Car>();
    public virtual IList<Car> Cars
    {
        get
        {
            return this._cars;
        }
    }

    private string error = string.Empty;
    public string Error
    {
        get
        {
            return this.error;
        }
    }

    public string this[string propertyName]
    {
        get
        {
            this.ValidatePropertyInternal(propertyName, ref this.error);

            return this.error;
        }
    }

    protected virtual void ValidatePropertyInternal(string propertyName, ref string error)
    {
        this.ValidateProperty(propertyName, ref error);
    }

    // Please implement this method in a partial class in order to provide 
    // the error message depending on each of the properties.
    partial void ValidateProperty(string propertyName, ref string error);
}
Public Partial Class Category
    Implements IDataErrorInfo
    Private _categoryID As Integer 
    Public Overridable Property CategoryID As Integer
        Get
            Return Me._categoryID
        End Get
        Set(ByVal value As Integer)
            Me._categoryID = value
        End Set
    End Property

    Private _categoryName As String 
    Public Overridable Property CategoryName As String
        Get
            Return Me._categoryName
        End Get
        Set(ByVal value As String)
            Me._categoryName = value
        End Set
    End Property

    Private _cars As IList(Of Car)  = New List(Of Car)
    Public Overridable ReadOnly Property Cars As IList(Of Car)
        Get
            Return Me._cars
        End Get
    End Property

    Private _error As String = String.Empty
    Public ReadOnly Property [Error]() As String Implements IDataErrorInfo.Error
        Get
            Return Me._error
        End Get
    End Property

    Public ReadOnly Property Item(ByVal propertyName As String) As String Implements IDataErrorInfo.Item
        Get
            Me.ValidatePropertyInternal(propertyName, Me._error)

            Return Me._error
        End Get
    End Property

    Protected Overridable Sub ValidatePropertyInternal(propertyName As String, ByRef [error] As String)
        Me.ValidateProperty(propertyName, [error])
    End Sub

    ' Please implement this method in a partial class in order to provide 
    ' the error message depending on each of the properties.
    Partial Private Sub ValidateProperty(ByVal propertyName As String, ByRef _error As String)
    End Sub

End Class

Make sure to implement the ValidateProperty() method in a partial class that extends the domain class. For example:

public partial class Category
{
    partial void ValidateProperty(string propertyName, ref string error)
    {
        error = string.Empty;
        switch (propertyName)
        {
            case "CategoryID": 
                if (CategoryID > 0)
                {
                    error = "The identification number of the category cannot be negative";
                }
                break;
            case "CategoryName":
                if (string.IsNullOrWhiteSpace(CategoryName))
                {
                    error = "You need to provide a name for the category";
                }
                break;
        }
    }
}
Partial Public Class Category
    Private Sub ValidateProperty(ByVal propertyName As String, ByRef [error] As String)
        [error] = String.Empty
        Select Case propertyName
            Case "CategoryID"
                If CategoryID > 0 Then
                    [error] = "The identification number of the category cannot be negative"
                End If
            Case "CategoryName"
                If String.IsNullOrWhiteSpace(CategoryName) Then
                    [error] = "You need to provide a name for the category"
                End If
        End Select
    End Sub
End Class

If the domain classes were created with implementation of IDataErrorInfo and at some point you uncheck Implement IDataErrorInfo Interface, it will be removed once you save the model. You can restored it by applying the described process.