65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.93/5 (27投票s)

2015 年 5 月 11 日

CPOL

8分钟阅读

viewsIcon

461104

downloadIcon

2337

SharePoint 2013, REST API

引言

本文档的目的是提供一个关于使用 REST API 在 SharePoint 2013 列表上执行 CRUD(创建、读取、更新和删除)操作的完整概念。目标受众必须了解 OData(Open Data Protocol 是一种 OASIS 标准,它定义了构建和使用 RESTful API 的最佳实践)。

初始设置

为了简化操作,请考虑我们有两个列表(SpTutorial&SpTutorialParent),我们将在其中执行 CRUD 操作。

SpTutorial

在此列表中,我尝试涵盖所有类型的列,以便我们可以了解如何获取和设置这些列的值。

Main list

SpTutorialParent

它在 SpTutorial 中用作查找列,以便我们可以了解如何获取和设置查找列的值。

lookup list

注意:请查看附件以获取创建这些列表的 PowerShell 脚本。

所需工具

所有示例均使用jQuery.ajax 提供,但您可以使用任何 REST 客户端,如FiddlerPostmanAdvanced REST Client 等。这些 REST 客户端存在一些问题。它们与 SharePoint 的兼容性不佳。因此,我创建了自己的SharePoint REST 客户端

sp rest client

我相信您会乐于使用此 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 方法是GETPOSTPUTMERGEPATCH。支持的数据格式是ATOM(基于 XML)或JSON

READHTTP GET 方法用于任何读取操作。

CREATE:任何创建操作,如列表、列表项、站点等,都映射到HTTP POST 方法。您必须在请求正文中指定数据,仅此而已。对于非必需列,如果您不指定值,则它们将设置为其默认值。另一件重要的事情是:您不能为只读字段设置值。如果这样做,您将收到一个异常。

UPDATE:要更新现有的 SharePoint 2013 对象,有三种HTTP 方法可用:PUTPATCHMERGE。推荐使用PATCHMERGE 方法。PUT 需要整个庞大的对象才能执行更新操作。假设我们有一个名为EMPLOYEE 的列表,它有 100 多个字段,我们只想更新EmployeeName 字段。在这种情况下,如果我们使用PUT 方法,则除了EmployeeName 字段外,我们还必须指定其他字段的值。但是PATCHMERGE 非常简单。我们只需要指定EmployeeName 字段的值。

DELETEHTTP DELETE 方法用于删除 SharePoint 2013 中的任何对象。

要使用REST API 访问 SharePoint 资源,我们首先需要找到合适的端点。下表演示了与列表中CRUD 操作相关的端点。

URL 端点

描述

支持的 HTTP 方法

/_api/Web/Lists

检索站点中的所有列表并添加新列表

GET, POST

/_api/Web/Lists/GetByTitle('listname')

通过标题获取列表详细信息并更新它。如果有人更改了您的列表标题,您的代码将会中断。

GET, POST

/_api/Web/Lists(guid'guid id of your list')

与上面相同,但更改列表标题不会影响代码。

GET, POST

/_api/Web/Lists/GetByTitle('listname')/Fields

检索与列表关联的所有字段并添加新字段

GET, POST

/_api/Web/Lists/GetByTitle('listname')/

Fields/GetByTitle('fieldname')

获取字段详细信息、修改和删除它。

GET, PUT, PATCH, MERGE, DELETE

/_api/Web/Lists/GetByTitle('listname')

/Items

检索列表中的所有项并添加新项

GET, POST

/_api/web/lists/GetByTitle('listname')

/GetItemById(itemId)

此端点可用于获取、更新和删除单个项。

GET, PUT, PATCH, MERGE, DELETE

希望您已经完成了如前所述创建上述列表。现在来看一下如何在实际生活中使用它的实际示例。从客户端访问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 中,您会发现字段的内部名称作为对象的属性。在上面的示例中,我们只会获取LookupPerson 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’。现在,让我们看看还有哪些其他查询运算符可用。

数值

字符串

日期时间函数

Lt(小于)

startsWith(如果以某个字符串值开头)

day()

Le(小于或等于)

substringof(如果包含任何子字符串)

month()

Gt(大于)

 

year()

Ge(大于或等于)

 

hour()

Eq(等于)

Eq

minute()

Ne(不等于)

Ne

second()

注意:不幸的是,日期时间函数在新式(URL)的 SharePoint 2013 中不起作用。但也有希望,我们可以像 SharePoint 2010 风格那样实现。

var filterByMonth = "/_vti_bin/listdata.svc/SpTutorial?$filter=month(SpDateTime) eq 6";

$orderby 用于对项进行排序。允许多个字段,用逗号分隔。可以通过追加ascdesc 关键字来指定升序或降序。

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";

类型

单行文本

字符串

多行文本

也可以在此处添加多行,包括富文本

选择

String,但它必须来自列表中可用的选项。

数字

Integerdouble

货币

类似于数字

日期和时间

String,但必须采用ISOString 格式

查找

Integer,并且必须是Lookup 项的ID

是/否

truefalse

人员或组

Integer,并且必须是Person or GroupID

超链接或图片

Object,它只有三个属性:__metadataUrlDescription

要为人员或组列插入多个值,我们必须指定人员或组的 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 的方法:

  1. "If-Match": oldItem.__metadata.etag(如果etag 值不匹配,服务将返回异常)
  2. "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 相同。操作成功时,它将不返回任何内容。但如果发生任何错误,它将返回一个异常。

使用 SharePoint 2013 REST API 对列表执行 CRUD 操作 - CodeProject - 代码之家
© . All rights reserved.