简体   繁体   English

asp.net mvc数据库交互验证

[英]asp.net mvc database interaction validation

Does anybody have any links or advice on how to hook up validation that requires interacting with the database before updating or adding to the database? 在更新或添加到数据库之前,是否有任何关于如何连接需要与数据库交互的验证的链接或建议? Every example I see shows how to validate properties eg "Is Required", "Is Email", "Is Numeric", etc, but how do you hook up validation for "Can't order out of stock item"? 我看到的每个例子都显示了如何验证属性,例如“Is Required”,“Is Email”,“Is Numeric”等,但是如何连接“Can not order out of stock item”的验证? This xVal blog post touches on it but doesn't provide an example. 这篇xVal博客文章涉及到它,但没有提供一个例子。

I've been following the NerdDinner tutorial which uses a Repository, but this is the bit I don't quite get... Say we had an OrderController with a Create method, and before creating an order we had to first check that the item is in stock. 我一直在关注使用存储库的NerdDinner教程,但这是我不太明白的...说我们有一个带有Create方法的OrderController,在创建订单之前我们必须首先检查该项目有货。 In the NerdDinner style the Controller uses the Repository to talk to the database, so how would our Order object (Model) be able to enforce this validation along with the property validation, as it can't talk to the database? 在NerdDinner样式中, Controller使用Repository与数据库进行通信,那么我们的Order对象(Model)如何能够与属性验证一起强制执行此验证,因为它无法与数据库通信?

Thanks for any help 谢谢你的帮助

In the NerdDinner tutorial, you can checkout the IsVaild and then the GetRuleViolation methods. 在NerdDinner教程中,您可以签出IsVaild,然后签出GetRuleViolation方法。 Based on your business and database rules, you could use these to check the data you have before you insert it. 根据您的业务和数据库规则,您可以使用这些规则检查插入之前的数据。 You could even create an IsValidForInsert Method to check any insert specific rules you need to enforce. 您甚至可以创建一个IsValidForInsert方法来检查您需要强制执行的任何插入特定规则。

In NerdDinner, the GetRuleViolation allows you to retrieve the violated rules and bubble them up to the interface as you choose. 在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...

    }

You could take this further and split database code into the repository. 您可以进一步将数据库代码拆分到存储库中。 The CheckDbForViolation would call the repo for the info and then determine if there was a violation or not. CheckDbForViolation将调用repo获取信息,然后确定是否存在违规。 In fact if you are using a repository, I think that would be the preferable way of doing it. 事实上,如果您正在使用存储库,我认为这将是更好的方式。

You do not really need any guidance from examples on how to do this. 您实际上并不需要有关如何执行此操作的示例的任何指导。 Ultimately you will have to be able to create such applications on your own which means being creative. 最终,您必须能够自己创建此类应用程序,这意味着具有创造性。

I've decided from the beginning do not use either built-in validation or membership API in order not to run into its limitations at some point of time. 我从一开始就决定不使用内置验证或成员资格API,以免在某些时候遇到其局限性。

For your situation: it's pretty much standard. 对于你的情况:它几乎是标准的。

Imagine the execution flow as follows: 想象一下执行流程如下:

  1. Post form 发表表格
  2. Validate input data format without talking to the database 无需与数据库通信即可验证输入数据格式
  3. If (2) is pass, then you validate the input from the point of business rules/data integrity. 如果(2)通过,则从业务规则/数据完整性验证输入。 Here you talk to the database 在这里您可以与数据库交谈
  4. If (3) passed then perform your operation whatever it is. 如果(3)通过,则执行您的操作,无论它是什么。 If it somehow fails (maybe data integrity rules in the database prohibit the operation, say, you deleted a related object from the other browser window) then cancel it and notify the user of an operation error. 如果它以某种方式失败(可能数据库中的数据完整性规则禁止操作,例如,您从其他浏览器窗口删除了相关对象),则取消它并通知用户操作错误。

Try to keep controller methods as empty as possible. 尽量保持控制器方法尽可能为空。 The validation and operation logic should reside in your models and business logic. 验证和操作逻辑应该驻留在您的模型和业务逻辑中。 The controller should basically attempt the one intended operation and based on the status returned just return one view or the other. 控制器基本上应该尝试一个预期的操作,并根据返回的状态返回一个视图或另一个视图。 Maybe a few more options, but not the whole load of checks for user roles, access rights, calling some web services etc. Keep it simple. 可能还有一些选项,但不是用户角色,访问权限,调用某些Web服务等的全部检查。保持简单。

PS I sometimes get the impression that the built-in features intended to simplify simple things for majority of developers tend to create new barriers over the removed ones. PS我有时会得到这样的印象:内置功能旨在简化大多数开发人员的简单操作,往往会为删除的功能创造新的障碍。

I would create an OrderService with a method PlaceOrder(Order order). 我将使用方法PlaceOrder(订单顺序)创建OrderService。 The OrderService use the Repository to perform CRUD ops and to enforce business rules (stock check) and eventually thrown exception on rules violation you can catch and report to the user. OrderService使用存储库来执行CRUD操作并强制执行业务规则(库存检查),并最终抛出违反规则的异常,您可以捕获并向用户报告。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM