Миллионы людей пользуются клиентскими приложениями Microsoft Office в повседневной работе для коммуникаций, анализа данных, перемалывания чисел, создания документов и презентаций и принимают бизнес-решения. И все чаще применяют Microsoft SharePoint как портал для коллективной работы и как платформу для доступа к общим данным и сервисам.
Некоторые корпоративные разработчики еще не задействовали возможности встраивания собственной функциональности в приложения Office, которая может обеспечить бесшовный прямой доступ к данным SharePoint из привычных пользователям офисных приложений. Для предприятий, ищущих способы повысить производительность труда конечных пользователей, возможность прямого доступа к данным SharePoint из приложений Office — важный вариант, который им стоит принять во внимание.
После выпуска SharePoint 2010 появился целый ряд новых способов доступа к данным SharePoint и их представления пользователям Office. Они варьируются от решений, практически обходящихся без написания кода (это стало возможным благодаря SharePoint Workspace 2010, ранее известным под кодовым названием Groove), прямой синхронизации между SharePoint и Outlook, до нового SharePoint REST API и новой клиентской объектной модели. Кроме того, как и в Microsoft Office SharePoint Server (MOSS) 2007, в SharePoint 2010 доступен широкий набор веб-сервисов.
В этой статье мы опишем несколько решений, обходящихся без написания дополнительного кода, и покажем, как создавать немного более сложные решения, используя новые средства SharePoint 2010.
Внешние источники данных
Начнем с краткого обзора типов списков SharePoint, которые можно применять как источники данных.
Один из особенно полезных источников данных — внешний список, где отображаются данные, полученные по соединению со специализированной бизнес-системой (line-of-business, LOB). MOSS 2007 позволяет подключаться к LOB-данным через Business Data Catalog (BDC), который обеспечивает доступ только для чтения к внутренним системам (back-end systems). SharePoint 2010 предоставляет службу Business Connectivity Services (BCS) — эволюционное развитие BDC с поддержкой полного доступа (для чтения и записи) к вашим LOB-данным.
А зачем вообще передавать LOB-данные в SharePoint? Допустим, у вас есть система управления связями с клиентами (customer relationship management, CRM), к которой напрямую может обращаться лишь ограниченный круг лиц в организации. Однако в базе данных есть таблица клиентов с именами и адресами, которыми могли бы пользоваться многие другие сотрудники, если бы такие данные были им доступны. На практике все, вероятно, кончилось бы тем, что пользователи копировали бы эту информацию из различных непроверенных источников и вставляли бы ее в свои документы Office. Было бы куда лучше, чтобы эти данные о клиентах были доступны из проверенной CRM-системы и предоставлялись в SharePoint как внешний список, к которому могут обращаться клиенты Office.
SharePoint Designer 2010 — инструмент, применяемый для настройки доступа к LOB-системе и позволяющий сделать ее данные доступными во внешнем списке SharePoint. Для этого нужно выполнить несколько операций.
Первым делом надо создать новый External Content Type (ECT). ECT содержит метаданные, описывающие структуру внутренних данных, например поля и CRUD-методы, которые будут использоваться SharePoint для взаимодействия с ними. После этого на основе ECT можно сгенерировать внешний список на любом сайте (узле) в рамках SharePoint. Внешние списки выглядят и работают, как и любые другие стандартные списки в SharePoint, но данные внешнего списка не хранятся в SharePoint. Вместо этого они извлекаются через ECT, когда к ним обращается конечный пользователь.
SharePoint Designer включает по умолчанию поддержку подключения к внешним источникам данных, в том числе к SQL Server, Windows Communication Foundation (WCF) и Microsoft .NET Framework. Так что вы можете легко создать ECT для соединения с любой таблицей или представлением базы данных SQL Server, WCF- или веб-сервисом. Собственные .NET-решения можно создавать в Visual Studio 2010, используя новый шаблон проектов SharePoint 2010 Business Data Connectivity Model.
Для наших целей мы восполизовались типом источника данных SQL Server для создания ECT, чтобы подключаться к таблице базы данных. Затем с помощью ECT создали внешний список (External List). ECT под именем «Customers From CRM», полученный после заполнения конфигурации в SharePoint Designer, показан на рис. 1.
Рис. 1. Конфигурация ECT для доступа к внешним данным CRM
Здесь стоит обратить внимание на пару вещей. Во-первых, на панели External Content Type Information значение свойства Office Item Type установлено в Contact. В процессе настройки вы можете сопоставить поля внешних данных соответствующему типу элемента Office вроде Contact. Это не является обязательным требованием, но, поскольку данные об именах и адресах из базы данных CRM можно корректно сопоставить с Outlook Contact, мы выбрали такой вариант. Результат данного параметра конфигурации можно использовать в программе Outlook позднее.
Во-вторых, на панели External Content Type Operations для этого ECT разрешены все CRUD-методы. Соответствующий выбор был сделан в мастере настройки. Однако в зависимости от конкретного бизнеса операции с LOB-системой могут быть ограничены только чтением. В таком случае вы просто выбираете при настройке операции Read List и Read Item. Для создания ECT требуются лишь эти две операции.
После создания ECT вы можете легко создать новый внешний список в SharePoint или SharePoint Designer.
Стандартные списки SharePoint
Конечно, для отображения бизнес-данных можно применять стандартные списки SharePoint. Например, ваш отдел управляет обучающими материалами. Вы поддерживаете два списка SharePoint: Course Category и Course. Эти списки содержат информацию, которую сотрудники из других групп используют в переписке с клиентами, для написания брошюр или проведения рекламных кампаний. Таким образом, данные поддерживаются небольшой группой, но должны быть доступны многим лицам в компании.
В SharePoint 2010 имеется новый механизм, благодаря которому между списками можно формировать связи. При создании нового столбца в списке вы можете сделать этот столбец подстановочным (lookup), и тогда он будет указывать на другой список в рамках данного сайта как на источник своих данных. SharePoint поддерживает подстановки с единственным значением (single-value lookups) для отношений «один ко многим» или подстановки с несколькими значениями (multi-value lookups) для отношений «многие ко многим». Если вы выберете это, SharePoint будет также обеспечивать ссылочную целостность между списками, которые поддерживают ограниченные или каскадные операции удаления. Это дает вам целый набор вариантов настройки и использования списков в SharePoint.
Но вернемся к нашему примеру. Вы могли бы легко создать в списке Course подстановочный столбец с именем Category, источником данных для которого служил бы список Course Category, как показано на рис. 2.
Рис. 2. Использование списка Course для получения данных из списка Course Category
Передача данных из списков SharePoint в Office
До сих пор мы обсуждали, как сделать доступными внешние данные в виде списков SharePoint, используя новую службу BCS в SharePoint 2010. Пользователи могут обращаться к данным через браузер с ПК или мобильного устройства, но скорее всего они предпочтут богатую функциональность полноценных клиентских приложений Office. Давайте теперь переключимся на то, как использовать данные списков SharePoint на клиентской стороне. Это можно делать двумя способами. Сначала мы посмотрим, как обращаться к данным без написания какого-либо кода, просто применяя SharePoint Workspace и Outlook.
При разработке нашего решения-примера с CRM мы имеем на ленте SharePoint две кнопки в разделе Connect & Export для внешних списков с информацией о клиентах: Sync to SharePoint Workspace и Connect to Outlook (рис. 3). Если на клиентском компьютере установлен SharePoint Workspace 2010, Sync to SharePoint Workspace позволит синхронизировать списки и библиотеки документов с клиентом одним щелчком кнопки мыши. После этого пользователю в SharePoint Workspace — независимо от того, подключен он к сети или работает в автономном режиме, — будет доступна локальная кешированная копия содержимого. Если пользователь находится в автономном режиме и изменяет какой-либо элемент списка или документ, а затем сохраняет его локально, то этот элемент списка или документ будет синхронизирован с SharePoint автоматически, как только пользователь снова подключится к сети.
Рис. 3. Варианты в разделе Connect & Export на ленте SharePoint
Это решение не требует никакого кода. Данные становятся доступными в клиентском приложении SharePoint Workspace (рис. 4). А поскольку в ECT были определены все CRUD-методы, любые изменения, внесенные в данные о клиентах в SharePoint Workspace, будут обновлены и в базе данных CRM.
Рис. 4. Доступ к данным внешнего списка в SharePoint Workspace
Так как мы сопоставили поля базы данных CRM типу элемента Contact Office при настройке ECT, SharePoint может предоставлять наши данные внешнего списка программе Outlook как «родные» элементы Contact. Щелкнув кнопку Connect to Outlook на ленте, вы заставите SharePoint синхронизировать этот внешний список напрямую с Outlook. И вновь не требуется никакого кода.
Применение REST API
Решения без кода вроде тех, которые поддерживаются через SharePoint Workspaces и средства Outlook для подключения к спискам, — штука отличная, но нередко требуется решение посложнее и с более широкими возможностями в настройке. Для этого доступ к данным списков надо предоставлять в приложениях Office так, чтобы у нас была возможность дальнейшей адаптации решения.
Вероятно, один из простейших для разработчика способов обеспечить доступ к данным списков и библиотек документов SharePoint — задействовать новый REST API (listdata.svc). Большая часть данных в SharePoint предоставляется как конечная точка RESTful. Стандартное месторасположение сервисов SharePoint — _vti_bin, поэтому, если вы просто введете в браузере URL к своему сайту и дополните его строкой «/_vti_bin.listdata.svc», то получите стандартный документ ATOM-сервисов, который описывает наборы, доступные на сайте (рис. 5).
Рис. 5. Документ ATOM-сервисов
Обратите внимание на присутствие списков Course и CourseCategory. Добавив к URL еще и /Course, вы сможете получить все обучающие курсы из списка или извлечь любой конкретный курс, дописав его номер. Например, этот URL позволит получить третий курс:
http://intranet.contoso.com/sites/SPC/_vti_bin/listdata.svc/Course(3)
Вы можете составлять более сложные запросы, добавив следующий фильтр свойства (property filter):
?$filter=startswith(propertyname,'value')
Но в данном случае важен запрос, который возвращает курсы вместе с сопоставленными им данными CourseCategory. Добавив следующий текст к URL сайта, вы можете получить комбинированную структуру Course и CourseCategory в одном блоке полезных данных:
/_vti_bin.listdata.svc/Course?$expand=Category
Вы увидите соответствующую реализацию в надстройке для Word, о которой пойдет речь в следующем разделе.
Создание надстройки для Word
Теперь, зная, как использовать REST API для запроса доступа к данным, вы можете предоставлять эти данные в клиентских приложениях. Для этого примера мы создадим надстройку Word, которая будет представлять данные в UI. В этом приложении будут: раскрывающийся список для категорий курсов, окно списка с перечнем курсов, соответствующих выбранной категории, и кнопка для вставки текста о курсе в документ Word.
В Visual Studio 2010 создайте проект надстройки Office 2010 Word на C#.
Теперь добавьте новый сервис — источник данных. На панели Add Service Reference в мастере введите URL к своему сайту SharePoint и добавьте «/_vti_bin/listdata.svc», например:
http://intranet.contoso.com/_vti_bin/listdata.svc
После ввода URL щелкните Go. Это приведет к считыванию метаданных для сайта SharePoint. Когда вы щелкнете OK, служба WCF Data Services создаст за вас строго типизированные классы, используя Entity Framework. Благодаря этому вы полностью абстрагируетесь от того, что источником данных служит SharePoint или какой-то провайдер OData, предоставляющий данные по протоколу Open Data Protocol. С этого момента вы просто работаете с данными как с привычными .NET-классами.
Затем создайте собственную область задач (task pane), которая будет служить в качестве UI для приложений Office; эту область можно стыковать с верхней, нижней, левой или правой границей окна приложения. В области задач можно добавлять элементы управления Windows Forms, в том числе пользовательский элемент управления Windows Presentation Foundation (WPF), которым мы и воспользуемся здесь.
Добавьте пользовательский элемент управления WPF в проект с помощью диалога Add New Item и присвойте ему имя CoursePicker. Когда откроется окно дизайнера, замените элемент Grid фрагментом XAML, показанным на рис. 6. Это просто приведет к появлению элементов управления ComboBox, Button и ListBox, а также к установке некоторых свойств. Позднее вы добавите несколько событий.
Рис. 6. Разметка UI для надстройки Word
<StackPanel>
<ComboBox
Name="cboCategoryLookup" Width="180" Margin="5"
HorizontalAlignment="Center" IsEditable="False"
ItemsSource="{Binding}"
DisplayMemberPath="CategoryName"
SelectedValuePath="CategoryName" />
<Button Name="button1"
Content="Insert Course Information" Margin="5" />
<ListBox Name="courseListBox" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=CourseID}"
FontWeight="Bold" />
<TextBlock Text=": " FontWeight="Bold" />
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
<TextBlock Text="{Binding Path=Description}"
Margin="5 0 0 0" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
Откройте файл CoursePicker.xaml.cs. Вставьте в пространство имен Conf_DS два выражения using (одно для ссылки на ваш сервис ServiceReference1, а другое для использования System.Net):
namespace Conf_DS {
using ServiceReference1;
using System.Net;
В классе CoursePicker первым делом надо создать экземпляр объекта контекста данных. Здесь вы передаете URL своего сайта, вновь дополняя его строкой «_vti_bin/listdata.svc»:
public partial class CoursePicker : UserControl {
Office2010DemoDataContext dc = new Office2010DemoDataContext(
new Uri("http://intranet.contoso.com/sites/spc/_vti_bin/listdata.svc"));
Затем вам понадобится переменная типа List уровня класса для кеширования извлеченных названий курсов, что позволит уменьшить частоту обмена данными с сервером:
List<CourseItem> courses = null;
Код для получения данных Courses и CourseCategory находится в переопределенном методе OnInitialized. Сначала вы указываете свои удостоверения для передачи серверу. Затем категории курсов считываются через объект контекста данных и связываются с ComboBox, где отображается список категорий. Наконец, при раскрытии списка возвращаются названия курсов, сопоставленные с конкретной категорией, и загружаются в объект списка курсов. Это приводит к локальному кешированию названий курсов для большей производительности:
protected override void OnInitialized(EventArgs e) {
dc.Credentials = CredentialCache.
DefaultCredentials;
// Load Category dropdown list
cboCategoryLookup.DataContext =
dc.CourseCategory;
cboCategoryLookup.SelectedIndex = 0;
// To cache data locally for courses
// Expand to retrieve the Category as well.
courses = dc.Course.Expand("Category").ToList();
base.OnInitialized(e);
}
Теперь нужно добавить пару обработчиков событий. Вернитесь в дизайнер CoursePicker и дважды щелкните кнопку, чтобы создать обработчик события click для этой кнопки. Затем щелкните ComboBox, в меню свойств выберите вкладку Events и дважды щелкните событие SelectionChanged. Добавьте код к обработчику события SelectionChanged:
private void cboCategoryLookup_SelectionChanged(
object sender, SelectionChangedEventArgs e) {
courseListBox.DataContext = from c in courses
where c.Category.CategoryName == cboCategoryLookup.SelectedValue.ToString()
orderby c.CourseID
select c;
}
Здесь простой LINQ-запрос просматривает объект списка с курсами (тот, что был загружен данными, извлеченными при нажатии кнопки раскрытия списка), чтобы найти все курсы с названием категории, совпадающим с выбранным в ComboBox. Он также упорядочивает результаты для удобства пользователя.
Наконец, добавьте в обработчик событий кнопки код для приведения выбранного элемента в окне списка к объекту CourseItem. Затем вы берете различные элементы данных, которые нужно представить пользователю, и помещаете их в документ в текущую позицию вставки:
private void button1_Click(
object sender, RoutedEventArgs e) {
CourseItem course = (CourseItem)courseListBox.SelectedItem;
Globals.ThisAddIn.Application.Selection.InsertAfter(
String.Format("{0}: {1} \n{2}\n", course.CourseID,
course.Name, course.Description));
}
Вот и все — действительно простой код для доступа к данным в SharePoint через WCF Data Services.
Теперь откройте файл ThisAddIn.cs. Это основная точка входа для всех надстроек Office. Здесь добавьте код для создания экземпляра области задач:
private void ThisAddIn_Startup(object sender, System.EventArgs e) {
UserControl wpfHost = new UserControl();
ElementHost host = new ElementHost();
host.Dock = DockStyle.Fill;
host.Child = new CoursePicker();
wpfHost.Controls.Add(host);
CustomTaskPanes.Add(wpfHost, "Training Courses").Visible = true;
}
Пользовательский WPF-элемент управления CoursePicker нельзя напрямую добавить к набору объектов собственной области задач. Его нужно разместить в элементе управления ElementHost, который служит мостиком между элементами управления WPF и Windows Forms. Заметьте, что объект CoursePicker добавлен как дочерний по отношению к объекту ElementHost, а затем тот в свою очередь добавлен к набору объектов собственной области задач. В приложении Office может быть установлено более одной собственной области задач, и они могут быть доступны пользователю в любой момент, поэтому область задач для этой надстройки будет лишь одной из таковых в наборе. Законченная надстройка показана на рис. 7.
Рис. 7. Надстройка Word в действии
Теперь после того, как данные появляются в приложении Office, вы можете расширить свое решение, добавив код, который взаимодействует с Word API. Например, вы можете сделать так, чтобы после выбора курса пользователем соответствующая информация вставлялась в документ и форматировалась в нем. API-интерфейсы приложений Office отличаются богатой функциональностью и позволяют включать в решения дополнительные средства для повышения производительности труда пользователей. Далее мы рассмотрим пример такого рода, в котором элементы управления содержимым Word подключаются к объектной модели SharePoint на клиентской стороне.
Использование клиентской объектной модели
Применение REST API для доступа к данным — один из нескольких возможных вариантов. Например, в SharePoint 2010 есть еще три новых API, которые предоставляют единую модель программирования для JavaScript, управляемых .NET-приложений и клиентов Silverlight. Эти три клиентские объектные модели взаимодействуют с SharePoint, используя подмножество серверной объектной модели и, по сути, работают с SharePoint на уровне набора сайтов (узлов) и ниже: веб-фрагментов (webs), списков, элементов списков, типов контента, полей и внешних списков. Если вы знакомы с серверной объектной моделью, то считайте, что знакомы и с клиентской объектной моделью.
Чтобы продемонстрировать применение клиентской объектной модели, мы возьмем внешний список с информацией о клиентах из CRM и создадим надстройку Word уровня документа, где вместе с данными о клиентах загружается панель действий (action pane). Это как раз тот случай, когда нужно пользоваться клиентской объектной моделью из-за того, что List Data Service не предоставляет доступа к внешним спискам. В данном примере пользователь может выбрать клиента и вставить его имя и адрес в элементы управления контентом в шаблоне справочного документа (quote document).
Предыдущий пример Course and Category был надстройкой уровня приложения. Такая надстройка запускается при каждом запуске Word. Однако надстройки уровня документов связаны с конкретным типом документов и загружаются лишь при открытии документа этого типа. В нашем случае внешний список клиентов будет появляться только при работе со справочным документом.
В Visual Studio начните с создания проекта документа Word 2010. В мастере вам понадобится выбрать либо документ по умолчанию (default document), либо документ, который вы уже сохранили. Здесь мы используем сохраненный справочный документ. Этот документ открывается в Visual Studio, и Word становится дизайнером документа.
Элементы управления из окна инструментария можно напрямую помещать на область документа — точно так же, как при создании приложения Windows Forms. Здесь вы добавляете элементы управления контентом Word для хранения информации об именах и адресах. Эти элементы будут заполняться данными в соответствии с выбором пользователя в период выполнения.
Чтобы добавить элемент управления контентом в документ, выделите текст в документе, который вы хотите заключить в этот элемент. Затем перетащите RichTextContentControl из Word Controls в окне инструментария на выделенный текст. Далее заполните значения свойств Name и Text элемента управления в окне Properties. Делайте так для имени клиента и названия компании, адреса, города и идентификатора клиента, чтобы ваш документ выглядел как на рис. 8.
Рис. 8. Создание справочного документа
Поскольку клиентская объектная модель не обеспечивает строгой типизации данных, получаемых с сервера, вам нужно добавить в проект класс Customer. Этот класс будет использоваться для преобразования данных, возвращаемых клиентской объектной моделью:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CSOM_Quote {
public class Customer {
public string CustomerID { get; set; }
public string CompanyName { get; set; }
public string ContactName { get; set; }
public string Address { get; set; }
public string City { get; set; }
}
}
Чтобы задействовать клиентскую объектную модель, нужны ссылки на Microsoft.SharePoint.Client и Microsoft.SharePoint.Client.Runtime.
Как и в предыдущем примере, выборка данных происходит в переопределенном методе OnIntitialized. Однако в кодировании с использованием клиентской объектой модели и WCF Data Services есть пара существенных различий. Во-первых, клиентская объектная модель требует знания SharePoint и его структуры, а WCF Data Services абстрагирует вас от этого, и вы имеете дело только с данными. Во-вторых, в клиентской объектной модели возвращаемые данные не являются строго типизированными. Ответственность за запись данных в объекты, применяемые для LINQ-запросов и связывания с данными, возлагается исключительно на вас.
Код для доступа к данным показан на рис. 9. Здесь центральным объектом является клиентский контекст. Для создания нового экземпляра клиентского клиента надо передать URL сайта. Затем вы можете начать создавать объекты SharePoint по следующей схеме.
- Создайте сайт (узел).
- Создайте набор списков сайта.
- Получите список с указанным именем.
- Получите все элементы из этого списка.
- Загрузите запрос в контекст.
- Выполните запрос.
Рис. 9. Код надстройки CRM для доступа к данным
protected override void OnInitialized(EventArgs e) {
SPClientOM.ClientContext context = new ClientContext("http://intranet.contoso.com/sites/spc");
SPClientOM.Web site = context.Web;
SPClientOM.ListCollection lists = site.Lists;
var theBCSList = lists.GetByTitle("Customers");
SPClientOM.CamlQuery cq = new SPClientOM.CamlQuery();
IQueryable<SPClientOM.ListItem> bcsListItems = theBCSList.GetItems(cq);
bcsList = context.LoadQuery(bcsListItems);
context.ExecuteQuery();
var bcsCustomerData =
from cust in bcsList
select new Customer {
CustomerID = cust.FieldValues.ElementAt(1).Value.ToString(),
ContactName = cust.FieldValues.ElementAt(2).Value.ToString()
+ " "
+ cust.FieldValues.ElementAt(3).Value.ToString(),
CompanyName = cust.FieldValues.ElementAt(4).Value.ToString(),
Address = cust.FieldValues.ElementAt(5).Value.ToString(),
City = cust.FieldValues.ElementAt(6).Value.ToString(), };
foreach (var x in bcsCustomerData) {
Customer tempCustomer = new Customer();
tempCustomer.CustomerID = x.CustomerID;
tempCustomer.CompanyName = x.CompanyName;
tempCustomer.ContactName = x.ContactName;
tempCustomer.Address = x.Address;
tempCustomer.City = x.City;
customers.Add(tempCustomer);
}
customerListBox.DataContext = customers;
base.OnInitialized(e);
}
До вызова метода ExecuteQuery все предыдущие выражения помещаются в очередь и лишь после этого посылаются на сервер вызовом ExecuteQuery. Тем самым вы получаете контроль над полосой пропускания и полезной нагрузкой. Как только запрос возвращает свои результаты, остальной код преобразует эти данные в объект списка клиентов, который может быть связан с элементом управления «окно списка клиентов».
В этом примере также применяется пользовательский элемент управления WPF. Поскольку XAML аналогичен предыдущему примеру, он здесь не показан. Однако код для создания экземпляра панели действий уровня документа отличается от такового для области задач уровня приложения:
public partial class ThisDocument {
private CustomersCRM CustomerActionPane = new CustomersCRM();
private void ThisDocument_Startup(object sender, System.EventArgs e) {
ElementHost host = new ElementHost();
host.Dock = DockStyle.Fill;
host.Child = new CustomerPicker();
CustomerActionPane.Controls.Add(host);
this.ActionsPane.Controls.Add(CustomerActionPane);
}
...
Заметьте, что WPF-элемент для выбора клиентов добавляется в ElementHost, а объект ElementHost включается в набор элементов управления панели действий для клиентов, после чего панель действий для клиентов вносится в набор элементов управления панели действий.
Последний шаг — добавление обработчика события щелчка кнопки для заполнения элементов управления контентом Word соответствующей информацией об именах и адресах (рис. 10).
Рис. 10. Добавление обработчика события щелчка кнопки к элементам управления контентом Word
private void button1_Click(
object sender, RoutedEventArgs e) {
Customer customer = (Customer)customerListBox.SelectedItem;
Globals.ThisDocument.wccContactName.Text = customer.ContactName;
Globals.ThisDocument.wccCompanyName.Text = customer.CompanyName;
Globals.ThisDocument.wccAddress.Text = customer.Address;
Globals.ThisDocument.wccCity.Text = customer.City;
Globals.ThisDocument.wccCustomerID.Text = customer.CustomerID;
}
Сначала вы преобразуете выбранный элемент в окне списка в объект клиента. Затем данные из этого объекта передаются в элементы управления контентом. Результат показан на рис. 11.
Рис. 11. Надстройка CRM в Word
Веб-сервисы как социальные сервисы
Вы уже увидели несколько способов доступа к данным SharePoint из клиентских приложений Office. Последний способ, который мы хотим обсудить, — применение веб-сервисов. SharePoint предлагает веб-сервисы как основной способ удаленного доступа к своим данным. Веб-сервисы в SharePoint 2010 обеспечивают доступ почти ко всей функциональности SharePoint Server. В отличие от некоторых других технологий доступа к данным, которые вы уже видели, например REST и клиентской объектной модели, веб-сервисы поддерживают доступ как к данным, так и к функциональности администрирования.
Все ваши любимые веб-сервисы по-прежнему на месте, в том числе Lists.asmx и Search.asmx. Веб-сервисы SharePoint реализуются на основе ASP.NET с расширением .asmx, а большая часть новых сервисов в SharePoint 2010 также написана как ASMX-сервисы. Это было сделано главным образом для большей совместимости с другими продуктами и инструментами.
Новый фокус внимания в веб-сервисах SharePoint — социальные сервисы. В центре всех социальных приложений находится пользователь. В SharePoint имеется UserProfileService, позволяющий обращаться ко всей информации о профиле конкретного пользователя. UserProfileService включает стандартные свойства вроде имени и адреса, но содержит и другие свойства, такие как хобби, профессии, учебные заведения и коллеги. Коллеги (или друзья, как они называются на других социальных сайтах) — ключевое средство в структуре SharePoint, обеспечивающей поддержку социальных сервисов.
Второй важный аспект социальных приложений — что думают люди о контенте, который они видят. В SharePoint есть SocialDataService, позволяющий посетителям помечать, оценивать и комментировать данные, документы и страницы на ваших сайтах.
Третий значимый социальный аспект SharePoint — публикация действий и подписка на действия ваших коллег. SharePoint предоставляет ActivityFeed и набор API для публикации таких действий в виде канала.
Поскольку наша статья вовсе не о новых средствах поддержки социальных сервисов в SharePoint, мы не станем вдаваться в детали, а просто дадим ссылки на некоторый важный контекст для примеров, которые вы увидите далее в этой статье. Советуем зайти на сайт SharePoint Developer Center или прочитать технический документ “Managing Social Networking with Microsoft Office SharePoint Server 2007”.
Расширение Outlook с помощью веб-сервисов
Вы убедились, что в SharePoint и Office широкий выбор способов доступа к данным для последующего использования в приложениях Office. Еще один способ включает применение веб-сервисов SharePoint. В этом примере мы создадим новую ленту Outlook, которая позволит вам получать всех ваших коллег из SharePoint в Outlook как элементы контактов. Вы даже сможете передать в Outlook картинку из профиля пользователя, как это делается при работе с Microsoft Exchange.
Начнем с создания новой надстройки Outlook в Visual Studio 2010. Мы будем писать ее на C#, но могли бы использовать и Visual Basic. В предыдущих версиях Visual Basic давал небольшое преимущество за счет поддержки необязательных параметров, но теперь такая поддержка есть и в C#.
Лента — средство согласованного взаимодействия со всеми приложениями Office. Outlook 2010 теперь отображает ленту на основном экране. В этом примере вы добавите сюда новую ленту. Visual Studio 2010 позволяет легко создавать ленты Office с помощью визуального дизайнера лент — Ribbon Designer. Вы можете просто перетаскивать элементы управления из окна инструментария слева на рабочую область дизайнера.
В данном случае нам нужно лишь задать некоторые свойства вроде метки для вкладки и группы. Затем добавить кнопку. Добавив кнопку в свою группу на ленте, вы можете задать размер и присвоить изображение кнопке. В итоге ваша лента будет выглядеть как на рис. 12.
Рис. 12. Создание новой ленты Outlook
Последнее, что осталось сделать, — задать свойство, определяющее, когда будет показываться лента. По умолчанию она отображается в Mail Explorer. Это окно, которое вы видите, открыв элемент, относящийся к почте. В данном примере ленту нужно отображать на основном экране. Выберите ленту и установите свойство RibbonType в Microsoft.Outlook.Explorer. Как видите, лента может появляться во множестве мест, в том числе в Mail Explorer и Contact Explorer.
Далее дважды щелкните кнопку на ленте, чтобы создать отделенный обработчик события щелчка. Это событие вы будете использовать для создания контакта в Outlook.
Теперь вы готовы добавить код, создающий контакт в Outlook. Visual Studio 2010 упрощает эту задачу. Я считаю, что любую задачу всегда лучше разбивать на несколько частей. Сначала вы создали надстройку Outlook, потом — ленту. После каждого такого этапа нажимайте F5 для компиляции и запуска приложения. Теперь вы можете создать контакт Outlook, используя «зашитые» в код значения. Убедившись, что все работает, можно добавить код, вызывающий SharePoint. И вновь проверяйте на каждом этапе, что все работает корректно, прежде чем переходить к следующему этапу.
На рис. 13 показан код для создания нового контакта на основе «зашитых» в код значений. В нем с помощью метода CreateItem создается новый объект ContactItem. Затем вы задаете свойства ContactItem и вызываете метод Save для фиксации изменений.
Рис. 13. Стереотипный код для создания контакта
Outlook.ContactItem newContact = Globals.ThisAddIn.Application.CreateItem(Outlook.OlItemType.olContactItem);
newContact.FirstName = "Paul";
newContact.LastName = "Stubbs";
newContact.Email1Address = "pstubbs@microsoft.com";
newContact.CompanyName = "Microsoft";
newContact.JobTitle = "Technical Evangelist";
newContact.CustomerID = "123456";
newContact.PrimaryTelephoneNumber = "(425)555-0111";
newContact.MailingAddressStreet = "1 Microsoft Way";
newContact.MailingAddressCity = "Redmond";
newContact.MailingAddressState = "WA";
newContact.AddPicture(@"C:\me.png");
newContact.Save();
Единственная трудная часть заключается в присваивании контакту картинки: для этого нужно вызвать метод AddPicture, который принимает путь к картинке на диске. Это проблематично, потому что вам надо получать изображения от SharePoint. Как это сделать, вы узнаете в следующем разделе. Убедившись, что код работает и контакт создается в Outlook, вы готовы обращаться к SharePoint и добавлять настоящие контакты.
Применение UserProfileService
UserProfileService — веб-сервис SharePoint, позволяющий обращаться к информации профилей, в том числе к списку ваших коллег и к их информации профилей. Чтобы задействовать этот сервис, начните с добавления ссылки на ваш проект. Так как это веб-сервис, а не WCF-сервис, вам нужно выбрать вкладку Advanced в диалоге Add Service, а затем щелкнуть кнопку Add Web Service. Это приведет к появлению старого диалога Add Web Service, знакомого вам по Visual Studio 2005.
Добавив ссылку, можно написать код для получения своих коллег:
// Instantiate the Web service.
UserProfileService userProfileService = new UserProfileService();
// Use the current user log-on credentials.
userProfileService.Credentials = System.Net.CredentialCache.DefaultCredentials;
Этот код создает экземпляр сервиса и передает ему ваши текущие удостоверения. Затем вызывается метод GetUserColleagues с передачей пользователя, для которого нужно получить список коллег. Вызов возвращает массив объектов ContactData:
ContactData[] contacts = userProfileService.GetUserColleagues("contoso\\danj");
Теперь мы перебираем все объекты ContactData, представляющие данные профилей для коллег этого пользователя в SharePoint. Расширенные свойства извлекаются вызовом метода GetUserProfileByName, который возвращает массив PropertyData, где содержатся пары «ключ-значение» для каждого коллеги:
// Add each Colleague as an Outlook Contact
foreach (ContactData contact in contacts) {
// Get the users detailed Properties
PropertyData[] properties = userProfileService.GetUserProfileByName(contact.AccountName);
// Create a new Outlook Contact
Outlook.ContactItem newContact = Globals.ThisAddIn.Application.CreateItem(Outlook.OlItemType.olContactItem);
Теперь мы преобразуем эти пары «ключ-значение» в свойства контакта:
// Set the Contact Properties
newContact.FullName = contact.Name;
newContact.FirstName = properties[2].Values[0].Value.ToString();
newContact.LastName = properties[4].Values[0].Value.ToString();
newContact.Email1Address = properties[41].Values[0].Value.ToString();
...
Наконец, мы получаем фотографию контакта и сохраняем новый контакт:
// Download the users profile image from SharePoint
SetContactImage(properties, newContact);
newContact.Save();
Последний фрагмент головоломки — получение картинки контакта от SharePoint. Одно из расширенных свойств включает путь к эскизу картинки в профиле пользователя. Вам нужно скачать эту картинку во временный файл на диске, чтобы Outlook API мог добавить ее к объекту ContactItem:
private static void SetContactImage(
PropertyData[] properties,
Outlook.ContactItem newContact){
// Download image to a temp file
string userid = properties[16].Values[0].Value.ToString();
string imageUrl = properties[15].Values[0].Value.ToString();
string tempImage = string.Format(@"C:\{0}.jpg", userid);
WebClient Client = new WebClient();
Client.Credentials = CredentialCache.DefaultCredentials;
Client.DownloadFile(imageUrl, tempImage);
newContact.AddPicture(tempImage);
}
Вот и все! Теперь у вас есть надстройка Ribbon для Outlook, которая обращается к SharePoint для выборки социальных данных в контакты Outlook. Запустив это приложение, вы увидите, что ContactItem заполнен данными SharePoint, в том числе информацией и изображением из профиля пользователя.
Заключение
Теперь вы убедились, насколько просто получать данные из SharePoint в клиенты Office. Мы показали вам самые разнообразные варианты — от решений без всякого кода до гибких решений с написанием кода на C# или Visual Basic.
Применение WCF Data Services для доступа к данным списков SharePoint предоставляет .NET-разработчикам стандартный способ, быстрый и несложный в реализации. Клиентская объектная модель обеспечивает доступ к внешним спискам SharePoint и открывает широкие возможности для передачи LOB-данных в Office. Наконец, веб-сервисы SharePoint обладают самой высокой гибкостью в доступе к данным, но требуют больше усилий в плане кодирования и тестирования.
Возможность доступа к данным SharePoint в виде списков — важный шаг вперед, так как ими удобно пользоваться в браузере. А если сделать еще один шаг, то вы сможете задействовать широкий набор вариантов доступа к данным из приложений Office, привычных пользователям. Visual Studio 2010 значительно упрощает создание, отладку и развертывание таких решений. Как видите, это отражает некоторые из новых и важных возможностей разработки, заложенных в новые версии продуктов.
ополнительные учебные материалы, примеры и информацию можно найти в онлайновых центрах разработки дл Office и SharePoint.