Breeze.js未从服务器返回自定义验证错误消息

Breeze.js未从服务器返回自定义验证错误消息,breeze,Breeze,我很难理解为什么Breeze.js(0.84.3)不向客户端返回错误消息,这些错误消息是由应用于类级别服务器模型的自定义验证属性设置的。我可以用Breeze TODO KO样本重现这一点,如下所示: using System; using System.ComponentModel.DataAnnotations; namespace Todo.Models { [MyCustomValidator] // NEW public class TodoItem {

我很难理解为什么Breeze.js(0.84.3)不向客户端返回错误消息,这些错误消息是由应用于类级别服务器模型的自定义验证属性设置的。我可以用Breeze TODO KO样本重现这一点,如下所示:

using System;
using System.ComponentModel.DataAnnotations;
namespace Todo.Models
{
    [MyCustomValidator] // NEW
    public class TodoItem
    {
        public int Id { get; set; }
        [Required, StringLength(maximumLength: 30)]     
        public string Description { get; set; } // Set to 'error' to trigger server error.        
        public System.DateTime CreatedAt { get; set; }  
        public bool IsDone { get; set; }                
        public bool IsArchived { get; set; }            
    }

    [AttributeUsage(AttributeTargets.Class)] // NEW
    public class MyCustomValidator : ValidationAttribute
    {
        public override Boolean IsValid(Object value)
        {           
            var todo = value as TodoItem;
            if (todo.Description == "error")
            {
                ErrorMessage = "The TodoItem is not valid!";
                return false;
            }
            return true;
        }
    }
 }
我希望将错误消息“TodoItem无效!”返回到客户端,但是Breeze似乎总是从服务器返回“Value不能为null。Parameter name:source”。似乎有一个例外发生在:

StackTrace:   
at System.Linq.Enumerable.Select[TSource,TResult](IEnumerable`1 source, Func`2 selector) at Breeze.WebApi.EFContextProvider`1.SaveChangesCore(Dictionary`2 saveMap)
at Breeze.WebApi.ContextProvider.SaveChanges(JObject saveBundle)
at Todo.Controllers.TodosController.SaveChanges(JObject saveBundle) in c:\Users\RichardH\Downloads\Software\Web\breeze-runtime-plus-0.84.3\Samples\Todo\Todo\Controllers\TodosController.cs:line 41
at lambda_method(Closure , Object , Object[] )
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass13.<GetExecutor>b__c(Object instance, Object[] methodParameters)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.<>c__DisplayClass5.<ExecuteAsync>b__4()
at System.Threading.Tasks.TaskHelpers.RunSynchronously[TResult](Func`1 func, CancellationToken cancellationToken)
StackTrace:
在System.Linq.Enumerable中,在Breeze.WebApi.EFContextProvider`1.SaveChangesCore(字典`2 saveMap)中选择[TSource,TResult](IEnumerable`1 source,Func`2选择器)
在Breeze.WebApi.ContextProvider.SaveChanges(JObject saveBundle)上
在c:\Users\RichardH\Downloads\Software\Web\breeze-runtime-plus-0.84.3\Samples\Todo\Todo\Controllers\todoscontler.cs中的Todo.Controllers.SaveChanges(JObject saveBundle)中:第41行
在lambda_方法(闭包、对象、对象[])
在System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.c__DisplayClass13.b__c(对象实例,对象[]方法参数)
位于System.Web.Http.Controller.ReflectedHttpActionDescriptor.ActionExecutor.Execute(对象实例,对象[]参数)
在System.Web.Http.Controllers.ReflectedHttpActionDescriptor.c_uuDisplayClass5.b_uuu4()中
在System.Threading.Tasks.TaskHelpers.RunSynchronously[TResult](Func`1 Func,CancellationToken CancellationToken)
有人能告诉我如何将服务器上的验证应用于整个模型(而不仅仅是单个属性/字段)吗

谢谢,
Richard

首先,Breeze.NET服务器端元数据不会将自定义服务器验证属性传递给Breeze客户端。它只传送某些标准的数据,如Required、MaxLength和StringLength。如果要在客户端上复制验证,必须在客户端上用JavaScript编写验证程序,并使用客户端元数据注册它们,如

其次,我猜失败发生在EF中,因为它试图使用您的自定义验证规则。在SaveChangesCore中引发异常,在这里EFContextProvider要求EF保存更改

根据堆栈跟踪,它可能是由
Select
语句引起的LINQ异常,Breeze试图在该语句中告诉您验证错误。我指的是这里的
选择

var formattedKey = key.EntitySetName + ";" + key.EntityKeyValues.Select(v => v.ToString()).ToAggregateString(" ,"); var formattedKey=key.EntitySetName+“;”+ 选择(v=>v.ToString()).ToAggregateString(“,”); “值不能为null…”消息表明
key.EntityKeyValues
为null。我无法解释没有关键值的实体是如何来到这里的。我想你可以设置一个断点并找出答案


就我们而言,我们需要减少这条线的脆弱性。我将把它放在我们要解决的问题列表中。

首先,Breeze.NET服务器端元数据不会将自定义服务器验证属性传递给Breeze客户端。它只传送某些标准的数据,如Required、MaxLength和StringLength。如果要在客户端上复制验证,必须在客户端上用JavaScript编写验证程序,并使用客户端元数据注册它们,如

其次,我猜失败发生在EF中,因为它试图使用您的自定义验证规则。在SaveChangesCore中引发异常,在这里EFContextProvider要求EF保存更改

根据堆栈跟踪,它可能是由
Select
语句引起的LINQ异常,Breeze试图在该语句中告诉您验证错误。我指的是这里的
选择

var formattedKey = key.EntitySetName + ";" + key.EntityKeyValues.Select(v => v.ToString()).ToAggregateString(" ,"); var formattedKey=key.EntitySetName+“;”+ 选择(v=>v.ToString()).ToAggregateString(“,”); “值不能为null…”消息表明
key.EntityKeyValues
为null。我无法解释没有关键值的实体是如何来到这里的。我想你可以设置一个断点并找出答案


就我们而言,我们需要减少这条线的脆弱性。我将把它放在我们要修复的事情列表中。

好的,这是一个bug,现在从breeze v1.0.0开始修复

好的,这是一个bug,现在从breeze v1.0.0开始修复

你好,沃德,谢谢你的快速回复。事实证明,正在抛出DbEntityValidationException。在这一行的EFContextProvider中调用SaveChanges方法:
count=((DbContext)(object)Context)。SaveChanges()。发生这种情况的原因是应用于类的自定义验证属性。我不是EF专家,但我怀疑
键。EntityKeyValues
为空b/c实体是新的/无效的。如果修改代码集
formattedKey
以处理此情况,至少可以将正确的验证错误返回给客户端。哦,还有一件事。。。在这种情况下,由于自定义验证属性应用于类而不是属性,因此从EFContextProvider返回的
ValidationException
消息的格式可能会有所改进,以假设如果属性为null,则验证错误应应用于整个实体。您好,谢谢你的快速回复。事实证明,正在抛出DbEntityValidationException。在这一行的EFContextProvider中调用SaveChanges方法:
count=((DbContext)(object)Context)。SaveChanges()。发生这种情况的原因是应用于类的自定义验证属性。我不是EF专家,但我怀疑
键。EntityKeyValues
为空b/c实体是新的/无效的。如果修改代码集
formattedKey
以处理此情况,至少可以将正确的验证错误返回给客户端。哦,还有一件事。。。在这种情况下,由于自定义V