Wednesday, March 25, 2009

WCF datacontracts and IDataErrorInfo

For those of you who are using WCF you not be aware of an interface that when implemented on your DataContracts allows you validate and reject invalid values.

This can be leveraged in either ASP.NET or WPF by binding the UI controls to the DataContract to give you client side input validation.


Its use is well documented in WPF , MCV framework, but iI could find nothing around using it on DataContracts. Of course you can only take advantage of this if you are WCF to WCF.

This post is not about using IDataErrorInfo, but solving a particular prolem related to its use.

Problem statement :

When using IDataErrorInfo in an inheretence hierachy we run into problems when the property that needs to be validated is on the base class. The reason for this is that it is the subclass that is casted to IDataErrorInfo and then validates. We need a way to ensure that properties are also validated in the base class.

As a first solution you’ll probably try something like;

(base as IDataErrorInfo)[“PropertyToValidate”] ,but this does not work, as the base keyword is invalid in the above statement.

A second solution would be to have a method on the base class and then have it validate its property, something like;

string Validate(string columnName)
{
Return (this as IDataErrorInfo)[“PropertyToValidate”]
}

But this also fails as it will cast the subclass instance into IDataErrorInfo and then validate the subclass.

So we have to come up with a solution that will ensure that the correct class’s properties be validated.

Solution :

The solution to this problem is actually a combination of the two proposed solutions above. We have the subclass call a method on the base to do the validation, but we also have the IDataErrorInfo methods call this same method to do the validation.

This way even if our subclass does not implement IDataErrorInfo, but only want’s the base class to do the validation it will still work. See code example below.

Base Class Definition:

public abstract class BaseClass : IDataErrorInfo
{
protected string m_Error;
public string BaseClassProperty { get; set; }

string IDataErrorInfo.Error

{
get
{
return m_Error;
}
}

string IDataErrorInfo.this[string columnName]
{
get
{
return Validate(columnName);
}
}

protected internal string Validate(string columnName)
{
m_Error = String.Empty;

if (columnName == "BaseClassProperty")
{
if (String.IsNullOrEmpty(BaseClassProperty))
{
m_Error = "BaseClassProperty not set.";
}
}

return m_Error;
}
}


research by E. Landsberg

No comments: