1

我无法弄清楚为什么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 似乎总是从服务器返回“值不能为空。参数名称:源”。似乎有一个例外发生在:

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)

谁能阐明我如何将服务器上的验证应用于整个模型(而不仅仅是单个属性/字段)?

谢谢,理查德

4

2 回答 2

3

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

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

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

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

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

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

于 2013-01-15T08:05:27.320 回答
1

好的,这是一个错误,现在已从微风 v1.0.0 修复。

于 2013-01-29T02:41:30.267 回答