我有一个实现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" }) };
}
}为什么DbContext会运行验证,而DbDomainService不会?
此测试通过了DbContext:
[TestMethod, ExpectedException(typeof(DbEntityValidationException))]
public void TestDbContext()
{
SampleDbContext ctx = new SampleDbContext();
var p = new Project()
{
ProjectName = "UnitTest",
};
var d = new Documentation()
{
FileGuid = "UnitTestDoc",
};
p.Documentations = new List<Documentation>();
p.Documentations.Add(d);
ctx.Projects.Add(p);
ctx.SaveChanges();
}而这不是(没有抛出异常):
[TestMethod, ExpectedException(typeof(ValidationException))]
public void TestDbDomain()
{
SampleDomainService svc = new SampleDomainService();
svc.Initialize(ServiceProvider.CreateDomainServiceContext());
var p = new Project()
{
ProjectName = "UnitTest",
};
var d = new Documentation()
{
FileGuid = "UnitTestDoc",
Project = p,
};
ChangeSet changeSet = new ChangeSet(
new [] {
new ChangeSetEntry(1, p, null, DomainOperation.Insert),
new ChangeSetEntry(2, d, null, DomainOperation.Insert),
}
);
svc.Submit(changeSet);
}示例代码是here
发布于 2013-06-23 22:30:15
如上所示,原始代码有两个问题。
首先,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.ValidateObjectRecursive:周围看看
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
}这显然是一个错误,因为IValidatableObject的存在应该已经设置了metaType.RequiresValidation标志。
https://stackoverflow.com/questions/17211320
复制相似问题