我无法弄清楚如何将服务器端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:
以下是重新创建我遇到的问题的一些说明。
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;
}
}
Description
字段:
[CustomValidator]
public string Description { get; set; }
using
s(System
和System.ComponentModel.DataAnnotations
)。这是我希望通过Breeze看到错误,甚至从实体框架中抛出DbEntityValidationException
的地方。我尝试了两台具有相同结果的独立计算机。实体保存到数据库,就好像没有错误一样。事实上,如果你在自定义验证器的IsValid
方法中的任何地方放置一个断点,你会发现它甚至没有被调用。
从Breeze v 0.78.1开始,所有已注册的DbContext服务器端验证现在将在EntityManager SaveChanges调用期间执行。遇到的任何异常都会导致save回滚,并且任何验证错误都会被序列化回Breeze客户端。
请注意,基于EF模型的旧ObjectContext(与DbContext相对)尚不支持此功能。
并且...感谢adamlj发现此问题并提出解决方案。
我不确定你的意思
将服务器端DbContext验证错误返回给客户端
您可能意味着要将验证错误消息发送到客户端。但是你的问题的其余部分表明你想知道(a)如何在服务器上运行自定义验证,以及(b)如何在客户端上获取和运行该验证的相应JavaScript版本。我会解释你对这个问题的解释。
服务器
实体框架(您在示例中使用)会自动为您运行数据注释验证规则...除非您手动禁用该功能。如果以正确的方式创建自定义验证规则,EF也会运行这些规则。 This post by Daniel Wertheim描述了如何编写这样的规则。我不能在每个细节上担保该帖子,但对我来说似乎是正确的。它甚至定义了一个自定义的Email-validationattribute!
如果创作自定义数据注释验证规则对您来说太过巴洛克式(就像我经常对我做的那样),您可以在“BeforeSave...
”中讨论的Server-side Interception方法之一中编写和调用自己的验证逻辑。
我认为这些是您最好的服务器选项。对客户......
客户
Breeze注册客户端JavaScript验证,以匹配元数据中遇到的某些服务器端数据注释(例如,Required
和MaxLength
)。在我写的时候,自定义数据注释不会被识别,也不会包含在元数据中,并且它们在客户端上没有开箱即用的模拟。如果您希望客户端使用这些规则对您的实体进行预筛选,则必须编写自己的相应JavaScript验证程序,并将其注册为相关的实体类型,如Validation文档页面中所述。
如果您有任何建议或更好的选择,我们很乐意听取他们的意见。