5

我无法弄清楚如何将服务器端DbContext验证错误返回给客户端。我知道 Breeze 有默认验证器,可以对一些属性做出反应,例如Required,但是所有其他属性呢?我可以为 Breeze 编写一个自定义 JavaScript 验证器,它将在客户端进行检查,但我还需要检查以确保实体在服务器端有效。

例如,应用程序需要Person一个有效的电子邮件地址。恶意用户出现并通过客户端获取电子邮件地址,并将无法通过EmailAddress验证器的数据发布到服务器。到目前为止,我对 Breeze 的体验是电子邮件地址将保存并且不会出现任何DbContext实体框架错误。

假设下面的模型,获得任何实体验证错误的最佳方法是什么?

public class PeopleContext : DbContext
{
    public PeopleContext()
        : base("name=ConnectionString"){ }

    public DbSet<Person> People { get; set; }
}

public class Person
{
    public int PersonId { get; set; }
    public string FirstName { get; set; }
    [Required]
    public string LastName { get; set; }
    [EmailAddress]
    [Required]
    public string Email { get; set; }
}

更新 1:

以下是重新创建我遇到的问题的一些说明。

  1. 按照说明创建“Todo”示例 ( http://www.breezejs.com/documentation/start-nuget )
  2. 在文件中添加一个新的自定义验证器BreezeSampleTodoItem.cs

    [AttributeUsage(AttributeTargets.Property)]
    public class CustomValidator : ValidationAttribute
    {
        public override Boolean IsValid(Object value)
        {
            string val = (string)value;
            if (!string.IsNullOrEmpty(val) && val == "Error")
            {
                ErrorMessage = "{0} equal the word 'Error'";
                return false;
            }
            return true;
        }
    }
    
  3. 使用新的自定义验证器装饰该Description字段:

    [CustomValidator]
    public string Description { get; set; }
    
  4. 当然添加正确using的 s (SystemSystem.ComponentModel.DataAnnotations)。

  5. 运行项目。
  6. 在描述字段之一中键入“错误”并保存。

这是我希望看到 Breeze 出现错误的地方,甚至DbEntityValidationException是 Entity Framework 抛出的错误。我已经在 2 台不同的计算机上尝试过,结果相同。实体保存到数据库中,就好像没有错误一样。事实上,如果你IsValid在自定义验证器的方法内的任何地方放置一个断点,你会看到它甚至没有被调用。

4

2 回答 2

3

从 Breeze v 0.78.1 开始,所有已注册的 DbContext 服务器端验证现在都将在 EntityManager SaveChanges 调用期间执行。遇到的任何异常都会导致保存回滚,并且任何验证错误都会被序列化回 Breeze 客户端。

请注意,旧的基于 ObjectContext(相对于 DbContext)的 EF 模型尚不支持此功能。

并且...感谢 adamlj 发现此问题并提出解决方案。

于 2012-12-16T08:42:33.207 回答
1

我不确定你的意思

将服务器端 DbContext 验证错误返回给客户端

您可能意味着您希望将验证错误消息发送到客户端。但是您的问题的其余部分表明您想知道(a)如何在服务器上运行自定义验证,以及(b)如何在客户端获取和运行该验证的相应 JavaScript 版本。我将解决您的问题的这种解释。

服务器

实体框架(您在示例中使用)会自动为您运行数据注释验证规则......除非您手动禁用了该功能。如果您以正确的方式创建自定义验证规则,EF 也会运行这些规则。Daniel Wertheim 的这篇文章描述了如何编写这样的规则。我不能保证那个帖子的每一个细节,但对我来说似乎是正确的。它甚至定义了一个自定义的电子邮件验证属性!

如果编写自定义数据注释验证规则对您来说太巴洛克(就像它对我经常做的那样),您可以使用“服务器端拦截BeforeSave...”中讨论的方法之一编写和调用自己的验证逻辑。

我认为这些是您最好的服务器选择。到客户端...

客户

Breeze 注册客户端 JavaScript 验证以匹配元数据中的某些服务器端数据注释(例如,RequiredMaxLength)。正如我所写的那样,自定义数据注释既不被识别也不包含在元数据中,并且它们在客户端上没有开箱即用的类似物。如果您希望客户端使用这些规则预先筛选您的实体,您必须编写自己的相应 JavaScript 验证器并将它们注册为相关的实体类型,如验证文档页面中所述。

如果您有建议或更好的选择,我们很乐意听到。

于 2012-12-13T07:35:38.137 回答