С выпуском Office 365 компания Microsoft представит следующую версию Microsoft Online Services — облачный сервис для коллективной работы и коммуникаций на основе SharePoint 2010, Exchange 2010 и Lync Server 2010. Office 365, в настоящее время пребывающий в стадии бета-версии, будет поддерживать SharePoint, Exchange и Lync как предложение Software as a Service (SaaS), покупаемое по подписке и размещаемое в информационных центрах облака, которые управляются Microsoft.
SharePoint Online — облачная версия SharePoint 2010 — предоставит пользователям многое из функциональности SharePoint 2010, но избавит от необходимости управлять аппаратно-программным обеспечением, которое требуется для масштабируемого и надежного решения в области коллективной работы. В этой статье я дам обзор того, чем схожа и чем отличается разработка для SharePoint Online от разработки для SharePoint 2010, и продемонстрирую создание решений, выполняемых в SharePoint Online.
В следующем выпуске SharePoint Online разработчики для SharePoint смогут создавать решения в области коллективной работы, применяя те же навыки и инструменты, что и в SharePoint 2010, в том числе Visual Studio 2010, SharePoint Designer 2010, C# или Visual Basic и различные SharePoint API и SDK. В разработке для SharePoint как локально, так и в облаке есть много общего, но имеются и существенные отличия, которые могут повлиять на то, как вы будете создавать решения.
Понимание этих отличий поможет разобраться в том, какие решения можно создавать для выполнения в SharePoint Online и как их разрабатывать.
Сходство адаптации SharePoint Online
В разработках для SharePoint 2010 у вас есть возможность настраивать SharePoint с использованием браузера и SharePoint Designer 2010, а также создавать решения в Visual Studio 2010. В случае SharePoint Online адаптация с помощью браузера и SharePoint Designer 2010 в основном осуществляется так же, как и SharePoint 2010 (с учетом разницы в функциональности, о которой рассказывается в следующем разделе). И решения для SharePoint Online в Visual Studio 2010 создаются в основном так же. Разработка ведется в Visual Studio 2010 применительно к локальному экземпляру SharePoint 2010 (который выполняется локально в Windows 7, Windows Server 2008 R2 или в виртуальной машине [VM]); при этом используются интегрированные средства отладки для итеративной разработки. По окончании разработки решение загружается в SharePoint Online через ту же Solution Gallery, которая предоставляется SharePoint 2010.
Главные отличия адаптации SharePoint Online
Хотя SharePoint Online основан на SharePoint 2010, при разработке решений под облачную версию нужно учитывать некоторые ключевые отличия. Во-первых, SharePoint Online поддерживает только решения с областью Site и Web. Он выполняется в мультитенантном облаке, где в общей инфраструктуре информационного центра работает множество тенантов, поэтому поддержка решений с область Farm (когда какая-либо функция активируется для всей фермы) не имеет смысла. Аналогично в SharePoint Online высший уровень доступа к вашему тенанту SharePoint ограничивается уровнем набора сайтов, поэтому функции с областью WebApplication (где функция выполняется на каждом веб-сайте в веб-приложении) тоже не поддерживаются.
Во-вторых, SharePoint Online поддерживает только решения с частичным доверием, так как решение с полным доверием могло бы обращаться за пределы уровня набора сайтов или получить разрешение на выполнение в ферме с привилегиями администратора.
Наконец, хотя SharePoint Online основан на SharePoint 2010, по функциональности он не на 100% совпадает со своим аналогом, размещаемым локально (на предприятии). Полное сравнение функциональности SharePoint 2010 и SharePoint Online см. в Microsoft SharePoint Online Beta Service Description, доступном на странице Office 365 Beta Service Descriptions по ссылке bit.ly/bBckol.
В этом списке видно, что поддерживается большинство средств адаптации SharePoint. Отсутствие поддержки Business Connectivity Services (BCS), внешних списков и возможности вызова веб-сервисов за пределами SharePoint Online (не поддерживаемых в решениях с частичным доверием) существенно повлияет на создание решений, выполняемых в SharePoint Online. Однако в будущей версии поддержка BCS планируется.
Учитывая эти сходства и различия, рассмотрим некоторые примеры типов решений, которые можно создавать в расчете на выполнение в SharePoint Online, в том числе изолированных решений (sandboxed solutions) и клиентской модели объектов SharePoint (object model, OM). Другие типы решений вроде автоматизации бизнес-процессов на основе решений с декларативными рабочими процессами будут обсуждаться в следующих статьях.
Разработка для SharePoint Online изолированных решений
Из предыдущего раздела вы знаете, что решения для SharePoint Online должны иметь область сайта или Web, их доступ ограничен данными в наборе сайтов, и они должны работать с частичным доверием. Разработка решений, выполняемых в «песочнице» (изолированной программной среде), отвечает всем этим критериям, в то же время позволяя администраторам SharePoint Online легко развертывать решения загрузкой напрямую в Solution Gallery.
Visual Studio 2010 обеспечивает отличную поддержку изолированных решений, в том числе предоставляет шаблон проекта, шаблон элемента проекта, мастер SharePoint Customization для создания новых проектов как изолированных решений, поддержку IntelliSense для SharePoint API с областью, ограниченной набором сайтов, а также средства отладки и упаковки. Чтобы приступить к созданию решения для SharePoint Online, сначала вы ведете разработку и отладку этого решения локально, применительно к SharePoint 2010. Для этого вам понадобится установить либо 64-разрядную Windows 7, либо Windows Server 2008 R2 вместе с SharePoint 2010 и Visual Studio 2010. Еще один хороший способ — использовать 2010 Information Worker Demonstration and Evaluation Virtual Machine (RTM); этот продукт создает виртуализованную среду разработки с SharePoint 2010 (скачайте с bit.ly/ezfe2Y). Кроме того, советую задействовать Visual Studio 2010 SharePoint Power Tools (bit.ly/azq882), который добавляет поддержку периода компиляции для изолированной среды и шаблон элемента проекта изолированного Visual Web Part (визуального веб-фрагмента).
В примерах в этой статье я создам решение на основе простого сценария:сотрудникам вымышленной компании Contoso Corp. будет предоставлена возможность запрашивать нестандартные закупки, не поддерживаемые их системой материально-технического снабжения. Для начала я создам набор сайтов и сайт в своей локальной среде разработки для SharePoint 2010. Я использую ранее упомянутые виртуальные машины, поэтому создал http://o365dpe.contoso.com/sites/spomsdnmag/purchasing. Мое первое решение будет развертывать список, применяемый для учета таких нестандартных закупок. С этой целью я открываю Visual Studio 2010, выбираю File | New Project и в диалоге New Project указываю Empty SharePoint Project, которому потом присваиваю имя PurchasingMgr.
В диалоге мастера SharePoint Customization Wizard в поле «What local site…» я ввожу URL своего сайта (http://o365dpe.contoso.com/sites/spomsdnmag/Purchasing/), выбираю Deploy as a sandboxed solution и нажимаю Finish, как показано на рис. 1.
Рис. 1. Указываем сайт и уровень доверия для PurchasingMgr
Далее я выбираю в Solution Explorer проект PurchasingMgr, щелкаю правой кнопкой мыши и выбираю Add | New Item. В диалоге Add New Item я указываю SharePoint 2010 в узле Installed Templates. Не все из этих шаблонов поддерживаются в случае изолированных решений (sandboxed solutions), а значит, и в SharePoint Online. Шаблоны элементов, поддерживаемые в изолированных решениях, приведены в табл. 2.
Табл. 2. Шаблоны элементов, поддерживаемые в изолированных решениях
Шаблон элемента | Совместим с изолированной средой? | Примечания |
Visual Web Part | Нет | Требует установки ASCX-файла на серверах SharePoint |
Visual Web Part (Sandboxed) | Да | При условии установки Visual Studio 2010 SharePoint Power Tools |
Web Part | Да | |
Sequential Workflow | Нет | Решение на основе рабочего процесса должно быть развернуто как решение с областью Farm (Ферма) |
State Machine Workflow | Нет | Решение на основе рабочего процесса должно быть развернуто как решение с областью Farm (Ферма) |
Business Data Connectivity Model | Нет | BCS-решение должно быть развернуто как решение с полным доверием; эта функция не поддерживается в SharePoint Online |
Application Page | Нет | Требует установки ASCX-страницы на сервере SharePoint |
Event Receiver | Да | |
Module | Да | |
Content Type | Да | |
List Definition from Content Type | Да | |
List Definition | Да | |
List Instance | Да | |
Empty Element | Да | |
User Control | Нет | Требует установки ASCX-файла на серверах SharePoint |
Чтобы сформировать свой список, я определяю для него Site Columns и Content Type, выбирая шаблон элемента Content Type и вводя NonStandBusPurchaseRequestsCT в качестве имени.
В SharePoint Customization Wizard в качестве базового типа контента я выбираю Item и щелкаю кнопку Finish. В Content Type будут столбцы Title, Description и Price, которые я буду определять декларативно, заменяя содержимое генерируемого файла Elements.xml своим XML-кодом, показанным на рис. 3.
Рис. 3. Определение NonStandBusPurchaseRequestsCT через Elements.xml
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Field SourceID="http://schemas.microsoft.com/sharepoint/v3"
ID="{A74E67E5-8905-4280-90C9-DEBFFC30D43D}"
Name="RequestDescription"
DisplayName="Description"
Group="Purchasing Manager Custom Columns"
Type="Note"
DisplaceOnUpgrade="TRUE" />
<Field SourceID="http://schemas.microsoft.com/sharepoint/v3"
ID="{CB5054F5-0C60-4DBE-94D2-CEFBFB793C7F}"
Name="Price"
DisplayName="Price"
Group="Purchasing Manager Custom Columns"
Type="Currency"
DisplaceOnUpgrade="TRUE" />
<!-- Parent ContentType: Item (0x01) -->
<ContentType ID="0x010078a81c8413f54917856495e56e7c09ed"
Name="Purchasing Manager - Non-Standard Business Purchase Requests Content Type"
Group="Purchasing Manager Content Types"
Description=
"Non-Standard Business Purchase Requests Content Type
for the Purchasing Manager Solution"
Inherits="TRUE"
Version="0">
<FieldRefs>
<FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title"
DisplayName="Title" />
<FieldRef ID="{A74E67E5-8905-4280-90C9-DEBFFC30D43D}"
Name="RequestDescription"
Required="TRUE" />
<FieldRef ID="{CB5054F5-0C60-4DBE-94D2-CEFBFB793C7F}" Name="Price"
Required="TRUE" />
</FieldRefs>
</ContentType>
</Elements>
Далее определяем список на основе типа контента; для этого щелкаем правой кнопкой мыши PurchasingMgr в Solution Explorer и выбираем Add New Item. Я выбрал List Definition из шаблона элемента Content Type, присвоил определению списка имя NonStandBusPurchaseRequestsListDefn и щелкнул Add.
В SharePoint Customization Wizard я выбираю ранее созданный тип контента помечаю флажок Add a list instance. Файл Elements.xml, созданный для NonStandBusPurchaseRequestsListDefn, показан на рис. 4.
Рис. 4. Определение NonStandBusPurchaseRequestsListDefn через Elements.xml
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<!-- Do not change the value of the Name attribute below.
If it does not match the folder name of the List Definition project item,
an error will occur when the project is run. -->
<ListTemplate
Name="NonStandBusPurchaseRequestsListDefn"
Type="10051"
BaseType="0"
OnQuickLaunch="TRUE"
SecurityBits="11"
Sequence="410"
DisplayName="Purchasing Manager –
Non-Standard Business Purchase Requests List Definition"
Description=
"Non-Standard Business Purchase Requests List Definition
for the Purchasing Manager Solution"
Image="/_layouts/images/itgen.png"/>
</Elements>
Заметьте, что каждое определение списка в моей функции (feature) нужно идентифицировать уникальным значением Type более 10 000 (чтобы избежать конфликтов со списками, уже определенными в SharePoint), и что я использую это значение при идентификации любого экземпляра списка, основанного на этом определении.
Чтобы добавить собственные столбцы к представлению списка, я открываю сгенерированный файл Schema.xml и добавляю элементы FieldRef в представление по умолчанию, как показано на рис. 5.
Рис. 5. Добавление собственных столбцов к представлению по умолчанию — NonStandBusPurchaseRequestsListDefn
<View BaseViewID="1" Type="HTML" WebPartZoneID="Main"
DisplayName="$Resources:core,objectiv_schema_mwsidcamlidC24;"
DefaultView="TRUE" MobileView="TRUE" MobileDefaultView="TRUE"
SetupPath="pages\viewpage.aspx" ImageUrl="/_layouts/images/generic.png"
Url="AllItems.aspx">
<Toolbar Type="Standard" />
<XslLink Default="TRUE">main.xsl</XslLink>
<RowLimit Paged="TRUE">30</RowLimit>
<ViewFields>
<FieldRef Name="Attachments">
</FieldRef>
<FieldRef Name="LinkTitle">
</FieldRef>
<FieldRef ID="{A74E67E5-8905-4280-90C9-DEBFFC30D43D}"
Name="RequestDescription" />
<FieldRef ID="{CB5054F5-0C60-4DBE-94D2-CEFBFB793C7F}" Name="Price" />
</ViewFields>
<Query>
<OrderBy>
<FieldRef Name="ID">
</FieldRef>
</OrderBy>
</Query>
<ParameterBindings>
<ParameterBinding Name="NoAnnouncements"
Location="Resource(wss,noXinviewofY_LIST)" />
<ParameterBinding Name="NoAnnouncementsHowTo"
Location="Resource(wss,noXinviewofY_DEFAULT)" />
</ParameterBindings>
</View>
Наконец, я определяю экземпляр списка выбором ListInstance1 под NonStandBusPurchaseRequestsListDefn и переименовываю его в NonStandBusPurchaseRequestsListInstance. Далее открываю Elements.xml и добавляю следующий XML, чтобы список базировался на нужном типе контента, и вставляю полезные описания для пользователей:
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<ListInstance Title="Non-Standard Business Purchase Requests"
OnQuickLaunch="TRUE"
TemplateType="10051"
Url="Lists/NonStandBusPurchaseRequestsListInstance"
Description=
"Non-Standard Business Purchase Requests List
for the Purchasing Manager Solution">
</ListInstance>
</Elements>
Для тестирования решения в Visual Studio 2010 выбираем Debug, а затем Start Debugging. Решение упаковывается и развертывается на моем локальном сайте (рис. 5).
Рис. 6. Отладка решения PurchasingMgr
Теперь, проверив решение PurchasingMgr, я готов развернуть его в SharePoint Online. Я создам новый набор сайтов (site collection) в SharePoint Online с именем Purchasing, используя шаблон Team Site. Возвращаемся в Visual Studio 2010 и упаковываем решение, щелкнув правой кнопкой мыши проект PurchasingMgr в Solution Explorer и выбрав Package. Для развертывания решения в SharePoint Online нужно просто загрузить его в Solution Gallery и активизировать функции сайта (это потребует привилегий администратора набора сайтов). Чтобы выполнить эту задачу, я вхожу в SharePoint Online, перехожу к своему набору сайтов и выбираю Site Actions | Site Settings, а затем Solutions для доступа к Solutions Gallery. В Solution Gallery я указываю вкладку Solutions и выбираю на ленте Upload Solution, потом перехожу к файлу PurchasingMgr.wsp в bin\Debug , щелкаю OK и Activate. Решение появится в Solution Gallery, как показано на рис. 7.
Рис. 7. Решение PurchasingMgr, развернутое в SharePoint Online
Далее, чтобы активизировать функцию, которая содержит столбцы для моего сайта, тип контента и список, я перехожу к сайту Purchasing и выбираю Site Actions | Site Settings | Manage Site Features. Далее указываю Purchasing Manager, функцию Content Types and Lists и выбираю Activate. В этот момент на сайте SharePoint Online должны появиться списки Non-Standard Business Purchase Requests.
Purchasing Manager — всего один пример того, как можно включать в SharePoint Online изолированные решения. Помните об ограничениях изолированных решений и поддерживаемых в SharePoint Online функциях — это позволит создавать решения, способные работать как в SharePoint 2010, так и в SharePoint Online.
Создание клиентских решений с помощью Silverlight
Клиентская OM, также введенная в SharePoint 2010, предоставляет объектно-ориентированный API для клиентов SharePoint, построенных с применением Microsoft .NET Framework, Silverlight и ECMAScript (в том числе JavaScript и JScript), которые выполняются на удаленных компьютерах (включая браузер для Silverlight и ECMAScript). Этот API соответствует пространству имен Microsoft.SharePoint на серверной стороне, поэтому освоить его несложно. Он также согласован между поддерживаемыми типами клиентов, благодаря чему его легко применять в различных клиентских решениях. Клиентский OM API поддерживается SharePoint Online и является ценным инструментом в разработке для облака.
Например, используя клиентскую OM, можно создать приложение Silverlight 4 для добавления элементов в список и разместить это приложение в изолированном веб-фрагменте (sandboxed Web Part). Для этого открываем Visual Studio 2010, выбираем File | New Project и в диалоге New Project указываем Empty SharePoint Project. Назовем проект PurchasingMgrWP и щелкаем OK. И вновь я создаю решение как изолированное и указываю на него на своем локальном сайте Purchasing. Чтобы создать приложение Silverlight 4, щелкните правой кнопкой мыши решение PurchasingMgrWP, выберите Silverlight в Installed Templates, укажите Silverlight Application присвойте решению имя NonStandBusPurchaseReqsSLOM. В диалоге New Silverlight Application сбросьте флажок Host the Silverlight application in a new Web Site (мы будем тестировать приложение в SharePoint) и в списке Silverlight Version выберите Silverlight 4.
Чтобы сослаться на клиентский Silverlight OM API, я добавляю ссылки на Microsoft.SharePoint.Client.Silverlight.dll и Microsoft.SharePoint.Client.Silverlight.Runtime.dll в C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\ClientBin. Далее создаю Silverlight UI, открыв MainPage.xaml и заменив содержащийся в нем XAML кодом, показанным на рис. 8.
Рис. 8. MainPage.xaml в NonStandBusPurchaseReqsSLOM
<UserControl xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
x:Class="NonStandBusPurchaseReqsSLOM.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<sdk:Label Content="Title:" Grid.Column="0" Grid.Row="0" Margin="3"/>
<sdk:Label Content="Description:" Grid.Column="0" Grid.Row="1" Margin="3"/>
<sdk:Label Content="Price:" Grid.Column="0" Grid.Row="2" Margin="3"/>
<TextBox Name="Title" Grid.Column="1" Grid.Row="0" Margin="3"/>
<TextBox Name="Description" Grid.Column="1" Grid.Row="1" Margin="3"/>
<TextBox Name="Price" Grid.Column="1" Grid.Row="2" Margin="3"/>
<Button Content="Add" Grid.Column="1" Grid.Row="3" Margin="3"
Name="addNonStanPurchaseReq" HorizontalAlignment="Right"
Height="25" Width="100" Click="addNonStanPurchaseReq_Click" />
</Grid>
</UserControl>
В XAML на рис. 8 определены текстовые поля и кнопка для сбора информации, которая вносится в мой список, как показано на рис. 9.
Рис. 9. MainPage.xaml в дизайнере
Дважды щелкните кнопку в дизайнере и замените класс кодом с рис. 10.
Рис. 10. AddNonStanPurchaseReq_Click
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.SharePoint.Client;
namespace NonStandBusPurchaseReqsSLOM
{
public partial class MainPage : UserControl
{
private string webUrl;
public MainPage(string url)
{
webUrl = url;
InitializeComponent();
}
private void addNonStanPurchaseReq_Click(object sender, RoutedEventArgs e)
{
ClientContext clientContext = new ClientContext(webUrl);
Web webSite = clientContext.Web;
ListCollection webLists = webSite.Lists;
List nonStandBusPurList =
clientContext.Web.Lists.GetByTitle(
"Non-Standard Business Purchase Requests");
ListItem newListItem =
nonStandBusPurList.AddItem(new ListItemCreationInformation());
newListItem["Title"] = Title.Text;
newListItem["RequestDescription"] = Description.Text;
newListItem["Price"] = Price.Text;
newListItem.Update();
clientContext.Load(nonStandBusPurList, list => list.Title);
clientContext.ExecuteQueryAsync(onQuerySucceeded, onQueryFailed);
}
private void onQuerySucceeded(
object sender, ClientRequestSucceededEventArgs args)
{
Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("New item added.");
});
}
private void onQueryFailed(object sender,
ClientRequestFailedEventArgs args)
{
Dispatcher.BeginInvoke(() =>
{
MessageBox.Show("Request failed. " + args.Message + "\n" +
args.StackTrace);
});
}
}
}
Код на рис. 10 соответствует стандартному шаблону, применяемому для клиентского OM-кода. Сначала я получаю доступ к клиентскому контексту через класс ClientContext (эквивалентный классу SPContext). Затем обращаюсь к сайту и списку через классы Web, ListCollection и List соответственно. (Обратите внимание на сходство с классами SPWeb, SPListCollection и SPList.) Наконец, я создаю ListItem вызовом метода List.AddItem, заполняю его данными из UI и вызываю метод ListItem.Update. На самом деле ListItem не создается, пока не будут вызваны методы ClientContext.Load и ClientContext.ExecuteQueryAsync для выполнения запроса. Заметьте, что вы можете уменьшить количество обменов данными с сервером, загрузив сразу несколько запросов через ClientContext.Load и вызвав метод ClientContext.ExecuteQueryAsync.
Для развертывания приложения Silverlight 4 я добавляю модуль, который будет развертывать это приложение с помощью проекта веб-фрагмента. Я указываю PurchasingMgrWP в Solution Explorer, щелкаю правой кнопкой мыши, выбираю Add | New Item | Module присваиваю модулю имя ClientBin. Далее заменяем содержимое созданного Elements.xml следующим XML:
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Module Name="ClientBin">
<File Path="ClientBin\NonStandBusPurchaseReqsSLOM.xap"
Url="ClientBin/NonStandBusPurchaseReqsSLOM.xap" />
</Module>
</Elements>
Этот XML развертывает файл NonStandBusPurchaseReqsSLOM.xap в папку ClientBin в моем сайте SharePoint.
Чтобы развернуть результат компиляции проекта NonStandBusPurchaseReqsSLOM с помощью модуля ClientBin, я выбираю этот модуль в Solution Explorer и открываю диалоговое окно свойств Project Output References. Щелкаю Add и в Project Name выбираю NonStandBusPurchaseReqsSLOM, а в DeploymentType — ElementFile.
Затем добавляем собственный веб-фрагмент в решение SharePoint для размещения приложения Silverlight 4. Я указываю PurchasingMgrWP в Solution Explorer, щелкаю правой кнопкой мыши, выбираю Add | New Item | Module присваиваю модулю имя ClientBin. Чтобы передать параметры (например, URL сайта, используемого для создания ClientContext) в приложение Silverlight 4, я применяю собственный веб-фрагмент. С этой целью я добавляю вспомогательный класс SilverlightObjectTagControl.cs и заменяю его тело кодом с рис. 11.
Рис. 11. Добавление вспомогательного класса SilverlightObjectTagControl.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace PurchasingMgrWP
{
class SilverlightObjectTagControl : WebControl
{
public string Source { get; set; }
public string InitParameters { get; set; }
protected override void CreateChildControls()
{
base.CreateChildControls();
if (Source != null && Source != "")
{
string width = (this.Width == Unit.Empty) ? "400" :
this.Width.ToString();
string height = (this.Height == Unit.Empty) ? "300" :
this.Height.ToString();
this.Controls.Add(new LiteralControl(
" <div>" +
" <object data=\"data:application/x-silverlight-2,\" +
" type=\"application/x-silverlight-2\" width=\"" + width +
" "\" height=\"" + height + "\">" +
" <param name=\"source\" value=\"" + Source + "\"/>" +
" <param name=\"onerror\" value=\"onSilverlightError\" />" +
" <param name=\"background\" value=\"white\" />" +
" <param name=\"minRuntimeVersion\" value=\"4.0.50826.0\" />" +
" <param name=\"autoUpgrade\" value=\"true\" />" +
" <param name=\"initparams\" value=\"" + InitParameters + "\" />" +
" <a href=\"http://go.microsoft.com/fwlink/?LinkID=" +
" 149156&v=4.0.50826.0\" +
" style=\"text-decoration: none;\">" +
" <img src=\"http://go.microsoft.com/fwlink/?LinkId=161376\" +
" alt=\"Get Microsoft Silverlight\" style=\"border-style: none\"/>" +
" </a>" +
" </object>" +
" <iframe id=\"_sl_historyFrame\" +
" style=.visibility:hidden;height:0;width:0;border:0px.></iframe>" +
" </div>"
));
}
}
}
}
У класса SilverlightObjectTagControl на рис. 11 два свойства: Source (через него передается URL приложения Silverlight для загрузки в веб-фрагмент) и InitParameters (для передачи инициализирующих параметров в приложение Silverlight 4). Эти свойства используются для формирования тега <object /> приложения Silverlight в методе CreateChildControls. Чтобы задействовать этот класс, откройте NonStandBusPurchaseReqsWP.cs и замените его содержимое кодом с рис. 12.
Рис. 12. NonStandBusPurchaseReqsWP.cs
using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
namespace PurchasingMgrWP.NonStandBusPurchaseReqsWP
{
[ToolboxItemAttribute(false)]
public class NonStandBusPurchaseReqsWP : WebPart
{
protected override void CreateChildControls()
{
base.CreateChildControls();
SilverlightObjectTagControl slhc =
new SilverlightObjectTagControl();
slhc.Source = SPContext.Current.Site.Url +
"/ClientBin/NonStandBusPurchaseReqsSLOM.xap";
slhc.InitParameters = "url=" + SPContext.Current.Web.Url;
this.Controls.Add(slhc);
}
}
}
Код на рис. 12 создает экземпляр SilverlightObjectTagControl, задает в свойстве Source значение URL приложения Silverlight в ClientBin и настраивает свойство InitParameters на хранение URL текущего сайта (где находится список Non-Standard Business Purchase Requests). Для передачи этого URL конструктору класса MainPage в NonStandBusPurchaseReqsSLOM откройте App.xaml.cs и добавьте в обработчик события Application_Startup следующий код:
private void Application_Startup(object sender,
StartupEventArgs e)
{
string url = e.InitParams["url"];
this.RootVisual = new MainPage(url);
}
Для тестирования веб-фрагмента разверните пакет PurchasingMgr.wsp на локальном сайте Purchasing, чтобы тем самым установить список Non-Standard Business Purchase Requests (этот список был удален, когда мы завершили предыдущий сеанс отладки), а затем отладить решение PurchasingMgrWP из Visual Studio 2010. После добавления в \Purchasing\Home.aspx веб-фрагмент позволяет добавлять элементы в список прямо из Silverlight, как видно на рис. 12 и 13.
Рис. 13. NonStandBusPurchaseReqsWP в действии
Рис. 14. Обновленный список Non-Standard Business Purchase Requests
Разработка с применением локального сайта позволяет использовать Visual Studio 2010 для отладки кода SharePoint и Silverlight 4 до завершения тестирования решения. После этого PurchasingMgrWP.wsp загружается в Solution Gallery в SharePoint Online.
Клиентская OM в SharePoint предоставляет привычный и согласованный объектно-ориентированный API для доступа к спискам и библиотекам в SharePoint Online. Этот API является подмножеством Microsoft.SharePoint API и ограничен областью набора сайтов, что великолепно подходит для разработок, рассчитанных на SharePoint Online.
Решения SharePoint в облаке
SharePoint Online дает разработчикам для SharePoint уникальную возможность создавать решения SharePoint для облака, используя существующие навыки и инструменты. Разобравшись в средствах адаптации SharePoint Online (в том числе что поддерживается, а что — нет), изолированных решениях, клиентской OM в SharePoint и декларативных рабочих процессах, формируемых в SharePoint Designer 2010, вы можете создавать решения SharePoint, способные выполняться в облаке с SharePoint Online. Чтобы быть в курсе всех изменений в SharePoint Online в процессе разработки бета-версий, заглядывайте на сайт SharePoint Online Developer Resource Center (msdn.com/sharepointonline).