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

Удаление

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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