Entity framework DbDomainService和IValidatableObject

Entity framework DbDomainService和IValidatableObject,entity-framework,silverlight,wcf-ria-services,domainservices,Entity Framework,Silverlight,Wcf Ria Services,Domainservices,我有一个实现IValidatableObject的POCO对象 public class Documentation : IValidatableObject { [Key] public int DocumentationId { get; set; } [ForeignKey("Project")] public int ProjectId { get; set; } public virtual Project Project { get; se

我有一个实现IValidatableObject的POCO对象

public class Documentation : IValidatableObject
{
    [Key]
    public int DocumentationId { get; set; }

    [ForeignKey("Project")]
    public int ProjectId { get; set; }

    public virtual Project Project { get; set; }

    public string FileGuid { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        return new[] { new ValidationResult("File has not been uploaded", new[] { "FileGuid" }) };
    }

}

示例代码是

如上图所示,原始代码存在两个问题

首先,DomainService不会为IValidatableObject验证错误引发ValidationException。只有DataAnnotation验证抛出ValidationException。所以首先要解决的是我的测试用例:

[TestMethod] //, ExpectedException(typeof(ValidationException))]
public void TestDbDomain()
{
    //... setup

    bool success = svc.Submit(changeSet);

    bool foundError = (from item in changeSet.ChangeSetEntries
                       where item.HasError
                       from validationError in item.ValidationErrors
                       select validationError).Any();

    Assert.IsTrue(foundError);
}
其次,在Telerik的JustDecompiler的一点帮助下(非常感谢!),只有当类中的某个成员已使用验证指令进行注释时,DomainServices.ValidateChanges才起作用

public class Documentation : IValidatableObject
{
    ...

    [DataType("File")]
    public string FileGuid { get; set; }

    ...
}
DataType(“File”)指令不会触发验证机制中的任何验证,但它对于设置标志非常有用

如果您对详细信息感兴趣,请查看System.DomainServices.Server.ValidationUtilities.ValidateObject Recursive:

private static bool ValidateObjectRecursive(object instance, string memberPath, ValidationContext validationContext, List<ValidationResult> validationResults)
{
    MetaType metaType = MetaType.GetMetaType(instance.GetType());
    if (!metaType.RequiresValidation)
    {
        return true;
    }

    // ... checks for IValidatableObject later
}
private static bool ValidateObjectRecursive(对象实例、字符串成员路径、ValidationContext ValidationContext、列表validationResults)
{
MetaType MetaType=MetaType.GetMetaType(instance.GetType());
if(!metaType.RequiresValidation)
{
返回true;
}
//…稍后检查表对象
}
这显然是一个错误,因为IValidatableObject的存在应该设置了metaType.RequiresValidation标志

public class Documentation : IValidatableObject
{
    ...

    [DataType("File")]
    public string FileGuid { get; set; }

    ...
}
private static bool ValidateObjectRecursive(object instance, string memberPath, ValidationContext validationContext, List<ValidationResult> validationResults)
{
    MetaType metaType = MetaType.GetMetaType(instance.GetType());
    if (!metaType.RequiresValidation)
    {
        return true;
    }

    // ... checks for IValidatableObject later
}