SharePoint List REST API. Часть 1

Основные операции по работе со списками и библиотеками документов описаны в статье Работа со списками и элементами списков с использованием REST. В этом посте я покажу как выполнять операции с большинством из существующих типов полей, таких как метаданные (Таксономия), множественный выбор, подстановка и другими.

Поля списка

Мой демонстрационный список содержит следующие поля:

Поля демонстрационного списка

Поля демонстрационного списка

Обязательным является только поле Title.

Перед тем как мы начнем работать с SharePoint REST API пара моментов о среде:

Простой AJAX запрос:

$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items",
    type: "POST",
    headers: {
        "Accept": "application/json; charset=utf-8",
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val()
    }
});

Заголовок X-RequestDigest должен содержать допустимое значение дайджеста для каждого не-POST запроса (Работа с __REQUESTDIGEST).

Для получения REST url'а для списка можно использовать следующий код:

var url = _spPageContextInfo.webServerRelativeUrl + "_api/web/lists/getbytitle('" + listTitle + "')"

List Item EntityType FullName

Для взаимодействия с данными, хранящимися в списке или библиотеке документов мы должны знать полное имя сущности. Получить это имя можно из соответствующего списка с помощью GET-запроса:

var url = _spPageContextInfo.webServerRelativeUrl + "_api/web/lists/getbytitle('" + listTitle + "')?$select=ListItemEntityTypeFullName"

Ответ от сервера будет содержать нужное нам значение:

<?xml version="1.0" encoding="utf-8"?>
<entry>
    <id>https://{YOUR_TENANT_NAME}.sharepoint.com/_api/Web/Lists(guid'{YOUR_LIST_ID}')</id>
    <category term="SP.List" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
    <link rel="edit" href="Web/Lists(guid'{YOUR_LIST_ID}')" />
    <content type="application/xml">
        <m:properties>
            <d:ListItemEntityTypeFullName>SP.Data.CRUDListListItem</d:ListItemEntityTypeFullName>
        </m:properties>
    </content>
</entry>

В моём случае имя сущности - SP.Data.CRUDListListItem.

Итак, у нас есть всё необходимое, чтобы начать: дайджест из скрытого поля страницы, имя списка, которое нам известно, относительный url сайта из объекта _spPageContextInfo и значение свойстваListItemEntityTypeFullName нашего списка.

Начнем с простого и будем постепенно переходить к сложному. Во всех примерах я покажу как выполнять четыре операции: Создание, Чтение, Обновление и Удаление.

Текст

Самый простой пример использования REST API.

Создание

Чтобы добавить новый элемент списка мы должны выполнить POST-запрос:

$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items",
    type: "POST",
    headers: {
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val() // <-- дайджест
    },
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- имя сущности
        "Title": "TextFieldValue" // <-- "Имя поля": "Значение"
    })
});

Ответ от сервера в случае успешного завершения операции будет содержать свойства созданного элемента и статус запроса будет HTTP 201 Created:

<?xml version="1.0" encoding="utf-8"?>
<entry>
    <content type="application/xml">
        <m:properties>
            <d:Id m:type="Edm.Int32">3</d:Id>
            <d:Title>TextFieldValue</d:Title>
        </m:properties>
    </content>
</entry>

Ответ содержит также идентификатор элемента, который можно использовать для чтения данных.

Чтение

Чтобы получить значение свойства, мы должны знать идентификатор элемента и внутреннее имя поля. Запрос на чтение данных:

$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items(3)?$select=Title", // <-- Идентификатор элемента 
    type: "GET",
    headers: {
        "Content-Type": "application/json;odata=verbose"
    }
});

Обновление

Запрос на обновление должен содержать два дополнительных заголовка: X-HTTP-Method и IF-MATCH:

$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items(3)", // <-- lsit item id
    type: "POST",
    headers: {
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val(), // <-- дайджест
        "X-HTTP-Method": "MERGE", // <--  заголовки для запроса на обновление
        "IF-MATCH": "*" // <--  заголовки для запроса на обновление
    },
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- имя сущности
        "Title": "NewFieldValue" // <-- "Имя поля": "Значение"
    })
});

Ответ на запрос обновления имеет статус 304 No Content (если всё прошло хорошо).

Значения всех полей необходимо передавать?

Нет, только те поля и значения, которые необходимо обновить. Поля не представленные в запросе обновлены не будут.

Удаление

Просто укажите значение поля равным null чтобы удалить его содержимое.

$.ajax({
    // другие параметры запроса
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- имя сущности
        "Title": null // <-- удаляем значение поля
    })
});

Выбор

Создание

В моём списке есть одно поле выбора и запретом на добавление новых значений при вводе данных:

Первый запрос на создание элемента с ожидаемым значением поля выбор:

$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items",
    type: "POST",
    headers: {
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val() // <-- дайджест
    },
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- имя сущности
        "SingleChoiceField": "Choice 1" // <-- "Имя поля": "Значение"
    })
});

И новый элемент в списке:

Обратите внимание на поведение SharePoint: SharePoint REST API позволяет создавать/обновлять элементы без заполнения обязательных полей!

Чтение

Смотрите раздел чтение для текстовых полей.

Обновление

Для запроса на обновление я пробую казать невалидные значения для значения поля:

$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items(3)", // <-- Идентификатор элемента
    type: "POST",
    headers: {
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val(), // <-- дайджест
        "X-HTTP-Method": "MERGE", // <-- for update request
        "IF-MATCH": "*" // <-- заголовки для запроса на обновление
    },
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- имя сущности
        "SingleChoiceField": "NotValidValue" // <-- "Имя поля": "Значение"
    })
});

Как видно, за валидацией надо следить самому при использовании SharePoint REST API:

Удаление

Смотрите раздел удаление для текстовых полей.

Множественный выбор

Работа с текстовыми полями и полем выбора (единственного) идентична. Но в случае множественного выбора есть несколько важных моментов, о которых надо помнить.

Создание

Значение поля множественного выбора должно быть представлено объектом Collection(Edm.String):

$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items",
    type: "POST",
    headers: {
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val() // <-- дайджест
    },
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- имя сущности
        "MultiChoiceField": {
                "__metadata": {"type": "Collection(Edm.String)"},
                "results": [ // <-- array of values
                        "Choice 1",
                        "Choice 2"
                ]
        }
    })
});

Чтение

GET-запрос

$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items(3)?$select=MultiChoiceField", // <-- Идентификатор элемента
    type: "GET",
    headers: {
        "Content-Type": "application/json;odata=verbose"
    }
});

Ответ от сервера содержит массив значений:

<?xml version="1.0" encoding="utf-8"?>
<entry>
    <category term="SP.Data.CRUDListListItem" />
    <content type="application/xml">
        <m:properties>
            <d:MultiChoiceField m:type="Collection(Edm.String)">
                <d:element>Choice 1</d:element>
                <d:element>Choice 2</d:element>
            </d:MultiChoiceField>
        </m:properties>
    </content>
</entry>

Обновление

Ещё один правильный запрос с неправильными значениями в поле множественного выбора:

$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items(3)", // <-- Идентификатор элемента
    type: "POST",
    headers: {
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val(), // <-- дайджест
        "X-HTTP-Method": "MERGE", // <--  заголовки для запроса на обновление
        "IF-MATCH": "*" // <--  заголовки для запроса на обновление
    },
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- имя сущности
        "MultiChoiceField": {
                "__metadata": {"type": "Collection(Edm.String)"},
                "results": [ // <-- массив значений
                        "NotValidValue 1",
                        "NotValidValue 2"
                ]
        }
    })
});

Удаление

Смотрите раздел удаление для текстовых полей.

Единственная подстановка/Пользователь

Поле выбора пользователя унаследовано от поля подстановки. Поэтому работа с обеими этими типами полей работа идентична в REST API.

Создание

В случае подстановки/пользователя достаточно передать только идентификатор элемента. Имя поля в запросе должно иметь вид Id. Просто добавьте "Id" к имени поля:

$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items",
    type: "POST",
    headers: {
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val() // <-- дайджест
    },
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- имя сущности
        "SingleLookupId": 1 // <-- Идентификатор элемента подстановки
    })
});

Чтение

Для чтения значения из поля подстановки можно использовать псевдо-поле Id для получения идентификатор элемента. Для получения полного набора идентификатора и текстового поля элемента необходимо указывать само поле в параметре $expand запроса:

var restUrl = "/_api/web/lists/getbytitle('CRUDList')/items(3)?"+
    "$select=SingleLookupId,SingleLookup/Id,SingleLookup/Title&"+ // <-- select id and projected fields
    "$expand=SingleLookup"; // <-- expand lookup field
$.ajax({
    url: restUrl,
    type: "GET"
});

Ответ на запрос от сервера:

<?xml version="1.0" encoding="utf-8"?>
<entry>
    <link title="SingleLookup">
        <m:inline>
            <entry>
                <content type="application/xml">
                    <m:properties>
                        <d:Id m:type="Edm.Int32">2</d:Id>
                        <d:Title>Item 2</d:Title>
                    </m:properties>
                </content>
            </entry>
        </m:inline>
    </link>
    <content type="application/xml">
        <m:properties>
            <d:SingleLookupId m:type="Edm.Int32">2</d:SingleLookupId>
        </m:properties>
    </content>
</entry>

Обновление

Запрос на обновление идентичен запросу на создание. Просто добавьте идентификатор обновляемого элемента и необходимые заголовки запроса.

$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items",
    type: "POST",
    headers: {
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val() // <-- дайджест
    },
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- имя сущности
        "SingleLookupId": 1 // <-- Идентификатор элемента подстановки
    })
});

Удаление

Смотрите раздел удаление для текстовых полей.

Множественная подстановка/Пользователи

Поле множественного выбора в запросах создания и обновления должно быть представлено массивом идентификаторов.

Имя поля множественной подстановки также должно содержать постфикс Id.

Create

Массив идентификаторов элементов подстановки в качестве значения поля:

$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items",
    type: "POST",
    headers: {
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val() // <-- дайджест
    },
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- имя сущности
        "MultiLookupId": {
                "results": [1, 2, 3]  // <-- Идентификатор элемента подстановки
        }
    })
});

Чтение

var restUrl = "/_api/web/lists/getbytitle('CRUDList')/items(3)?"+
    "$select=MultiLookupId,MultiLookup/Id,MultiLookup/Title&"+ // <-- select id and projected fields
    "$expand=MultiLookup"; // <-- expand lookup field
$.ajax({
    url: restUrl,
    type: "GET"
});

Ответ от сервера содержит массив идентификаторов и коллекцию объектов с выбранными полями:

<?xml version="1.0" encoding="utf-8"?>
<entry>
    <link title="MultiLookup">
        <m:inline>
            <feed>
                <entry>
                    <content type="application/xml">
                        <m:properties>
                            <d:Id m:type="Edm.Int32">1</d:Id>
                            <d:Title>Item 1</d:Title>
                        </m:properties>
                    </content>
                </entry>
                <entry>
                    <content type="application/xml">
                        <m:properties>
                            <d:Id m:type="Edm.Int32">2</d:Id>
                            <d:Title>Item 2</d:Title>
                        </m:properties>
                    </content>
                </entry>
                <entry>
                    <content type="application/xml">
                        <m:properties>
                            <d:Id m:type="Edm.Int32">3</d:Id>
                            <d:Title>Item 3</d:Title>
                        </m:properties>
                    </content>
                </entry>
            </feed>
        </m:inline>
    </link>
    <content type="application/xml">
        <m:properties>
            <d:MultiLookupId m:type="Collection(Edm.Int32)">
                <d:element>1</d:element>
                <d:element>2</d:element>
                <d:element>3</d:element>
            </d:MultiLookupId>
        </m:properties>
    </content>
</entry>

Обновление

Запрос на обновление идентичен запросу на создание. Просто добавьте идентификатор обновляемого элемента и необходимые заголовки запроса.

Удаление

Смотрите раздел удаление для текстовых полей.

Работа с другими типами полей такими как метаданные, ссылка и другими я покажу во второй части этого поста.

Виталий Жуков

Виталий Жуков

SharePoint архитектор, разработчик, тренер, Microsoft MVP (Office Development). Более 15 лет опыта работы с SharePoint, Dynamics CRM, Office 365, и другими продуктами и сервисами Microsoft.

Смотрите также

Развертывание списков и библиотек с помощью SPFx-решений

Развертывание списков и библиотек с помощью SPFx-решений

SharePoint. Drag-and-Drop Загрузчик файлов

SharePoint. Drag-and-Drop Загрузчик файлов

CSOM. Загрузка файлов

CSOM. Загрузка файлов

SharePoint List REST API. Часть 2

SharePoint List REST API. Часть 2

SharePoint Framework. Создание веб-части на Angular

SharePoint Framework. Создание веб-части на Angular

Презентация с доклада о SharePoint Framework

Презентация с доклада о SharePoint Framework

SharePoint Framework. Создаем AngularJS 1.x Client WebPart

SharePoint Framework. Создаем AngularJS 1.x Client WebPart

SharePoint. Регистрация CSS и JavaScript с помощью DelegateControl

SharePoint. Регистрация CSS и JavaScript с помощью DelegateControl

SharePoint. Расширяем REST API

SharePoint. Расширяем REST API

SharePoint Excel Services. Создаем кредитный калькулятор

SharePoint Excel Services. Создаем кредитный калькулятор

SharePoint Ribbon API. Использование ToggleButton

SharePoint Ribbon API. Использование ToggleButton

SharePoint 2013. How To: настройка входящей почты для разработчиков

SharePoint 2013. How To: настройка входящей почты для разработчиков

Мифы и правда о Linq to SharePoint

Мифы и правда о Linq to SharePoint

5 особенностей SPSiteDataQuery

5 особенностей SPSiteDataQuery

SharePoint 2013. Введение в SharePoint App. Часть 2

SharePoint 2013. Введение в SharePoint App. Часть 2

SharePoint 2013. Введение в SharePoint App. Часть 1

SharePoint 2013. Введение в SharePoint App. Часть 1

Превью для веб-части в SharePoint 2010/2013

Превью для веб-части в SharePoint 2010/2013

SharePoint 2013. Еще немного о новых контролах

SharePoint 2013. Еще немного о новых контролах

SharePoint 2013. Контрол ClientPeoplePicker

SharePoint 2013. Контрол ClientPeoplePicker

SharePoint 2013. Контрол ImageCrop

SharePoint 2013. Контрол ImageCrop

SharePoint 2013. Тип поля Geolocation

SharePoint 2013. Тип поля Geolocation

Создание типа поля в SharePoint

Создание типа поля в SharePoint

SharePoint 2010. Длительные операции с обновляемым статусом

SharePoint 2010. Длительные операции с обновляемым статусом

Linq to SharePoint. Создаем ContentIterator

Linq to SharePoint. Создаем ContentIterator

Linq to SharePoint. Получение данных из другой коллекции сайтов

Linq to SharePoint. Получение данных из другой коллекции сайтов

Linq to SharePoint. Версионность

Linq to SharePoint. Версионность

SharePoint. Получение URL-адреса иконки для документа

SharePoint. Получение URL-адреса иконки для документа

SharePoint 2010. PostBack для Fluent Ribbon API

SharePoint 2010. PostBack для Fluent Ribbon API

Linq to SharePoint. Блокировка документов

Linq to SharePoint. Блокировка документов

Linq to SharePoint. Паттерн Repository

Linq to SharePoint. Паттерн Repository

Linq to SharePoint. Получение мета-данных списка

Linq to SharePoint. Получение мета-данных списка

Linq to SharePoint. Мапинг полей

Linq to SharePoint. Мапинг полей

Linq to SharePoint. Формирование данных для ProcessBatchData

Linq to SharePoint. Формирование данных для ProcessBatchData

Linq to SharePoint. Сравнение производительности с Camlex.NET

Linq to SharePoint. Сравнение производительности с Camlex.NET

Linq to SharePoint. Часть 5. Поля Choice и MultiChoice

Linq to SharePoint. Часть 5. Поля Choice и MultiChoice

Linq to SharePoint. Часть 4. Dynamic LINQ

Linq to SharePoint. Часть 4. Dynamic LINQ

Linq to SharePoint. Особенности. Часть 3

Linq to SharePoint. Особенности. Часть 3

Linq to SharePoint. Особенности. Часть 2

Linq to SharePoint. Особенности. Часть 2

SharePoint 2010. PeopleEditor. Установка значения

SharePoint 2010. PeopleEditor. Установка значения

SharePoint 2010. Настройка входящей почты для кастомного списка

SharePoint 2010. Настройка входящей почты для кастомного списка

Linq to Sharepoint. Особенности

Linq to Sharepoint. Особенности

EntityFramework. Оптимистические блокировки

EntityFramework. Оптимистические блокировки