使用 SharePoint 2013 REST API 执行 CRUD 操作以列表化






4.93/5 (27投票s)
SharePoint 2013, REST API
引言
本文档的目的是提供一个关于使用 REST API 在 SharePoint 2013 列表上执行 CRUD(创建、读取、更新和删除)操作的完整概念。目标受众必须了解 OData(Open Data Protocol 是一种 OASIS 标准,它定义了构建和使用 RESTful API 的最佳实践)。
初始设置
为了简化操作,请考虑我们有两个列表(SpTutorial
&SpTutorialParent
),我们将在其中执行 CRUD 操作。
SpTutorial
在此列表中,我尝试涵盖所有类型的列,以便我们可以了解如何获取和设置这些列的值。
SpTutorialParent
它在
SpTutorial
中用作查找列,以便我们可以了解如何获取和设置查找列的值。
注意:请查看附件以获取创建这些列表的 PowerShell 脚本。
所需工具
所有示例均使用jQuery.ajax
提供,但您可以使用任何 REST 客户端,如Fiddler、Postman 或Advanced REST Client 等。这些 REST 客户端存在一些问题。它们与 SharePoint 的兼容性不佳。因此,我创建了自己的SharePoint REST 客户端。
我相信您会乐于使用此 REST 客户端来测试/探索 SharePoint 的 REST API。在此处找到其文档。
SharePoint 2013 中的 REST
列表的REST
服务首次引入于 SharePoint 2010。它位于端点/_vti_bin/listdata.svc
下,并且在 SharePoint 2013 中仍然有效。SharePoint 2013 引入了另一个端点/_api/web/lists
,它比 SharePoint 2010 中的功能更强大。SharePoint 2013 中 REST 的主要优势是:我们可以使用支持REST
Web 请求和Open Data Protocol
(OData) 语法的任何技术来访问数据。这意味着您只需向专用端点发出HTTP
请求即可完成所有操作。可用的HTTP
方法是GET
、POST
、PUT
、MERGE
和PATCH
。支持的数据格式是ATOM
(基于 XML)或JSON
。
READ
:HTTP GET
方法用于任何读取操作。
CREATE
:任何创建操作,如列表、列表项、站点等,都映射到HTTP POST
方法。您必须在请求正文中指定数据,仅此而已。对于非必需列,如果您不指定值,则它们将设置为其默认值。另一件重要的事情是:您不能为只读字段设置值。如果这样做,您将收到一个异常。
UPDATE
:要更新现有的 SharePoint 2013 对象,有三种HTTP
方法可用:PUT
、PATCH
和MERGE
。推荐使用PATCH
和MERGE
方法。PUT
需要整个庞大的对象才能执行更新操作。假设我们有一个名为EMPLOYEE
的列表,它有 100 多个字段,我们只想更新EmployeeName
字段。在这种情况下,如果我们使用PUT
方法,则除了EmployeeName
字段外,我们还必须指定其他字段的值。但是PATCH
和MERGE
非常简单。我们只需要指定EmployeeName
字段的值。
DELETE
:HTTP DELETE
方法用于删除 SharePoint 2013 中的任何对象。
要使用REST API
访问 SharePoint 资源,我们首先需要找到合适的端点。下表演示了与列表中CRUD
操作相关的端点。
URL 端点 |
描述 |
支持的 HTTP 方法 |
|
检索站点中的所有列表并添加新列表 |
|
|
通过标题获取列表详细信息并更新它。如果有人更改了您的列表标题,您的代码将会中断。 |
|
|
与上面相同,但更改列表标题不会影响代码。 |
|
|
检索与列表关联的所有字段并添加新字段 |
|
|
获取字段详细信息、修改和删除它。 |
|
|
检索列表中的所有项并添加新项 |
|
|
此端点可用于获取、更新和删除单个项。 |
|
希望您已经完成了如前所述创建上述列表。现在来看一下如何在实际生活中使用它的实际示例。从客户端访问REST
端点有多种方式,但方法几乎在所有地方都相同。在本文中,将使用jQuery($.ajax)
来访问所有端点。
从列表获取项
首先,创建从特定列表获取项的方法。如果我们使用$.ajax
,它应该如下所示:
function getItems(url) {
$.ajax({
url: _spPageContextInfo.webAbsoluteUrl + url,
type: "GET",
headers: {
"accept": "application/json;odata=verbose",
},
success: function (data) {
console.log(data.d.results);
},
error: function (error) {
alert(JSON.stringify(error));
}
});
}
在上面的代码中,_spPageContextInfo.webAbsoluteUrl
对您来说可能不熟悉。实际上,它返回当前站点 URL,并且是首选方式,而不是硬编码。现在是时候构建一些 URL 并调用上述方法了。
从 SpTutorial 获取所有项
如果我们再次查看REST
端点表,端点(构造的 URL)应该如下所示:
var urlForAllItems = "/_api/Web/Lists/GetByTitle('SpTutorial')/Items";
调用方法getItems(urlForAllItems);
在data.d.results
中,您会发现字段的内部名称作为对象的属性。在上面的示例中,我们只会获取Lookup
和Person type
列的 ID。但我们需要在JSON
结果中获取有关这些列的更多信息。要解决此问题,我们需要学习一些OData
查询字符串运算符。
$select
指定在JSON
结果中返回哪些字段。
$expand
帮助从查找列中检索信息。
现在如果我们重写urlForAllItems
,它应该如下所示:
var urlForAllItems =
"/_api/Web/Lists/GetByTitle('SpTutorial')/Items?"+
"$select=ID,Title,SpMultiline,SpChoice,
SpNumber,SpCurrency,SpDateTime,SpCheckBox,SpUrl,"+
"SpPerson/Name,SpPerson/Title,SpLookup/Title, SpLookup/ID" +
"&$expand=SpLookup,SpPerson";
要将$expand
与$select
一起使用,您必须在$select
中指定列名,就像我在上面所做的那样,例如SpLookup/Title, SpLookup/ID
。
$filter
指定返回哪些项。如果我想获取SpTutorial
的标题等于'first tutorial'
且SpTutorialParent
的 ID 等于1
的项,则URL
应该如下所示:
var urlForFilteredItems =
"/_api/Web/Lists/GetByTitle('SpTutorial')/Items?"+
"$select=ID,Title,SpMultiline,SpChoice,SpNumber,
SpCurrency,SpDateTime,SpCheckBox,SpUrl,"+
"SpPerson/Name,SpPerson/Title,SpLookup/Title,SpLookup/ID"+
"&$expand=SpLookup,SpPerson&$filter=Title eq
'first tutorial' and SpLookup/ID eq 1";
您可能会注意到我在上面的URL
中使用了查询运算符,例如‘eq’
。现在,让我们看看还有哪些其他查询运算符可用。
数值 |
字符串 |
日期时间函数 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
注意:不幸的是,日期时间函数在新式(URL)的 SharePoint 2013 中不起作用。但也有希望,我们可以像 SharePoint 2010 风格那样实现。
var filterByMonth = "/_vti_bin/listdata.svc/SpTutorial?$filter=month(SpDateTime) eq 6";
$orderby
用于对项进行排序。允许多个字段,用逗号分隔。可以通过追加asc
或desc
关键字来指定升序或降序。
var urlForOrderBy = "/_api/Web/Lists/GetByTitle('SpTutorial')/Items?" +
"$select=ID,Title,SpMultiline,SpChoice,
SpNumber,SpCurrency,SpDateTime,SpCheckBox,SpUrl," +
"SpPerson/Name,SpPerson/Title,SpLookup/Title,SpLookup/ID" +
"&$expand=SpLookup,SpPerson&$orderby=ID desc";
$top
用于对项进行分页。
var urlForPaging = "/_api/Web/Lists/GetByTitle
('SpTutorial')/Items?$top=2";
添加新项
在这种情况下,我们的HTTP
方法将是POST
。所以为此编写一个方法。
function addNewItem(url, data) {
$.ajax({
url: _spPageContextInfo.webAbsoluteUrl + url,
type: "POST",
headers: {
"accept": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val(),
"content-Type": "application/json;odata=verbose"
},
data: JSON.stringify(data),
success: function (data) {
console.log(data);
},
error: function (error) {
alert(JSON.stringify(error));
}
});
}
在标头中,您必须指定X-RequestDigest
的值。这是一个隐藏在页面中的字段,您可以通过上述方式($("#__REQUESTDIGEST").val()
)获取其值。但有时它不起作用。因此,适当的方法是从/_api/contextinfo
获取它。为此,您需要向此 URL(_api/contextinfo
)发送一个HTTP POST
请求,它将返回X-RequestDigest
值(在JSON
结果中,其名称应为FormDigestValue
)。
用于向列表中添加新项的URL
和请求正文将如下所示:
var addNewItemUrl = "/_api/Web/Lists/GetByTitle('SpTutorial')/Items";
var data = {
__metadata: { 'type': 'SP.Data.SpTutorialListItem' },
Title: 'Some title',
SpMultiline: 'Put here some multiline text.
You can add here some rich text also',
SpChoice: 'Choice 3',
SpNumber: 5,
SpCurrency: 34,
SpDateTime: new Date().toISOString(),
SpCheckBox: true,
SpUrl: {
__metadata: { "type": "SP.FieldUrlValue" },
Url: "http://test.com",
Description: "Url Description"
},
SpPersonId: 3,
SpLookupId: 2
};
注意:data
的属性是字段的内部名称。我们可以通过向以下URL
发送HTTP GET
请求来获取它们。
var urlForFieldsInternalName = "/_api/Web/Lists/GetByTitle('SpTutorial')/
Fields?$select=Title,InternalName&$filter=ReadOnlyField eq false";
类型 |
值 |
|
|
|
也可以在此处添加多行,包括富文本 |
|
|
|
|
|
类似于数字 |
|
|
|
|
|
|
|
|
|
|
要为人员或组列插入多个值,我们必须指定人员或组的 ID。
var data = {
__metadata: { "type": "SP.Data.TestListItem" },
Title: "Some title",
MultiplePersonId: { 'results': [11,22] }
}
注意:这是基于用户评论的更新。
如何为新列表项指定__metadata
的值?实际上,它看起来像这样:
__metadata: {'type': 'SP.Data.' + 'Internal Name of the list' + 'ListItem'}
或者我们可以通过发送GET
请求从以下 URL 获取它。
/_api/Web/Lists/getbytitle('List Name')/ListItemEntityTypeFullName
更新项
我们可以使用以下方法来更新项。
function updateItem(url, oldItem, newItem) {
$.ajax({
url: _spPageContextInfo.webAbsoluteUrl + url,
type: "PATCH",
headers: {
"accept": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val(),
"content-Type": "application/json;odata=verbose",
"X-Http-Method": "PATCH",
"If-Match": oldItem.__metadata.etag
},
data: JSON.stringify(newItem),
success: function (data) {
console.log(data);
},
error: function (error) {
alert(JSON.stringify(error));
}
});
}
然后,您可以获取旧项,修改它,并构造URL
。
var updateItemUrl = "/_api/Web/Lists/GetByTitle('SpTutorial')/
getItemById('Id of old item')";
与添加新项相比,有一些变化。现在HTTP
方法是PATCH
,并且在标头("X-Http-Method": "PATCH"
)中也指定了它,这正是我之前推荐的方法。
etag
表示实体标签,它在进行HTTP GET
项时总是返回的。在进行任何更新或删除请求时,您都必须指定etag
值,以便 SharePoint 可以识别该项自请求以来是否已更改。以下是指定etag
的方法:
"If-Match": oldItem.__metadata.etag
(如果etag
值不匹配,服务将返回异常)"If-Match": "*"
(当需要强制更新或删除时考虑此项)
删除项
这非常简单。只需以下方法即可完成所有操作。
function deleteItem(url, oldItem) {
$.ajax({
url: _spPageContextInfo.webAbsoluteUrl + url,
type: "DELETE",
headers: {
"accept": "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val(),
"If-Match": oldItem.__metadata.etag
},
success: function (data) {
},
error: function (error) {
alert(JSON.stringify(error));
}
});
}
URL 与更新项的 URL 相同。操作成功时,它将不返回任何内容。但如果发生任何错误,它将返回一个异常。