服务器端验证

时间:2012-12-13 00:09:57

标签: validation dbcontext breeze

我无法弄清楚如何将服务器端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当然(SystemSystem.ComponentModel.DataAnnotations)。

  5. 运行项目。
  6. 在其中一个说明字段中输入“错误”并保存。
  7. 我希望通过Breeze看到错误,甚至从实体框架中抛出DbEntityValidationException。我尝试了两台具有相同结果的独立计算机。实体保存到数据库,就好像没有错误一样。实际上,如果在自定义验证器的IsValid方法中的任何位置放置断点,您将看到它甚至没有被调用。

2 个答案:

答案 0 :(得分:3)

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

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

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

答案 1 :(得分:1)

我不确定你的意思

  

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

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

服务器

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

如果创作自定义数据注释验证规则对您来说太过巴洛克式(就像我经常做的那样),您可以在“{{3”中讨论的BeforeSave...方法之一中编写和调用自己的验证逻辑。 }}”。

我认为这些是您最好的服务器选项。对客户......

客户端

Breeze注册客户端JavaScript验证,以匹配元数据中遇到的某些服务器端数据注释(例如,RequiredMaxLength) 。在我写的时候, 自定义 数据注释无法识别,也不会包含在元数据中,并且它们没有开箱即用的类似物客户。如果您希望客户端使用这些规则对您的实体进行预筛选,则必须编写自己的相应JavaScript验证程序,并为相关实体类型注册它们,如Server-side Interception文档页面中所述。

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