3

我正在尝试使用微风.js 保存一些实体。Breeze 工作正常,它会根据需要保存所有更改。但是,我无法验证和确保授权是服务器端。根据我目前收集到的信息,我想唯一的方法是检查传递到保存包中的 JObject 并在服务器端构造相应的对象。我必须这样做(而不是依赖 Breeze.SaveChanges,因为我在服务器端有一些逻辑)。我该怎么做呢?以及如何构建 Breeze.WebApi。保存结果?也非常欢迎任何其他解决此问题的方法的想法</p>

4

3 回答 3

2

这应该通过实现自定义来完成EFContextProvider

下面的代码实现了EFContextProviderNorthwind 数据库的自定义,直接取自Bread.com 网站上的文档

    公共类 NorthwindContextProvider: EFContextProvider<NorthwindIBContext> {
    公共 NorthwindContextProvider() : base() { }

    protected override bool BeforeSaveEntity(EntityInfo entityInfo) {
      // 如果我们不想保存实体,则返回 false。
      // 禁止添加任何类型为“角色”的实体
      if (entityInfo.Entity.GetType() == typeof(Role)
        && entityInfo.EntityState == EntityState.Added) {
        返回假;
      } 别的 {
        返回真;
      }
   }

    受保护的覆盖 Dictionary<Type, List<EntityInfo>> BeforeSaveEntities(Dictionary<Type, List<EntityInfo>> saveMap) {
      // 返回我们要保存的那些实体的地图。
      返回保存地图;
    }
  }
于 2013-06-03T11:26:52.967 回答
2

@jaq316 是正确的:自定义EFContextProvider是拦截来自客户端的更改的地方。它是授权和验证它们的地方。该文档有更多详细信息。它的本质是您在重写BeforeSaveEntityBeforeSaveEntities虚拟方法中仔细检查建议的更改;或者,您可以将处理程序附加到BeforeSaveEntityDelegateand BeforeSaveEntitiesDelegate

于 2013-06-04T01:23:10.307 回答
1

所以这是我对这个的想法,因为我根本没有使用 ContextProvider。我正在利用 SQL 后端和 Ninject 将存储库依赖项注入到我拥有的每个控制器中。我有比“Todos”演示更多的项目,并且还想要单独的控制器和存储库。如果我创建了如微风文档所示的 ContextProvider,我将拥有一个包含所有实体的 ContextProvider 文件。这将是巨大的。如果我将它们分成单独的上下文,我会在所有覆盖中复制代码。

这是我在 ContactFormController.cs 中保存更改的方法:

             [HttpPost]
    public SaveResult SaveChanges(JObject saveBundle)
    {
        var sr = new SaveResult() { KeyMappings = new List<KeyMapping>(), Entities = new List<object>()};
        dynamic entity = saveBundle["entities"][0];
        ContactForm form = entity.ToObject<ContactForm>();
        EntityState state = entity.entityAspect.entityState;

        switch (state)
        {
            case EntityState.Added:

                KeyMapping mapping = new KeyMapping(){EntityTypeName = typeof(ContactForm).ToString(), TempValue = form.Id };
                var validationErrors = _contactFormService.ProcessContactForm(ref form).Cast<object>().ToList();

                //if we succeed then update the mappings
                if (validationErrors.Count == 0)
                {

                    //setup the new mappings
                    mapping.RealValue = form.Id;
                    sr.KeyMappings.Add(mapping);

                    //link the entity
                    sr.Entities.Add(form);
                }
                else
                {
                    sr.Errors = validationErrors;
                }

                break;
        }

        return sr;
    }

我在客户端保存之前动态更改端点,以便我的 webapi 中的每个控制器都有一个 SaveChanges() 方法。然后我调用适当的存储库以根据需要处理后端功能。这样,我可以根据注入的 repo 运行模拟代码或实际的 SQL 更改。

如果它们是表单处理中的错误,那么我们将自定义 List 列表转换为 List 并将其分配给 SaveResult 的 Errors 属性。如果没有错误,我们会发回新的键映射以在客户端上更新。

理想情况下,我想减少此控制器中的所有代码,并可能将其抽象为实用方法,以便每个控制器中的重复更少。我喜欢这种方法,因为这样我就可以创建普通的存储库,而不是让它们依赖于 ContextProvider。那时微风独立。

于 2014-01-23T15:57:28.900 回答