gpt4 book ai didi

c# - 分层应用程序中的验证

转载 作者:太空狗 更新时间:2023-10-29 20:37:17 25 4
gpt4 key购买 nike

我想知道在 ASP.NET MVC 应用程序中验证数据库约束(例如 UNIQUE)的最佳方法是什么,构建时考虑到 DDD,其中底层是应用程序层(应用程序服务)、领域层(域模型)和基础设施层(持久性逻辑、日志记录等)。

我一直在查看大量的 DDD 示例,但其中很多都没有提到如何在存储库中进行验证(我想这正是这种类型的验证适合的地方)。如果您知道任何这样做的示例,请分享它们,我们将不胜感激。

更具体地说,我有两个问题。 你将如何执行实际验证?你会通过查询数据库明确检查客户名称是否已经存在,或者你会尝试将其直接插入数据库并捕获错误(如果有的话)(看起来很乱) ?我更喜欢第一个,如果选择这个,它应该在存储库中完成,还是应该由应用程序服务完成?

当检测到错误时,如何将它传递给 ASP.NET MVC,以便用户可以很好地了解错误?最好使用 ModelStateDictionary,这样错误很容易在表单上突出显示。

在Microsoft Spain的N-Lyered app中,他们使用了IValidatableObject接口(interface),最简单的属性验证放在了实体本身,例如:

public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var validationResults = new List<ValidationResult>();

if (String.IsNullOrWhiteSpace(this.FirstName))
validationResults.Add(new ValidationResult(Messages.validation_CustomerFirstNameCannotBeNull, new string[] { "FirstName" }));

return validationResults;
}

实体被持久化前,调用Validate消息确保属性有效:

void SaveCustomer(Customer customer)
{
var validator = EntityValidatorFactory.CreateValidator();

if (validator.IsValid(customer)) //if customer is valid
{
_customerRepository.Add(customer);
_customerRepository.UnitOfWork.Commit();
}
else
throw new ApplicationValidationErrorsException(validator.GetInvalidMessages<Customer>(customer));
}

然后可以在 MVC 应用程序中捕获 ApplicationValidationErrorsException,并且可以解析验证错误消息并将其插入到 ModelStateDictionary 中。

我可以将所有验证逻辑添加到 SaveCustomer 方法中,例如使用给定列(UNIQUE 列)查询数据库检查客户是否已经存在。也许这没关系,但我宁愿 validator.IsValid (或类似的东西)会为我做这件事,或者在基础设施层再次执行验证(如果它属于这里,我不确定)。

你怎么看?你怎么做呢?我对深入了解分层应用程序中的不同验证技术非常感兴趣。


可能的解决方案 #1

如果无法在表示层完成验证逻辑(如 Iulian Margarintescu 所建议的那样)而需要在服务层完成,您将如何将验证错误传递到表示层?

微软有一个建议here (参见 list 5)。您如何看待这种方法?

最佳答案

您提到 DDD,但 DDD 远不止实体和存储库。我假设您熟悉 Eric Evans 先生的书领域驱动设计,我强烈建议您重新阅读有关战略设计和限界上下文的章节。埃文斯先生也有一个非常好的演讲,叫做“自本书以来我对 DDD 的了解”,您可以找到 here . Greg Young 或 Udi Dahan 关于 SOA、CQRS 和事件溯源的讨论也包含大量关于 DDD 和应用 DDD 的信息。我必须警告您,您可能会发现一些事情会改变您对应用 DDD 的看法。

现在关于验证的问题 - 一种方法可能是在用户在“名称”字段中键入内容时立即查询数据库(使用定向到应用程序服务的 Ajax 调用)并尝试建议替代方案如果他输入的名字已经存在。当用户提交表单时,尝试将记录插入数据库并处理任何重复键异常(在存储库或应用程序服务级别)。由于您已经提前检查重复项,因此出现异常的情况应该很少见,因此任何像样的“对不起,请重试”消息都应该这样做,除非您有很多用户,否则他们可能永远不会看到它.

This post来自 Udi Dahan 的也有一些关于接近验证的信息。请记住,这可能是您对企业施加的约束,而不是企业对您施加的约束——也许它为企业提供了更多值(value),允许同名客户注册,而不是拒绝他们。

另请记住,DDD 更多地是关于业务而非技术。您可以执行 DDD 并将您的应用程序部署为单个程序集。服务之上、存储库之上、数据库之上的实体之上的客户端代码层以“好”设计的名义被滥用了很多次,没有任何理由证明它是一个好的设计。

我不确定这是否会回答您的问题,但我希望它能引导您自己找到答案。

关于c# - 分层应用程序中的验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10404081/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com