首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >Breeze.JS用于SharePoint 2013年错误保存更改

Breeze.JS用于SharePoint 2013年错误保存更改
EN

Stack Overflow用户
提问于 2014-07-16 05:42:46
回答 5查看 910关注 0票数 0

对象extraMetadata未定义,并在breeze.labs.dataservice.sharepoint.js的第247行引发错误。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rawEntity.__metadata = { 'type': aspect.extraMetadata.type };

我怀疑这是因为我还没有在实体定义中定义在__metadata对象中找到的类型。任何关于如何正确定义我的类型的建议都是非常欢迎的!这是我对其中一个对象的类型定义。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
   models.Project = {
        name: 'Project',
        defaultResourceName: 'getbytitle(\'Projects\')/items',
        dataProperties: {
            ID: {
                type: breeze.DataType.Int32
            },
            Title: {
                nullable: false
            },
            StatusId: {
                type: breeze.DataType.Int32,
                nullable: false
            },
            SelectedApproverId: {
                type: breeze.DataType.Int32,
                nullable: false
            },
            Created: {
                type: breeze.DataType.DateTime
            },
            Modified: {
                type: breeze.DataType.DateTime
            }
        },
        navigationProperties: {
            Status: {
                type: "Status",
                foreignKeyNames: ['StatusId'],
                hasMany: false
            },
            SelectedApprover: {
               type: "User",
               foreignKeyNames: ["SelectedApproverId"]
            }
        }
    };

更新:2013年11月11日

如果我运行以下查询:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    return breeze.EntityQuery
           .from(metadataStore.getEntityType('Project').defaultResourceName)
           .orderBy('Created desc')
           .using(manager)
           .execute()
           .then(function (data) {
                console.log(data.results);
                return data.results;
           });

结果是一个简单的JavaScript对象数组,而不是缺乏__metadata属性的Breeze实体。我想弄清楚为什么会这样。

最新情况: 11/12/2014

我已经确认,当我在navigationProperties下定义了多个实体时,就会出现这个问题。

EN

回答 5

Stack Overflow用户

发布于 2014-07-16 14:40:40

请确保您使用的是BreezeJS v.1.4.12或更高版本。

要明确的是,您所引用的代码位于我所拥有的文件的第147行(而不是247号)上。

它位于_createChangeRequest中,正在准备保存修改后的实体。我将假设您已经查询了一个Product实体,对其进行了更改,并在错误发生时将其保存回去。

我不相信问题会被追溯到如何定义Product类型的元数据。

__metadata 您不应该为您的类型定义属性。__metadata属性是我们期望SharePoint (实际上是任何OData源)添加到JSON实体数据中的东西,当您查询实体的OData源时,它会发送给客户端。

__metadata不会为投影返回的结果定义,但是您的问题涉及一个修改的实体,所以我假设您是通过正常的查询获得这个实体的……没有select子句的人。

我想知道是否在检索正在修改的实体的查询的JSON有效负载中看到了JSON __metadata 属性。请检查来自查询请求的网络流量。,如果您没有看到它,我们必须找出服务器没有发送它的原因。

背景

JSON节点上的__metadata属性是与SharePoint OData服务器的契约的关键部分。这就是Breeze客户端如何了解实体的类型及其etag。

查看jsonResultsAdapter.visitNodeupdateEntityNode方法。您将看到适配器如何使用__metadata来确定该数据的EntityType。您还将看到适配器将__metadata移动到适配器结果的extraMetadata属性。BreezeJS随后将“额外的元数据”从该结果对象移动到实体的entityAspect.extraMetadata属性。

这看上去很痛苦吗?它被折磨了。OData需要与实体(特别是etag)一起携带额外的信息,否则服务器就不会更新或删除实体。我们必须把这些信息藏在某个地方,远离你的头发,然后当我们向服务器发出保存请求时,把它拿回来。我们将其放在entityAspect上,以符合该属性作为与对象的业务目的无关的“实体-状态”的守护者角色,以及与其如何持久化有关的所有操作。

就这么多原因。窃听器在哪里?

臭虫

底层的错误是这个来自SharePoint OData源的OData已经消失了。我们还不知道它是怎么消失的。但没有它我们就有大麻烦了。

extraMetadata丢失时,sharepoint适配器应该会给出更好的消息。我们实际上是在几行之后查找这个问题;请参见adjustUpdateDeleteRequest

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var extraMetadata = aspect.extraMetadata;
if (!extraMetadata) {
    throw new Error("Missing the extra metadata for an update/delete entity");
}

那个测试看起来太晚了。我会做个笔记把测试移到上面去。

但是,这样的修复只会导致保存失败,并带来更好的消息。它不会告诉你怎么修理它。

所以让我们找出__metadata消失的地方.从它是否曾经到达的地方开始。

我在等你的报告。

2014年7月17日最新情况

我仍在等待您是否在原始实体查询的响应的有效负载中看到__metadata属性。

同时,我检查了OData规范(复数)对__metadata属性的引用。看来,__metadata属性始终是可选的。因此,OData提供者不需要发送或遵守etag .我们知道这是可能的,因为Web 2 OData不支持etags .一个即将被纠正的缺陷。

参见描述OData格式的JSONv.2规范。搜索"__metadata“这个词。 JSONv.3规范还在OData响应中调用__metadata属性(至少是一个JSON详细响应)。 但是..。沉重的叹息..。__metadata属性似乎与v.4规范无关,元数据信息完全通过JSON注释提供。DataJS库(由许多BreezeJS OData适配器使用,但不是所有)可以将这些注释映射到节点的__metadata属性中,但我还不能确认它。我们有一些工作要处理所有这些变化。

同时,我认为all BreezeJS OData数据服务适配器应该对额外的元数据采取更多的防御立场,而不应该抛出异常。

我们很快就会做出防御上的改变。

当然,如果OData服务实际需要etag或其他元数据,服务器将拒绝您的更新或删除请求。我还不知道我们能做些什么。

票数 3
EN

Stack Overflow用户

发布于 2014-10-06 11:00:29

已经有一段时间没有帖子了,但我会分享我发现的问题,以及我是如何解决这个问题的(因为我花了很长时间)。

基本上,breeze.labs.dataservice.sharepoint适配器有一个函数serverTypeNameToClientDefault(),它期望REST/OData在__metadata " type“字段中返回的SharePoint自定义列表类型为确切的格式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SP.Data.**mylistname**sListItem**  (notice the "sListItem" suffix; ;  Ex. SP.Data.CustomersListItem)

该函数执行字符串regex从SharePoint类型中提取Breeze实体名称,并使用该名称在元数据存储中查找实体(在上面的示例中为“Customer”)。如果没有匹配,Breeze将找不到您的实体,并将返回一个基本对象而不是Breeze实体。因此,您从SharePoint返回的REST结果,即使它具有__metadata属性,也不会转换为包含属性entityAspect.extraMetadata的Breeze实体。这就是导致“无法获得未定义或空引用的属性‘类型’”错误的原因。

对于我的解决方案,因为在我的例子中,我不太关心我的自定义列表的URL是什么,我只是确保当我的自定义列表由SharePoint提供时,它会根据Breeze的期望得到一个名称。为此,您可以设置Url元素的ListInstance属性,如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<ListInstance 
      Title="My Customers" 
      OnQuickLaunch="TRUE" 
      TemplateType="10000" 
      Url="Lists/Customers"    <!-- List/Customer will not work -->
      Description="My List Instance">
      ...

更好的解决方案是使serverTypeNameToClientDefault()函数更健壮,或者在本地修复它以满足我的需要,但希望这可以在适配器的未来版本中得到解决。

请注意,我已经用以下配置(并非列出所有依赖项)测试了此解决方案: Breeze.Client 1.4.9和Breeze.DataService.SharePoint 0.2.3

Breeze.Client 1.5.0和Breeze.DataService.SharePoint 0.3.2

还请注意,当出现上述情况时,0.3.2版本的适配器现在会显示更好的错误消息--“缺少update/delete实体的额外元数据”;但它没有解决问题。

希望这能帮上忙。

票数 3
EN

Stack Overflow用户

发布于 2014-07-17 08:45:33

对于微风v1.4.14和微风实验室,SharePoint2013v0.2.3,我在文件breeze.labs.dataservice.sharepoint.js.中使用小补丁在功能的末尾

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function visitNode(node, mappingContext, nodeContext)

就在之前

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
return result;

我只是像这样设置属性extraMetadata:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
result.extraMetadata = node.__metadata;

当我试图将修改后的实体保存回sharepoint时,这似乎解决了问题。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24782426

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文