0

У меня есть объект POCO, который реализует IValidatableObject.DbDomainService и IValidatableObject

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

ответ

0

Существовали две проблемы с оригиналом как показано выше.

Во-первых, DomainService не выбрасывает исключение ValidationException для ошибок проверки IValidatableObject. Только проверки 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); 
} 

Во-вторых, с небольшой помощью JustDecompiler Telerik в (! Большое спасибо), получается DomainServices.ValidateChanges только работает, если есть какой-то член в классе, был аннотирован директивами валидации.

public class Documentation : IValidatableObject 
{ 
    ... 

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

    ... 
} 

тип данных («Файл») директива не вызывает каких-либо проверки в механизме проверки, но это полезно для установки флагов.

Если вы заинтересованы в деталях, посмотрите вокруг 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 ,