SharePoint List REST API. Часть 2

SharePoint List REST API

Работа со списками и элементами списков с использованием REST (docs.microsoft.com)
Часть 1 - Текстовые поля, Да/Нет, Выбор, Множественный выбор, Подстановка, Пользователи и группы
Часть 2 - Ссылка или рисунок, Метаданные, Дата и время (этот пост)

Вторая часть серии постов о работе с SharePoint REST API. В этом посте я покажу как выполнять операции со следующими типами полей: Ссылка или рисунок, Метаданные, Дата и время.

Значение поля ссылки должен быть объект, а не просто текст. Этот объект содержит два поля свойства:Url (ссылка) и Description (описание).

Создание

Запрос на создание элемента списка:

$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items",
    type: "POST",
    headers: {
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val() // <-- дайджест</span>
    },
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- имя сущности</span>
        "HyperlinkField": {// <-- hyperlink object</span>
            "Description": "My blog",
            "Url": "https://blog.vitalyzhukov.ru"
        }
    })
});

Ответ от сервера со статусом 201 содержит информацию о созданном элементе:

<?xml version="1.0" encoding="utf-8"?>
<entry>
    <category term="SP.Data.CRUDListListItem" />
    <content type="application/xml">
        <m:properties>
            <d:Id m:type="Edm.Int32">10</d:Id>
            <d:HyperlinkField m:type="SP.FieldUrlValue">
                <d:Description>My blog</d:Description>
                <d:Url>https://blog.vitalyzhukov.ru</d:Url>
            </d:HyperlinkField>
        </m:properties>
    </content>
</entry>

Чтение

Для чтения значения поля надо указать его имя в GET-запросе:

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

Обновление

Нельзя обновить только свойство Description или только свойство Url. Объект с обеими свойствами должен быть представлен в запросе на обновление:

$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items(10)",
    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" }, // <-- имя сущности
        "HyperlinkField": {// <-- hyperlink object
            "Url": "http://blog.vitalyzhukov.ru",
            "Description": "Sharepoint blog"
        }
    })
});

Удаление

Как мы знаем из моего предыдущего поста, для удаления значения в поле достаточно указать его раным null:

$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items(10)",
    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" }, // <-- имя сущности
        "HyperlinkField": null // <-- clear field value
    })
});

Дата и время

CRUD-операции с полем типа Дата и время крайне похожи на операции с текстовыми полями списка или библиотеки. Только тип данных Date вместо String.

Создание

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" }, // <-- имя сущности
        "DateField": new Date(2020, 0, 1)// <-- 01.01.2020 
    })
});

Read

Для чтения значения поля указываем его имя в запросе:

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

Ответ содержит значение поля в формате UTC:

<?xml version="1.0" encoding="utf-8"?>
<entry>
    <content type="application/xml">
        <m:properties>
            <!-- UTC-3 TimeZone --></span>
            <d:DateField m:type="Edm.DateTime">2019-12-31T21:00:00Z</d:DateField>
        </m:properties>
    </content>
</entry>

Обновление

Обновление поля дата и время не требует приведение значения даты к UTC. Сервер сделает это сам при записи значения поля в базу данных..

$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items(10)",
    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" }, // <-- имя сущности
        "DateField": new Date() // <-- текущая дата
    })
});

Удаление

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

Метаданные (Таксономия)

Поле метаданных (поля со множественным выбором смотрите ниже) долно быть представленно объектом SP.Taxonomy.TaxonomyFieldValue.

Создание

Запрос на создание элемента

$.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" }, // <-- имя сущности
        "SingleTerm": {
            "__metadata": {
                "type": "SP.Taxonomy.TaxonomyFieldValue"
            },
            "TermGuid": "d3ce8903-4b4e-442e-8f19-161bf45be9e8", // <-- Term Id 
            "WssId": "-1" // <-- always "-1" 
        }
    })
});

Чтение

Чтение поля таксономии через REST:

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

Пример данных, которые возвращает сервер

<entry>
    <content type="application/xml">
        <m:properties>
            <d:SingleTerm m:type="SP.Taxonomy.TaxonomyFieldValue">
                <d:Label>67</d:Label>
                <d:TermGuid>d3ce8903-4b4e-442e-8f19-161bf45be9e8</d:TermGuid>
                <d:WssId m:type="Edm.Int32">67</d:WssId>
            </d:SingleTerm>
        </m:properties>
    </content>
</entry>

Как видно SharePoint возвращает идентификаторы вместо имен терминов.

SharePoint REST API не возвращает имена терминов для полей с единственным выбором.

Обновление

Также как и для создания нам требуется знать только идентификатор термина:

$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items(11)",
    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" }, // <-- имя сущности
        "SingleTerm": {
            "__metadata": {
                "type": "SP.Taxonomy.TaxonomyFieldValue"
            },
            "TermGuid": "33899e31-576e-4254-a9cf-d53bac59935a", // <-- Term Id 
            "WssId": "-1" // <-- всегда указываем "-1" 
        }
    })
});

Delete

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

Метаданные (Таксономия) со множественным выбором

Создание

Работать с полем таксономии, в котором разрешен множественный выбор, надо совсем иначе. Здесь необходимо проделать несколько трюков.

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

$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/fields?$filter=InternalName eq 'MultiTerm&$select=TextField",
    type: "GET",
    headers: {
        "Content-Type": "application/json;odata=verbose"
    }
});

Мы получаем от SharePoint идентификатор скрытого поля:

<feed>
    <entry>
        <content type="application/xml">
            <m:properties>
                <d:TextField m:type="Edm.Guid">7ec65949-1ecc-4b04-9a0e-da6282cd747b</d:TextField>
            </m:properties>
        </content>
    </entry>
</feed>

Следующим шагом мы получаем имя (InternalName) этого скрытого поля:

$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/fields/getbyid(guid'7ec65949-1ecc-4b04-9a0e-da6282cd747b')?$select=InternalName",
    type: "GET",
    headers: {
        "Content-Type": "application/json;odata=verbose"
    }
});

Теперь у нас есть InternalName скрытого поля, которое мы будем использовать для обновления поля таксономии:

<entry>
    <content type="application/xml">
        <m:properties>
            <d:InternalName>j9e7c67e91e64e8a8c26e61ec1e4007b</d:InternalName>
        </m:properties>
    </content>
</entry>

Поле, которое надо использовать для обновления известно. Значение для него мы получаем путем конкатенации значений: -1;#|TERMGUID1;#-1;#|TERMGUID2:

$.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" }, // <-- имя сущности
        "j9e7c67e91e64e8a8c26e61ec1e4007b": "-1;#|d3ce8903-4b4e-442e-8f19-161bf45be9e8;#-1;#|33899e31-576e-4254-a9cf-d53bac59935a"
    })
});

Чтение

Чтение значения поля таксономии с помощью REST API:

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

Ответ содержит названия терминов (а не WssId как в случае с полем без множественного выбора):

<entry>
    <content type="application/xml">
        <m:properties>
            <d:MultiTerm m:type="Collection(SP.Taxonomy.TaxonomyFieldValue)">
                <d:element>
                    <d:Label>Demo</d:Label>
                    <d:TermGuid>d3ce8903-4b4e-442e-8f19-161bf45be9e8</d:TermGuid>
                    <d:WssId m:type="Edm.Int32">67</d:WssId>
                </d:element>
                <d:element>
                    <d:Label>Meeting</d:Label>
                    <d:TermGuid>33899e31-576e-4254-a9cf-d53bac59935a</d:TermGuid>
                    <d:WssId m:type="Edm.Int32">68</d:WssId>
                </d:element>
            </d:MultiTerm>
        </m:properties>
    </content>
</entry>

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

Обновление

Ровно как и создание:

$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items(10)",
    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" }, // <-- имя сущности
        "j9e7c67e91e64e8a8c26e61ec1e4007b": "-1;#|d3ce8903-4b4e-442e-8f19-161bf45be9e8"
    })
});

Удаление

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

Теги

Поделиться

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

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

Техлид, Архитектор, Разработчик, Microsoft MVP. Более 20 лет опыта в области системной интеграции и разработки программного обеспечения. Специализируюсь на проектировании и внедрении масштабируемых высокопроизводительных программных решений в различных отраслях.