SharePoint. Расширяем REST API
Создание простого REST-сервиса и регистрацией его в SharePoint 2013/2016.
REST API
SharePoint предоставляет большой набор REST-сервисов из коробки, которые облегчают создание решений на их основе.
Например следующий GET-запрос к приложению SharePoint, расположенному по адресу http://portal:
http://portal**/_api/Web/GetFolderByServerRelativeUrl('/')**
Вернет информацию о корневой папке сайта (XML представлен неполностью):
<?xml version="1.0" encoding="utf-8"?>
<entry>
<id>Web/GetFolderByServerRelativeUrl('/')</id>
<category term="SP.Folder" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<title />
<updated>2016-06-11T15:56:51Z</updated>
<author>
<name />
</author>
<content type="application/xml">
<m:properties>
<d:ItemCount m:type="Edm.Int32">0</d:ItemCount>
<d:Name></d:Name>
<d:ServerRelativeUrl>/</d:ServerRelativeUrl>
<d:WelcomePage>Lists/MyList/DispForm.aspx?ID=1#hash</d:WelcomePage>
</m:properties>
</content>
</entry>
Получать данные можно и в формате JSON. Для этого необходимо добавить в заголовок запроса ключ Accept, равный application/json;odata=verbose. И результат будет следующий (JSON неполностью):
{
"d": {
"ItemCount": 0,
"Name": "",
"ServerRelativeUrl": "/",
"WelcomePage": "Lists/MyList/DispForm.aspx?ID=1#hash"
}
}
Странное на первый взгляд значения свойства WelcomePage - артефакт от поста о домашней странице.
SharePoint позволяет не только использовать REST API из коробки, но и создавать свои собственные REST-сервисы. В качестве примера я покажу как реализовать свой сервис и опубликовать его в SharePoint.
Публикация сервиса
Информация о сервисах SharePoint публикуется в виде XML-файлов в папке C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\CONFIG\ClientCallable:
Каждый XML-файл содержит лишь информацию о сборке. Например, сервис для поиска описан в виде XML-файла ProxyLibrary.SearchApp.xml:
<?xml version="1.0"?>
<ClientCallableProxyLibrary>
<AssemblyName SupportAppAuth="true">
Microsoft.Office.Server.Search.Applications.ServerProxy, Version=15.0.0.0,
Culture=neutral, PublicKeyToken=71e9bce111e9429c
</AssemblyName>
</ClientCallableProxyLibrary>
Теперь переходим непосредственно к созданию сервиса.
Создание REST-сервиса
Шаг 1. Создаем проект
Создаем новый проект на основе шаблона SharePoint 2013 - Empty Project:
Указываем тип решения Farm solution.
Шаг 2. Создаем XML-описание сервиса
Добавляем в проект папку, сопоставленную с упомянутой выше ClientCallable:
Создаем в этой папке файл ProxyLibrary.Zhukov.xml со следующим содержимым (полное имя сборки):
<ClientCallableProxyLibrary>
<AssemblyName SupportAppAuth="true">
VitalyZhukov.Blog.SP.CustomRestApi, Version=1.0.0.0, Culture=neutral, PublicKeyToken=423eec37c6ffe594
</AssemblyName>
</ClientCallableProxyLibrary>
Шаг 3. Создаем сервис
Демонстрационный сервис будет содержать один метод и одно свойство:
using Microsoft.SharePoint.Client;
namespace Zhukov.Blog.SP.REST
{
[ClientCallableType(
Name = "CustomService",
ServerTypeId = "{7954fe10-6ba6-4cc0-9fcf-e23a04816790}")]
public class CustomService
{
[ClientCallableMethod]
public string GetString()
{
return "Hello, world!";
}
[ClientCallableProperty]
public string About => "Simple REST service";
}
}
Всё просто: класс сервиса должен быть помечен атрибутом ClientCallableType, методы - атрибутом ClientCallableMethod, свойства - ClientCallableProperty.
Шаг 4. Создаем прокси для сервиса
Теперь для сервиса необходимо создать заглушку, которая опишет доступные свойства и методы. Также она будет использоваться для их вызова. Частично код такой заглушки касаемо только свойств сервиса:
using System;
using System.Collections.Generic;
using Microsoft.SharePoint.Client;
namespace Zhukov.Blog.SP.REST
{
[ServerStub(
typeof(CustomService),
TargetTypeId = "{7954fe10-6ba6-4cc0-9fcf-e23a04816790}")]
public class CustomServerStub : ServerStub
{
protected override Type TargetType => typeof(CustomService);
protected override Guid TargetTypeId => new Guid("{7954fe10-6ba6-4cc0-9fcf-e23a04816790}");
protected override string TargetTypeScriptClientFullName => "SP.Zhukov";
protected override ClientLibraryTargets ClientLibraryTargets => ClientLibraryTargets.All;
protected override object GetProperty(object target, string propName, ProxyContext proxyContext)
{
propName = GetMemberName(propName, proxyContext);
switch (propName)
{
case "About":
CheckBlockedGetProperty("About", proxyContext);
return ((CustomService)target).About;
}
return base.GetProperty(target, propName, proxyContext);
}
protected override IEnumerable<PropertyInformation> GetProperties(ProxyContext proxyContext)
{
var propAbout = new PropertyInformation
{
Name = "About",
IsStatic = false,
PropertyODataType = ODataType.Primitive,
ExcludeFromDefaultRetrieval = false,
PropertyType = typeof(string),
ReadOnly = false,
RequiredForHttpPutRequest = true,
DefaultValue = false,
OriginalName = "About",
RESTfulPropertyType = null,
RequiredRight = ResourceRight.Default
};
yield return propAbout;
}
}
}
Метод GetProperties возвращает коллекцию PropertyInformation, метод GetProperty используется для обращения к свойствам.
Шаг 5. Описываем сервис
SharePoint из файла узнает о наличие сборки, которую необходимо использовать для REST API сервиса. Чтобы SharePoint понимал как именно работает REST-сервис, его необходимо описать в атрибутах сборки. Для этого открываем файл AssemblyInfo.cs. Добавляем атрибут UrlSegmentAliasMap:
[assembly: UrlSegmentAliasMap("zhukov", "SP.Zhukov", ResourceType = typeof(CustomService))]
Готово. Пять простых шагов и мы имеем решение уровня фермы, расширяющее REST API SharePoint. После развертывания этого решения наш сервис будет зарегистрирован и информацию о нём можно посмотреть при обращении к URL вида http://portal/_api/$metadata:
Теперь попробуем обратиться к созданному сервису через SharePoint.
Тест
Простой GET-запрос к URL вида для вызова метода GetString нашего сервиса:
http://portal/_api/**zhukov/getstring**
И результат в браузере:
Исходные коды
Исходные коды доступны на code.msdn.microsoft.com: https://code.msdn.microsoft.com/SharePoint-REST-API-04182068.