Веб-сервисы в наше время становятся очень популярными. И это понятно, они универсальны. На их основе можно написать кроссплатформенное мобильное приложение на HTML5, сделать гаджет для рабочего стола Windows 7 или просто вывести на сайт список последних новостей.
Я бы хотел продемонстрировать, как можно, совмещая современные технологии, такие как REST-сервис, OData и jQuery, работать с SharePoint 2010 через его стандартный RESTful интерфейс на примере создания небольшой веб-части для поиска и просмотра данных о сотрудниках компании. Главная особенность моего примера — это отсутствие server-side программирования.
SharePoint Foundation REST Interface
SharePoint Foundation REST Interface — это новый сервис, который появился в Microsoft SharePoint 2010.
Основная концепция этого веб-сервиса в том, что все списки и элементы SharePoint представлены в виде HTTP ресурсов и доступны удаленно по URL. Это полноценный RESTful сервис. Он имеет стандартный набор операций: чтение, запись, редактирование и удаление. Формат вывода данных возможен как XML, так и JSON. Веб-сервис поддерживает Open Data Protocol, о котором я расскажу чуть ниже.
За счет всех этих возможностей достигается высокая гибкость и совместимость веб-сервиса с любыми приложениями, которые умеют делать HTTP-запросы.
Мое знакомство с SharePoint Foundation REST Interface произошло относительно недавно, но сразу стало понятно, насколько удобно его использовать. Я пожалел, что не знал о нем раньше. Конечно, это не инструмент на все случаи жизни, но иногда он жизнь значительно упрощает.
SharePoint Foundation REST Interface доступен по ссылке:
http://{server_name}/_vti_bin/listdata.svc
Использовать его можно сразу после установки Microsoft SharePoint Foundation 2010. Он не требует никаких дополнительных настроек.
Зайдя по ссылке, вы увидите XML со всеми доступными списками и библиотеками в SharePoint, как стандартными, так и созданными администратором.Например, список пользователей доступен по URL:
http://{server_name}/_vti_bin/listdata.svc/UserInformationList
Open Data Protocol
Open Data Protocol – это открытый веб-протокол для запроса и обновления данных. Протокол позволяет выполнять операции с ресурсами, используя в качестве запросов HTTP-команды, и получать ответы в форматах JSON или XML.
Получив список пользователей от веб-сервиса, вы заметите, что он возвращает не только пользователей, но и группы. Они отличаются значением элемента ContentType. У пользователей ContentType имеет значение “Person”. Вот теперь, для того чтобы отфильтровать только пользователей, мы и воспользуемся возможностью веб-сервиса работать с OData. Нужно добавить в URI переменную $filter:
http://{server_name}/_vti_bin/listdata.svc/UserInformationList?$filter=ContentType eq 'Person'
В результате мы получим список всех пользователей.
Также в веб-части используется динамическая подстановка имени пользователя при вводе. Поэтому нужно искать включая имя пользователя и сортировать по нему. Усложним условие фильтрации:
http://{server_name}/_vti_bin/listdata.svc/UserInformationList?$filter=((ContentType eq 'Person') and (substringof(Name,'{query}')))&$orderby=Name
Теперь в результатах выборки присутствуют только пользователи, в имени которых встречается подстрока {query}.
Как вы увидите, веб-сервис возвращает много информации, которая не всегда нужна. Поэтому размер получаемого файла можно уменьшить, указав, какие именно поля мы хотим получить. Для этого нужно добавить переменную $select:
http://{server_name}/_vti_bin/listdata.svc/UserInformationList?$filter=((ContentType eq 'Person') and (substringof(Name,'{query}')))&$orderby=Name&$select=Id,Name,ContentType
Теперь получаемый файл содержит всего три поля, которые мы указали.
Ну вот, насчет гибкости я говорил не зря, запрос с параметрами OData может быть каким угодно сложным. Так, без каких-либо затрат можно получить данные с любого листа или библиотеки SharePoint, будь то новости, список документов или что-либо другое.
Как я говорил в самом начале, SharePoint Foundation REST Interface позволяет не только получать данные, но и добавлять, редактировать и удалять их. О том, как можно это сделать, и об остальных возможностях Open Data Protocol можно более детально почитать вот здесь:
http://www.odata.org/developers/protocols/operations
No C#, use jQuery
Перейдем к частному применению веб-сервиса. Построим на основе него небольшую веб-часть.
Схематически веб-часть будет выглядеть вот так:
Начальное состояние
Начинаем вводить имя пользователя
Пользователь выбран
Как говорилось ранее, на сервере мы ничего программировать не будем. Все переходит на клиентскую часть и будет выполняться с помощью jQuery и $.ajax(). Конечно, без создания проекта в студии и деплоймента не обойтись, но привлечение специализированного программиста не потребуется и можно справиться силами любого веб-разработчика.
Создаем проект веб-части и добавим в него все необходимые файлы:
Создаем веб-часть
Так выглядит структура проекта со всеми файлами
Теперь нужно подключить css и JavaScript файлы к ascx контролу. Открываем EmployeesWebPartUserControl.ascx и вставляем код:
// подключаем css для jQuery Autocomplete
<SharePoint:CssRegistration ID="jquery_autocomplete" Name="/_layouts/EmployeesWebPart/css/jquery.autocomplete.css" After="corev4.css" runat="server" />
// подключаем css файл, в котором описаны стили непосредственно для элементов веб-части
<SharePoint:CssRegistration ID="webpart_base" Name="/_layouts/EmployeesWebPart/css/webpart.css" After="corev4.css" runat="server" />
// подключаем javascripts
<script src="/_layouts/EmployeesWebPart/js/webpart.include.js" type="text/javascript"></script>
В этот же файл вставляем HTML-код веб-части:
<div><input type="search" name="wpuser_search" id="wpuser_search" placeholder="Search users as you type..." /></div>
<div>
<div>
<div id="wpuser_image"><img src="" /></div>
<div>
<div id="wpuser_name"></div>
<div id="wpuser_position"></div>
<div id="wpuser_departament"></div>
<div id="wpuser_status"></div>
</div>
</div>
<div>
<div>Ask me about:</div>
<div id="wpuser_asklist"></div>
<ul>
<li id="wpuser_phone"><span>Mobile:</span> <a href=""></a></li>
<li id="wpuser_email"><span>Email:</span> <a href=""></a></li>
</ul>
</div>
</div>
Это, можно сказать, шаблон нашей веб-части. В пустые div-ы с помощью jQuery мы будем вписывать значения, полученные через $.ajax();
Собственно, с приготовлениями закончили, теперь можно перейти к написанию самого кода.
Способ получения списка пользователей простой и понятный:
// URL веб-сервиса с нужными переметрами
var serviceUrl = "/_vti_bin/listdata.svc/UserInformationList?$filter=ContentType eq 'Person'&$orderby=Name";
// выполняем запрос
$.ajax({
'type': 'GET',
'url': serviceUrl,
'dataType': 'json',
'success': function(data){ userSearch(data['d']['results']); }
});
Не забываем добавить параметр:
'dataType': 'json'
Без него веб-сервис вернет XML вместо JSON.
На самом деле, я немного схитрил и использовал готовый плагин jQuery Autocomplete
Этот плагин может принимать значения не только в виде готового массива элементов, но также может сам обрабатывать URL сервиса, который возвращает JSON. К сожалению, я не смог заставить его работать напрямую с веб-сервисом SharePoint. Плагин выдавал какую-то ошибку при разборе полученных данных, а мне лень было разбираться, в чем проблема. Кроме того, мне показалось лучшим подгрузить сразу весь список пользователей, а не ждать ответа от сервера после каждой введенной буквы. Да и частые запросы к серверу ни к чему. Поэтому мое решение имело такой вид:
function userSearch(data){
$field = $("#wpuser_search"); // поле с автоподстановкой
$field.autocomplete(data, {
formatItem: function (item) { return item.Name },
matchContains: true
});
$field.result(function (event, data, formatted) { userShowInfo(data); });
}
Поле с автоподстановкой имени пользователя готово. Осталось показать остальную информацию о пользователе:
function showUserInfo(data) {
// name
$("#wpuser_name").text(data.Name);
// email
$("#wpuser_email a").text(data.WorkEMail).attr('href', 'mailto:' + data.WorkEMail);
// phone
$("#wpuser_phone a").text(data.MobilePhone).attr('href', 'callto:' + data.MobilePhone);
// departament
$("#wpuser_departament").text(data.Department);
// picture
$("#wpuser_image img").attr('src', data.Picture.split(", ")[0]);
// position
$("#wpuser_position").text(data.Title);
// ask me abolut list
$("#wpuser_asklist").text(data.AskMeAbout);
}
Функция заполнит наш шаблон данными с веб-сервиса.
Вот и все. Как и обещал, в процессе разработки не было использовано никакого server-side программирования. Я упростил код для того, чтобы сделать его максимально коротким и понятным. Сходу скажу, что нужно еще учитывать путь к коллекции сайта и путь к подсайту, где лежит страница с веб-частью. Это нужно для того, чтобы сформировать путь к веб-сервису именно с той же коллекции и того же подсайта.
Надеюсь, знакомство с SharePoint Foundation REST Interface было приятным, и вы сможете его правильно применить в своих проектах. Желаю удачи!
Весь проект можно скачать здесь:
SVN http://users-list-webpart.googlecode.com/svn/trunk/
Дополнительные ссылки:
- Microsoft SharePoint 2010: sharepoint.microsoft.com
- SharePoint Foundation REST Interface: msdn.microsoft.com/en-us/library/ff521587.aspx
- Open Data Protocol: odata.org
- Что такое RESTful-сервис: ru.wikipedia.org/wiki/REST
- jQuery asynchronous HTTP (Ajax) request: api.jquery.com/jQuery.ajax