Мой сайт
Среда, 30.07.2025, 12:35
Меню сайта
Мини-чат
Наш опрос
Оцените мой сайт
Всего ответов: 0
Статистика

Онлайн всего: 2
Гостей: 2
Пользователей: 0
Форма входа
Главная » 2014 » Февраль » 19 » Использование Silverlight и COM для доступа к данным в Sha
07:47
 

Использование Silverlight и COM для доступа к данным в Sha

Дата публикации: Ноябрь 2011 г.

Аннотация: в этой статье освещается создание приложений Microsoft Silverlight для Microsoft SharePoint 2010 с использованием клиентской объектной модели. В частности, читатель узнает, как использовать Silverlight для загрузки, редактирования и обновления данных SharePoint через интерфейс API клиентской объектной модели.

Эмблема Wrox

Применимо к: Microsoft SharePoint 2010, Microsoft Silverlight

Автор: Райан Морган (Ryan Morgan)

Редакторы: технические редакторы статей по SharePoint 2010 из издательства WROX

Содержание

Приведенный здесь пример кода является работающим примером реализации простого проекта представления модели ViewModel для управления данными SharePoint 2010. Кроме того, здесь содержится код, который можно использовать в аналогичных проектах для предоставления функциональной возможности отмены действия.

Введение в использование Silverlight и COM для доступа к данным SharePoint 2010

В этой статье используется следующий сценарий, который позволяет объяснить, как создавать приложения Silverlight в SharePoint 2010 с помощью клиентской объектной модели.

Отдел маркетинга Adventure Works управлял ресурсами с помощью сайта группы в SharePoint. Группа решила повысить удобство работы и расширить возможности пользовательского интерфейса. Теперь пользователи используют Silverlight для просмотра и администрирования утвержденных графических ресурсов, имеющих отношение к продукции компании. Сотрудники отдела маркетинга используют рабочие процессы SharePoint и список задач для запроса новых ресурсов у группы графического дизайна. Когда группа графического дизайна предоставляет ресурс, содержимое этого ресурса сначала просматривается группой маркетинга, а затем группой юристов; только после этого к утвержденным версиям ресурса получают доступ и другие сотрудники компании. Простой последовательный рабочий процесс, встроенный в Visual Studio, служит для пометки ресурса как утвержденного после указания дат утверждения группой маркетинга и группой юристов. Пример в этой статье содержит представление и режим редактирования ресурсов в списке доступных ресурсов, а также демонстрирует, как можно управлять элементами в этом списке с помощью интерфейса API клиентской объектной модели.

Ознакомление с этой статьей предполагает базовое понимание способа загрузки данных объектом ClientContext и внесения изменений в данные.

Введение в клиентскую объектную модель

Интерфейс API клиентской объектной модели является нововведением SharePoint 2010. С его помощью можно получать доступ к сайтам и содержимому приложений SharePoint 2010, в том числе доступ на управление. В отличие от более ранних версий SharePoint знание веб-служб SOAP не является обязательным условием для создания приложений, так как библиотека абстрагирует все вызовы к службе WCF с помощью строго типизированного интерфейса API, который очень схож по своим функциям с серверной объектной моделью. С помощью этого интерфейса API можно работать с удаленным экземпляром SharePoint и использовать стиль, который покажется знакомым, если вы раньше разрабатывали в SharePoint нестандартные веб-части и службы.

Получение данных с помощью клиентской объектной модели

При наличии опыта использования серверной объектной модели для разработки SharePoint многие пространства имен и операции окажутся знакомыми. В таблице 1 приведены некоторые пространства имен интерфейса API SharePoint и соответствующие пространства имен в управляемой клиентской объектной модели.

Таблица 1.

Серверная объектная модель

Клиентская объектная модель

SPContext

ClientContext

SPSite

Site

SPWeb

Web

SPUser

User

SPList

List

SPListItem

ListItem

SPField

Field

При переходе с программирования серверной объектной модели на разработку приложений Silverlight, использующих клиентскую объектную модель, следует помнить, что Silverlight работает на стороне клиента. Этот простой факт является причиной появления перечисленных ниже принципиальных различий.

  • Клиентская объектная модель не поддерживает концепцию текущего контекста, который предоставляется SPContext.Current. Экземпляр объекта ClientContext создается с параметром URI веб-сервера SharePoint, к которому выполняется подключение.

  • В Silverlight все вызовы сервера осуществляются асинхронно. Независимо от того, вызывается ли метод ClientContext.Load или нет, к данным невозможно получить доступ до вызова метода ExecuteQueryAsync. В следующем примере ни один из загруженных объектов или запросов не является доступным, пока не будет вызван метод OnQuerySucceeded. Метод OnQuerySucceeded зарегистрирован как обработчик обратного вызова для успешного запроса при возврате после асинхронного вызова из метода ExecuteQueryAsync.

  • Отсутствует какой-либо способ запуска кода с повышенным уровнем привилегий.

Объект ClientContext является механизмом, через который предоставляется весь доступ к данным сервера SharePoint. Объект ClientContext отслеживает состояние ListItems, предоставляет возможности пакетного выполнения вызовов SharePoint и позволяет выполнять любые вызовы интерфейса API клиентской объектной модели.

В следующем примере кода показано, как загружать содержимое списка с помощью C# и клиентской объектной модели. Обработка ошибок явно не показана (для экономии места), и ошибки, возникающие во время запроса, передаются в стандартный компонент обработки ошибок проекта Silverlight. Рекомендации по работе с ведением журналов и обработкой исключений см. в библиотеке по Silverlight для предприятий (Возможно, на английском языке).

public HomeViewModel() { // First - instantiate the Assets Web. // Note that SharePointSiteURI resolves to "http://sl2sp.local/". AssetsContext = new ClientContext(AppViewModel.Instance.SharePointSiteURI); // Queue the call to load the web. AssetsContext.Load(AssetsContext.Web); // Build the CAML query used to select the data. // In this case, simply select all fields. CamlQuery qry = new CamlQuery(); string strQuery = "<View/>"; qry.ViewXml = strQuery; // Query the list by loading a query for the ProductAssets list. ProductAssetsListItems = AssetsContext.Web.Lists.GetByTitle("ProductAssets").GetItems(qry); // Mark the query for loading by the AssetsContext. AssetsContext.Load(ProductAssetsListItems); // Run the query, and assign the return method. AssetsContext.ExecuteQueryAsync(onQuerySucceeded, onQueryFailed); } private void onQuerySucceeded(object sender, ClientRequestSucceededEventArgs args) { // Because the AssetsCount property is bound in the UI, the Dispatcher // for the UI thread should be used when assigning a value to it. AppViewModel.Instance.AppDispatcher.BeginInvoke( () => { AssetsCount = ProductAssetsListItems.Count; } ); } private void onQueryFailed(object sender, ClientRequestFailedEventArgs args) { //Bubbles the error message up. This will // be caught by the unhandled exception handler in App.XAML. throw new Exception(string.Format("Query failed with message {0}", args.Message)); }

Несмотря на свою простоту, предыдущий пример демонстрирует многие обсуждавшиеся выше аспекты. В объект ClientContext передается URL-адрес сайта, на котором он будет использоваться, а метод асинхронного обратного вызова работает с возвращенным значением после завершения выполнения запроса. Если какой-либо код пытается получить доступ к свойствам объекта Web или объекта List до выполнения вызова ExecuteQueryAsync, возникает исключение NotInitialized.

Преобразование данных в свойства объекта

Познакомившись с основами ClientContext и способом получения доступа к данным из SharePoint, можно продолжить рассмотрение маркетингового примера. На рис. 1 показан интерфейс, который группа разработала для управления продуктами.



Рис. 1. Интерфейс управления ресурсами продуктов

Интерфейс управления активами продуктов

Данные списка и библиотеки возвращаются из интерфейса API клиентской объектной модели в виде нестрого типизированного словаря. Чтобы воспользоваться преимуществами мощной модели привязки, доступной в приложениях Silverlight, разработчики должны вручную создать объекты и свойства для представления данных из списков SharePoint в пользовательском интерфейсе Silverlight. Этот интерфейс создан для редактирования сведений о ресурсах продуктов. Чтобы предоставить доступ к данным как строго типизированным объектам, которые могут быть привязаны к элементам управления в представлении, приложение нуждается в следующих объектах:

  • объект для представления списка поиска для категорий;

  • объект для представления списка поиска для продуктов;

  • объект для представления ресурсов продуктов, которые управляются в приложении.

Так как каждый из перечисленных выше объектов представляет объект ListItem в SharePoint, необходимо сначала создать базовый класс, от которого могут наследовать все три объекта. Рассмотрите следующее определение для класса SharePointEntityBase.

public class SharePointEntityBase : ObservableObjectBase { public ListItem SourceItem { get; set; } public int? Id { get { if (SourceItem != null) return SourceItem.Id; else return null; } } public void UpdateSourceItem(string fieldName, object value) { if (!IsLoading) { if (SourceItem != null) { SourceItem[fieldName] = value; } HasChanges = true; } } }

Сначала класс наследует от базового класса ObservableObjectBase, который реализует интерфейс INotifyPropertyChanged. Этот класс предоставляет функциональные возможности, которые вызывают события PropertyChanged, способствующие привязке (см. исходный код, доступный для загрузки). Свойства базового класса управляют объектом ListItem, к которому прикрепляются производные классы. Свойство SourceItem использует экземпляр ListItem, который применялся для загрузки объекта из SharePoint. Так как объект ClientContext отслеживает состояние объекта ListItem, сохранение ссылки на ListItem позволяет объектам, которые наследуют от этого объекта, автоматически обновлять базовое поле в объекте ListItem.

После подготовки базового класса следует создать класс для хранения свойств ProductAsset. Рассмотрите следующее определение класса ProductAsset.

public class ProductAsset : SharePointEntityBase { public string FileName { get { return _FileName; } private set { _FileName = value; NotifyPropertyChanged(_FileNameChangedEventArgs); } } private string _FileName; private PropertyChangedEventArgs _FileNameChangedEventArgs = new PropertyChangedEventArgs("FileName"); public string FileType { get { return _FileType; } private set { _FileType = value; NotifyPropertyChanged(_FileTypeChangedEventArgs); } } private string _FileType; private PropertyChangedEventArgs _FileTypeChangedEventArgs = new PropertyChangedEventArgs("FileType"); public Product AssociatedProduct { get { return _AssociatedProduct; } set { _AssociatedProduct = value; NotifyPropertyChanged(_AssociatedProductChangedEventArgs); if (value != null) UpdateSourceItem("Product", value.Id); else UpdateSourceItem("Product", null); } } private Product _AssociatedProduct; private PropertyChangedEventArgs _AssociatedProductChangedEventArgs = new PropertyChangedEventArgs("AssociatedProduct"); public DateTime? LegalApprovedDate { get { return _LegalApprovedDate; } set { _LegalApprovedDate = value; NotifyPropertyChanged(_LegalApprovedDateChangedEventArgs); UpdateSourceItem("LegalApprovedDate", value); } } private DateTime? _LegalApprovedDate; private PropertyChangedEventArgs _LegalApprovedDateChangedEventArgs = new PropertyChangedEventArgs("LegalApprovedDate"); public DateTime? MarketingApprovedDate { get { return _MarketingApprovedDate; } set { _MarketingApprovedDate = value; NotifyPropertyChanged(_MarketingApprovedDateChangedEventArgs); UpdateSourceItem("MarketingApprovedDate", value); } } private DateTime? _MarketingApprovedDate; private PropertyChangedEventArgs _MarketingApprovedDateChangedEventArgs = new PropertyChangedEventArgs("MarketingApprovedDate"); }

В отношении редактируемых свойств доступен вызов, который обновляет исходный элемент в методе задания значения свойства. Данный вызов обновляет базовый объект ListItem. В целях краткости шаблон отмены действия (undo) был исключен из этого примера, однако он также реализован в методе задания значения редактируемых свойств (см. исходный код, доступный для загрузки). Обратите внимание, что с использованием объекта FieldLookupValue, который показан в коде ниже, в коде задается базовое значение Id. Интерфейс API клиентской объектной модели использует это значение Id для надлежащего создания ссылки на связанный продукт в виде поля подстановки.

Последнее действие, необходимое для преобразования объектов ListItem в строго типизированные объекты, — это создание логики для наполнения свойств. В большом приложении для этого хорошо подходит отражение, чего без труда можно достичь, сохраняя свойство FieldName из SharePoint в пользовательском атрибуте, сопутствующем каждому свойству. Однако так как эта статья посвящена работе интерфейса API, в следующем примере приводится более простая версия, которая наполняет сущность в конструкторе.

public ProductAsset(ListItem source, IEnumerable<Product> products) { IsLoading = true; SourceItem = source; if (SourceItem != null && SourceItem["FileRef"] != null) FileName = SourceItem["FileRef"].ToString(); if (SourceItem != null && SourceItem["File_x0020_Type"] != null) FileType = SourceItem["File_x0020_Type"].ToString(); if (SourceItem != null && SourceItem["LegalApprovedDate"] != null) LegalApprovedDate = (DateTime)SourceItem["LegalApprovedDate"]; if (SourceItem != null && SourceItem["MarketingApprovedDate"] != null) MarketingApprovedDate = (DateTime)SourceItem["MarketingApprovedDate"]; if (SourceItem != null && SourceItem["Product"] != null && products != null) { FieldLookupValue productValue = (FieldLookupValue)SourceItem["Product"]; AssociatedProduct = products.Where(p => p.Id == productValue.LookupId).FirstOrDefault(); } IsLoading = false; }

Конструктор для этого класса принимает два параметра, объект ListItem, с которым следует связать элемент, и список продуктов IEnumerable. С помощью полей каждого из свойств в ProductAsset можно задать для общих свойств значение из объекта ListItem. Чтобы использовать в Silverlight возможность привязки выбранного значения напрямую к объекту, подстановка использует запрос LINQ to Objects для выбора соответствующего продукта из списка, на который указывает ссылка. Объект выбирается с помощью свойства LookupId, которое хранится в объекте FieldLookupValue, возвращаемом в объекте ListItem. Рассмотрим метод задания значения для свойства Product в классе ProductAsset еще раз; скорее всего, вызов обновления свойства SourceItem стал более понятным и очевидным. Этот класс абстрагирует базовый объект ListItem и обновляет свойство Id из источника соответствующего продукта. Это абстрагирование устраняет потребность объекта ViewModel в обновлении базовых объектов SharePoint при изменении полей ListItem. Пока используется двухсторонняя привязка любые изменения пользовательского интерфейса автоматически обновляют поля ListItem, чтобы вызов обновления к SharePoint оставался допустимым.

Привязка представления к ViewModel

Рассмотрите макет представления списка и подробных сведений на рис. 1. Интерфейс содержит две области: список ресурсов продуктов в нижней части, представленный в виде сетки, и коллекцию доступных для редактирования полей формы в верхней части. При выборе элемента в нижней сетке поля в верхней части автоматически привязываются для предоставления формы редактирования выбранного элемента.

ViewProductAssetsViewModel поддерживает представление на рис. 1. В XAML ViewModel добавляется в качестве расширения разметки StaticResource для View. Это приводит к вызову конструктора и созданию экземпляра ViewModel, к которому может быть привязан объект View. В следующем коде показан конструктор ViewModel.

<UserControl.Resources> <ViewModels:ViewProductAssetsViewModel x:Key="ViewProductAssetsViewModelResource"></ViewModels:ViewProductAssetsViewModel> </UserControl.Resources>

После создания экземпляра ViewModel и добавления его в ресурсы элемента управления следующая разметка задает для свойства DataContext значение экземпляра класса.

<Grid x:Name="LayoutRoot" DataContext="{Binding Source={StaticResource ViewProductAssetsViewModelResource}}"> ...

Задание для свойства DataContext родительского объекта значения экземпляра класса, который был создан в объекте Resources для пользовательского элемента управления позволяет привязать любое свойство зависимостей элемента View к свойству в ViewModel. Следующая разметка определяет форму редактирования для объекта ProductAsset.

<TextBlock Text="Associated Product"></TextBlock> <ComboBox ItemsSource="{Binding Path=Products}" SelectedItem="{Binding SelectedProductAsset.AssociatedProduct, Mode=TwoWay}"></ComboBox> <TextBlock Text="Marketing Approved Date"></TextBlock> <sdk:DatePicker SelectedDate="{Binding SelectedProductAsset.MarketingApprovedDate, Mode=TwoWay}"/> <TextBlock Text="Legal Approved Date"></TextBlock> <sdk:DatePicker SelectedDate="{Binding SelectedProductAsset.LegalApprovedDate, Mode=TwoWay}" /> <Button Content="Save" Command="{Binding SaveCommand}"></Button> <Button Content="Cancel" Command="{Binding CancelCommand}"></Button>

Доступные для редактирования значения элемента управления двусторонне привязаны к свойству SelectedProductAsset элемента ViewModel, который задается путем выбора элемента в объекте DataGrid. Так как модель привязки задана как TwoWay, любые изменения значений в объектах DatePicker или ComboBox напрямую определяют свойство выбранного объекта ProductAsset. С помощью вызова метода задания значений этих свойств базовые поля ListItem обновляются посредством шаблона, приведенного ранее в этой статье.

Внесение изменений в данные

Чтобы завершить форму редактирования ресурсов продуктов, следует создать команду сохранения, которая будет вносить любые изменения обратно в SharePoint. Теперь, когда в свойстве SourceItem обновлены поля, следует вызвать объект ClientContext в SharePoint для отправки изменений обратно в SharePoint и внесения их в объект ListItem на сайте. На примере следующего кода показан метод, привязанный к команде для кнопки Save (Сохранить).

private void SaveProductAsset(object param) { if (SelectedProductAsset != null) { AppViewModel.Instance.OperationIsInProgress = true; SelectedProductAsset.SourceItem.Update(); AssetsContext.ExecuteQueryAsync(onSaveSucceeded, onSaveFailed); } } private void onSaveSucceeded(object sender, ClientRequestSucceededEventArgs args) { AppViewModel.Instance.AppDispatcher.BeginInvoke( () => { SelectedProductAsset = null; AppViewModel.Instance.OperationIsInProgress = false; }); }

При вызове метод SaveProductAsset получает доступ к базовому свойству SourceItem в целях вызова метода UpdateObject, который был сделан доступным в исходном объекте ListItem, возвращенном из запроса к этому элементу, выполненного в SharePoint. Метод Update фиксируется путем осуществления вызова ExecuteQueryAsync с последующим сбросом формы редактирования посредством очистки объекта SelectedProductAsset.

В этом примере каждое обновление фиксируется по-отдельности, однако объект ClientContext может использоваться и иначе. Объект ClientContext поддерживает пакетные вызовы. Это означает, что рассматриваемая форма может пройти рефакторинг для отправки всех обновлений посредством одного вызова сохранения. Рассмотрите следующий пример.

foreach (ProductAsset item in ProductAssets) { bool operationHasChangesToCommit = false; if (item.HasChanges) { item.SourceItem.Update(); operationHasChangesToCommit = true; } if(operationHasChangesToCommit) AssetsContext.ExecuteQueryAsync(onSaveSucceeded, onSaveFailed); }

Об авторе

Райан Морган (Ryan Morgan) — управляющий партнер и главный архитектор в компании Arrow Consulting & Design, Уэст-Палм-Бич, Флорида. Райан занимается крупномасштабной автоматизацией бизнес-процессов и бизнес-аналитики в сфере финансов и управления основными данными с помощью SharePoint с Silverlight и ASP.NET. Райан — активный участник сообщества .NET и SharePoint, выступает на мероприятиях Code Camps, SharePoint Saturdays и DevConnections в Лас-Вегасе. Участвовал в написании книги Professional DotNetNuke 5 (DotNetNuke 5 для специалистов) издательства Wrox. Веб-сайты компании, в которой работает Райан, расположены по адресам www.ArrowDesigns.com и www.ArrowNuke.com (возможно, на английском языке).

В работе над статьями, посвященными Microsoft SharePoint 2010, принимали участие следующие технические редакторы из издательства Wrox.

  • Мэт Рэнлет (Matt Ranlett) — специалист по SQL Server со статусом MVP, многолетний участник сообщества разработчиков .NET г. Атланты. Основатель и автор сайта Atlanta Dot Net Regular Guys (возможно, на английском языке), учредил и возглавляет несколько региональных групп пользователей. Уделяет много времени общественно-полезной деятельности на местном и национальном уровне: поддерживает ресурс SharePoint 1, 2, 3! (Возможно, на английском языке), трижды принимал участие в организации мероприятия Atlanta Code Camp, работает в совете директоров INETA в качестве вице-президента по технологии и участвует в нескольких подкастах, например .Net Rocks и ASP.NET Podcast. Несмотря на это, Мэт недавно нашел свободное время и женился на очаровательной женщине по имени Ким, которой помогает воспитывать трех собак. В настоящее время Мэт работает главным консультантом в компании Intellinet и является участником группы, помогающей достичь успеха благодаря использованию инновационных решений, создающих бизнес-ценность.

  • Джейк Дэн Эттис (Jake Dan Attis). Если речь заходит о шаблонах, методиках и управлении применительно к разработке SharePoint, Джейк Дэн Эттис — это именно тот, кто вам нужен. Дэн переехал в Атланту из г. Монктон, Канада. Хотя его специальность — прикладная математика, он самый настоящий разработчик SharePoint. Дэн регулярно посещает и организует мероприятия сообщества Атланты (Code Camp, SharePoint Saturday и Atlanta SharePoint User Group), а также выступает на них. Когда Дэн не работает в Visual Studio, он любит проводить время с дочерью Лили, смотреть хоккей или футбол и дегустировать пиво со всех концов света.

  • Кевин Досталек (Kevin Dostalek) имеет более чем 15-летний опыт работы в ИТ-индустрии, и свыше 10 лет управляет крупными ИТ-проектами и руководит сотрудниками. Он вел проекты в небольших, средних и крупных компаниях и занимал различные должности, в том числе разработчика, архитектора, бизнес-аналитика, технического руководителя, менеджера по разработке, проект-менеджера, менеджера программы и преподавателя. Помимо этого, в 2005–2008 гг. Кевин возглавлял отдел поставки решений в должности вице-президента средней компании — партнера Майкрософт со статусом Gold, а затем работал вице-президентом по инновациям и обучению. В начале 2010 г. Кевин основал компанию Kick Studios, предоставляющую услуги в области консалтинга, разработки и обучения в таких специальных областях, как SharePoint и социальные компьютерные технологии. С тех пор он часто выступает на многих мероприятиях и конференциях, проводимых группами пользователей и сообществом по всей стране. Узнать о Кевине больше можно из его блога, The Kickboard.

  • Ларри Риман (Larry Riemann) 17 лет разрабатывает архитектуру и создает бизнес-приложения для некоторых из крупнейших компаний мирового уровня. Ларри — независимый консультант и владелец компании Indigo Integrations, консультации по SharePoint он проводит исключительно на сайте SharePoint911. Он пишет и публикует статьи и время от времени выступает на разных конференциях. Последние несколько лет он занимается в основном SharePoint, создавая новые функции и расширяя существующие там, где стандартной функциональности SharePoint уже не хватает. Помимо этого, Ларри еще и квалифицированный архитектор .NET и обладает обширными познаниями в области системной интеграции, корпоративной архитектуры и решений с высоким уровнем доступности. Посетить его блог можно здесь (Возможно, на английском языке).

  • Сундараджан Нарасиман (Sundararajan Narasiman) — технический архитектор в группе по управлению контентом и порталам компании Cognizant Technology Solutions, Ченнаи. Работает в данной области свыше 10 лет. Сундараджан занимается главным образом консультациями в области архитектуры и технологий стека сервера SharePoint 2010 и основной разработки для платформы .NET 3.5. Увлекается программированием, также интересуется экстремальным программированием и разработкой через тестирование.

Дополнительные ресурсы

Дополнительные сведения см. в следующих источниках:

История изменений

Дата Описание Причина

Ноябрь 2011 г.

Первая публикация

Просмотров: 220 | Добавил: xclatit | Рейтинг: 0.0/0
Всего комментариев: 0
Поиск
Календарь
«  Февраль 2014  »
Пн Вт Ср Чт Пт Сб Вс
     12
3456789
10111213141516
17181920212223
2425262728
Архив записей
Друзья сайта
  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz