【问题标题】:asp.net mvc database interaction validationasp.net mvc 数据库交互验证
【发布时间】:2009-05-16 21:29:11
【问题描述】:

是否有人对如何连接需要在更新或添加到数据库之前与数据库交互的验证有任何链接或建议?我看到的每个示例都显示了如何验证属性,例如“是必需的”、“是电子邮件”、“是数字”等,但是如何连接“无法订购缺货商品”的验证? This xVal blog post 涉及但未提供示例。

我一直在关注使用 Repository 的 NerdDinner 教程,但这是我不太明白的一点......假设我们有一个带有 Create 方法的 OrderController,在创建订单之前,我们必须先检查该项目有库存。在 NerdDinner 样式中,Controller 使用 Repository 与数据库通信,那么我们的 Order 对象(模型)如何能够执行此验证以及属性验证,因为它无法与数据库通信数据库?

感谢您的帮助

【问题讨论】:

    标签: asp.net-mvc validation


    【解决方案1】:

    在 NerdDinner 教程中,您可以查看 IsVaild 和 GetRuleViolation 方法。根据您的业务和数据库规则,您可以使用它们在插入数据之前检查您拥有的数据。您甚至可以创建一个 IsValidForInsert 方法来检查您需要强制执行的任何插入特定规则。

    在 NerdDinner 中,GetRuleViolation 允许您检索违反的规则并将它们冒泡到您选择的界面。

        public bool IsValid
        {
            get { return (GetRuleViolations().Count() == 0); }
        }
    
        public IEnumerable<RuleViolation> GetRuleViolations()
        {
    
    
            if (CheckDbForViolation)
                yield return new RuleViolation("Database Violation", "SomeField");
    
            if (String.IsNullOrEmpty(Title))
                yield return new RuleViolation("Title is required", "Title");
    
            if (String.IsNullOrEmpty(Description))
                yield return new RuleViolation("Description is required", "Description");
    
            if (String.IsNullOrEmpty(HostedBy))
                yield return new RuleViolation("HostedBy is required", "HostedBy");
    
     ... etc ...
    
    
            yield break;
        }
    
        public bool CheckDbForViolation()
    
        {
    
        /// Do your database work here...
    
        }
    

    您可以更进一步,将数据库代码拆分到存储库中。 CheckDbForViolation 将调用 repo 以获取信息,然后确定是否存在违规行为。事实上,如果您使用的是存储库,我认为这将是最好的方式。

    【讨论】:

    • 我已经阅读了有关 IsValid 和 GetRuleViolations 的信息,但没有提到“无法订购缺货商品”的场景。这种类型的业务规则应该放在哪里?谢谢
    • 您的验证步骤之一是走出去查询数据库以查看该项目是否有库存。然后要么继续,要么失败,要么阻止数据库写入发生。
    • 我了解验证步骤是什么,但逻辑会在哪里?控制器使用存储库,因此要查询数据库,此逻辑需要在控制器中,但是,我的理解是业务规则应该保留在模型中?我开始认为控制器不应该使用存储库?!谢谢
    • 对不起,我不是更清楚...如果您进入 Models/dinner.cs 文件,您将添加验证代码,作为 GetRuleViolations 方法中的方法调用.我将其设为方法调用只是为了保持 GetRuleViolations 方法美观、干净且易于解释。这是否更清楚?
    【解决方案2】:

    您实际上并不需要示例中的任何指导来说明如何执行此操作。最终,您必须能够自己创建此类应用程序,这意味着要有创造力。

    我从一开始就决定不要使用内置验证或会员 API,以免在某些时候遇到其限制。

    对于您的情况:这非常标准。

    想象一下执行流程如下:

    1. 发布表单
    2. 在不与数据库对话的情况下验证输入数据格式
    3. 如果 (2) 通过,则从业务规则/数据完整性的角度验证输入。在这里你与数据库对话
    4. 如果 (3) 通过,则执行您的操作。如果它以某种方式失败(可能是数据库中的数据完整性规则禁止该操作,例如,您从另一个浏览器窗口中删除了相关对象)然后取消它并通知用户操作错误。

    尽量保持控制器方法为空。验证和操作逻辑应该驻留在您的模型和业务逻辑中。控制器应该基本上尝试一个预期的操作,并根据返回的状态返回一个视图或另一个视图。也许还有更多选项,但不是检查用户角色、访问权限、调用某些 Web 服务等的全部负载。保持简单。

    附:有时我的印象是,旨在为大多数开发人员简化简单事情的内置功能往往会在已删除的功能上创造新的障碍。

    【讨论】:

    • 您列出的执行流程正是我会做的,我只是不确定在 NerdDinner 示例中的条款,验证将放置在哪里。如果 Order 对象使用 Repository,然后 Controller 只与 Order 对象对话,那对我来说会更有意义。这样,处理这两种验证形式的 Order 对象现在可以与数据库通信,您认为这是一个更好的选择吗?谢谢
    • 我对 NerdDinner 示例不太熟悉。如果“Repository”代表某种数据库层,而有一个中间业务逻辑层(例如,您的 Order 可以被视为业务对象),那么控制器出于任何目的直接使用 Repository 显然是错误的。通信应该是:[控制器] BLL DAL。有时你只是使用模型而不是 BLL,但这并不完全正确。模型只是为了打包数据以供视图显示。
    【解决方案3】:

    我会创建一个带有方法 PlaceOrder(Order order) 的 OrderService。 OrderService 使用 Repository 执行 CRUD 操作并执行业务规则(库存检查),并最终在违反规则时抛出异常,您可以捕获并报告给用户。

    【讨论】:

    • 我希望将其保留在 NerdDinner 的上下文中,并且目前不使用服务。想让事情尽可能简单,让我了解它是如何连接起来的。谢谢
    猜你喜欢
    • 2017-03-22
    • 2012-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-21
    • 1970-01-01
    • 1970-01-01
    • 2016-05-25
    相关资源
    最近更新 更多