这是场景:
所以基本上,所有很酷的东西。 :)
基本 UI 操作的事件流(“添加帖子”):
现在,我正在努力找出可以将验证放在哪里。
在这个阶段,我需要两种类型的验证:
现在,我一直在阅读 Julie Lerman 撰写的“Programming Entity Framework, Second Edition”(顺便说一句,很棒),并且一直在研究 Hook SavingChanges 事件以执行“最后一刻”验证。这将是确保验证 总是 的好方法,每当我做“某事”(添加、修改、删除)时都会发生,但这也有点晚了 IMO(因为这些项目已经在状态管理器中) - 那我能怎么办如果验证失败,删除它们?
我当然可以让我的 POCO 实现一个接口(interface)(比如“IValidatable”),并在这个事件期间调用这个接口(interface)上的一个方法。
但这对于业务验证来说似乎“为时已晚”——这是共识吗?
我基本上是在这里寻找指导,鉴于我的上述架构,我正在尝试为复杂的业务逻辑设计一个可重用的智能验证方案。
另一个曲线球 - 如您所知,带有 EF 的 POCO 意味着 POCO 具有数据库上的所有属性 - 所以我可能有一个“PostID”属性,带有获取/设置访问器(因为 EF 需要获取/设置这些属性)。
但问题是,“PostID”是一个 标识 列,那么我如何保护该字段不被显式设置?例如,如果我(出于某种原因)执行以下操作:
var post = service.FindSingle(10);
post.PostId = 10;
unitOfWork.Commit();
这将抛出一个 SqlException。我怎样才能防止这种情况?我无法“隐藏”该属性(使其成为私有(private)的,甚至是内部的),因为 POCO 位于存储库的单独程序集中。
关于验证的说明 - 我计划创建自定义异常(从异常派生)。所以当验证失败时,我需要抛出这些异常。
这样,我可以在我的 Controller 上编写这样的代码:
[HttpPost]
public ActionResult AddPost(Post post)
{
try
{
IUnitOfWork uow = new UnitOfWork();
postService.Add(post);
uow.Commit();
}
catch(InvalidPostOperation ipo)
{
// add error to viewmodel
}
}
每次执行 Add 时,我都必须手动对服务层进行验证吗?那我该如何处理保存呢? (因为这是在工作单元上,而不是在服务层上)。
因此,为了防止这是一个“无处不在”的问题,以下是我的问题:
任何想法将不胜感激。
如果这篇文章“太长”,请道歉,但这是一个重要的问题,可以通过多种方式解决,所以我想提供所有信息,以便获得最佳答案。
谢谢。
编辑
以下答案很有帮助,但我仍在(理想情况下)寻找更多想法。还有谁?
最佳答案
DataAnnotations
并不适合所有情况。根据我的经验,缺点主要是复杂的验证(多个属性和多个属性不同的对象)。 DataAnnotations
接口(interface)兼容,因此是“MVC 友好的”。 关于asp.net-mvc - 使用 ASP.NET MVC/Entity Framework 进行 POCO 验证的建议,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3878112/