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

时间:2013-01-15 07:19:22

标签: breeze

我无法弄清楚为什么 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。参数名称: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)

任何人都可以了解如何将服务器上的验证应用到整个模型(而不仅仅是单个属性/字段)?

谢谢, 理查德

2 个答案:

答案 0 :(得分:3)

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

中所述。

其次,我猜在EF尝试使用您的自定义验证规则时,失败发生在EF中。在SaveChangesCore中抛出异常,这是EFContextProvider要求EF保存更改的地方。

根据堆栈跟踪,它可能是由Select语句引起的LINQ异常,其中Breeze试图告诉您有关验证错误的信息。我的意思是Select在这里

 var formattedKey = key.EntitySetName + ";" +
                    key.EntityKeyValues.Select(v => v.ToString()).ToAggregateString(" ,");

“值不能为空...”消息表明key.EntityKeyValues为空。我无法解释你的实体如何在没有关键值的情况下到达这里。我想你可以设置一个断点并找出答案。

就我们而言,我们需要使这条线不那么脆弱。我会把它放在我们要修复的事项清单上。

答案 1 :(得分:1)

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