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

16 июня 2016 г.

Создание простого REST-сервиса и регистрацией его в SharePoint 2013/2016.

SharePoint Custom REST API

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 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.

Поделиться

Комментарии