如何进行跨实体服务器端验证

时间:2013-12-19 23:27:20

标签: validation breeze

在我的应用程序中,我有跨实体验证逻辑,要求我查看整个更改集,并且我使用BeforeSaveEntities覆盖执行此操作。

我可以通过检查saveMap参数来构造正确的逻辑,但如果我发现某些内容无效,我应该怎么做?

如果我抛出一个异常,就像我在BeforeSaveEntity覆盖中进行单个实体验证一样,整个保存将中止,并将错误报告给客户端。但是有些实体可能是有效的,所以我想保存这些实体并且只中止无效的部分。

由于BeforeSaveEntities返回saveMap,我认为我应该能够从更改集中删除无效实体并继续保存有效实体,但是如何将无效部分报告给客户?

是否可以仅对有效实体进行部分保存,同时向客户报告合理的错误,以描述失败的保存部分?

2 个答案:

答案 0 :(得分:1)

杰告诉你的方式。

我不会屏住呼吸等待Breeze的改变,因为我认为你的情况很少见,而且我们不想鼓励它。

但我很奇怪,如果你和我完全不愿意这样做,我就不能再想我会做什么了。我可能会尝试这样的事情。

警告:这是伪代码,我正在解决这个问题。我不建议或保证

  1. 创建源自MyCustomEFContextProvider的自定义EFContextProvider

  2. 为其提供ErrorEntities属性以容纳错误对象

  3. 覆盖(影子)SaveChanges方法与委托给基础的另一个方法

    public new CustomSaveResult SaveChanges(JObject saveBundle, 
                                     TransactionSettings transactionSettings = null) {
       var result = base.SaveChanges(saveBundle, transactionSettings);
       // learn about CustomSaveResult below
       return new CustomSaveResult(this.ErrorEntities, result);
    }
    
  4. BeforeSaveEntities

  5. 中抓取无效实体
  6. 将错误消息传递给您的自定义ErrorEntities媒体资源

    您可以通过EntityInfo实例访问该属性,如在
    ((MyCustomEFContextProvider) info.ContextProvider).ErrorEntities.Add(new ErrorEntity(info, message));

  7. SaveMap中移除无效实体,使其不会包含在实际保存中

  8. 让保存继续

  9. 覆盖SaveChanges方法的第二行从标准版本创建CustomSaveResult的新实例,并将其返回给调用者。

    public class CustomSaveResult : SaveResult {
    
       public List ErrorEntities;
       public CustomSaveResult(List errorEntities, SaveResult result){
           // copy over everything
           this.Entities = result.Entities;
           this.KeyMappings = result.KeyMappings;
           this.Errors = this.Errors;
           // and now your error stuff
           this.ErrorEntities = errorEntities;
      }
    }
    
  10. 假设调用者是您的Web API控制器的SaveChanges方法。好吧,你不需要改变一件事,但你可以通过显式返回你的自定义SaveResult来明确:

        readonly MyCustomEFContextProvider _contextProvider = new MyCustomEFContextProvider();
        ...
        [HttpPost]
        public CustomSaveResult SaveChanges(JObject saveBundle) {
            return _contextProvider.SaveChanges(saveBundle);
        }
    

    JSON.Net将很乐意序列化常用材料+您的自定义ErrorEntities属性(确保使其可序列化!)并将其发送给Breeze客户端。

    在Breeze客户端上,您可以在stock Breeze Web API data service adapter上编写自己的变体。你和Breeze版本完全一样。但是,当从服务器处理保存有效负载时,它还会在响应中提取这些额外的“错误实体”材料,并做任何你想做的事情。

    我不知道那会是什么,但现在你拥有它。

    看看这有多容易? LOL。

答案 1 :(得分:0)

Breeze目前不支持同时保存和返回错误的保存机制。虽然可能这似乎有点巴洛克式。

正如您所指出,您可以

1)在BeforeSaveEntities内部抛出异常并使保存失败。您甚至可以指定导致失败的特定实体或原因。在这种情况下,整个保存将中止。

2)从BeforeSaveEntities中的saveMap中删除“bad”项,并仅保存传入的子集。在这种情况下,您正在执行部分保存。

但我们不支持这两者的混合。如果你感觉强烈,请将其添加到Breeze用户语音中,我们可以看到社区的其他成员是否认为这有用。