SharePoint 2010可以与Silverlight实现紧密集成。不管是在浏览器中运行的Silverlight程序还是单独的一个Silverlight程序,都能与SharePoint 2010实现很好的整合。本文中我们将实现一个Silverlight和SharePoint高度整合的例子,通过SharePoint 2010客户端对象模型访问SharePoint任务列表。同时,我们还将学习如何通过SharePoint自带的Silverlight Web部件来宿主Silverlight应用。下图是根据我个人的理解绘制的Silverlight和SharePoint 2010应用整合示意图。
从上图我们可以看到,我们分别有SharePoint客户端对象模型(OM)和SharePoint Web服务两种API供 Silverlight应用程序调用。 事实上客户端对象模型和服务这两条途径,不仅仅能用在Silverlight中,还可以用于其它的客户端应用程序中。
在开始编写应用程序之前,我们首先了解一下Silverlight和SharePoint之间不同类型的集成模型。我们可以简单的通过HTML以IFrame的方式显示Silverlight应用程序,也可以将Silverlight应用程序宿主在Web部件中,还可以 调用SharePoint对象模型或服务。这些方式彼此之间并没有硬性的分类界限。只是人为的通过使用规模所做的一个区分。 分类如下:
1. 无接触 :通过无接触方式,可以直接把现有的Silverlight应用集成到SharePoint。 目的只是在SharePoint中进行显示。直接使用iframe即可。
2.低接触 :低接触的应用与SharePoint间的互动多了一点。但也仅仅是通过SharePoint 开箱即用的Silverlight Web部件对Silverlight应用进行装载而已。 这个应用程序本身是一个独立的应用程序,它可能会调用一些除SharePoint API以外的其他服务。
之前我的一篇博文中,曾讨论过一个典型的低接触的例子。是关于SharePoint2010整合Silverlight 4应用——Bing地图控件
3.高接触:高接触整合是指利用到SharePoint客户端对象模型或Web服务来读写SharePoint Server信息的应用整合。 应用程序本身可以是一个WPF应用程序,或者是像Silverlight这样的客户端应用程序,或者是ASP.NET 、JavaScript应用程序。下图为一个Silverlight客户端应用程序的高接触整合。
接下来,我们要实现一个Silverlight与SharePoint高接触的应用,通过Silverlight调用客户端对象模型。会对使用客户端对象模型的三种场景都进行描述:
1. 在浏览器中运行的Silverlight应用程序
2. 在浏览器外运行的(Out of Browser,简称OOB)Silverlight应用程序
3. 作为Silverlight XAP文件宿主在SharePoint Web部件中的Silverlight应用程序
首先,我们需要创建一个Silverlight应用程序, 打开Visual Studio 2010>“新建” >“项目” 。 选择Silverlight项目模板,并选择.NET Framework 4.0。将该项目命名为“SilverlightSPIntegration”。
点击“确定”按钮后,会弹一个窗口要求自动创建一个Web应用程序,Silverlight应用程序将自动宿主在该Web应用程序中 。
下一步我们要做的就是编写Silverlight程序来调用客户端对象模型的API 。 右击Silverlight解决方案,选择“添加引用”
这里我们需要添加“Microsoft.SharePoint.Client.Silverlight.dll”和“Microsoft.SharePoint.Client.Silverlight.Runtime.dll”这两个dll。他们位于"C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\ClientBin"文件夹下。
引用添加完成后,整个Silverlight应用程序的文件夹结构如下:
接下来,我们要对Silverlight的XAML进行设计,实现SharePoint网站中的某些功能。如上所述,在本例中,我们会从SharePoint内置的任务列表中读取一些数据 。因此,我们不妨先参考一下SharePoint默认的界面。打开SharePoint网站,从快速启动区中找到“任务”列表并点击它。
这是默认的SharePoint任务列表。 当然你也可以使用任意的列表,甚至是自定义列表。 只需要根据实际的设计修改对应的用户界面和代码即可。现在,为该任务列表输入一些虚拟的数据。
下面是我为的任务列表添加的一些虚拟数据。
至此,我们完成了SharePoint部分的工作。 接下来我们要创建一个自定义的UI,用Silverlight来显示这些数据。 界面比较简陋,只是为了说明两者是如何实现整合的。
返回Visual Studio,在Silverlight解决方案中,设计一些简单的XAML界面。
为了快速设置样式,我用Expression Blend对界面做了一点美化工作。
保存该Expression Blend项目,并在Visual Studio中从我们的Silverlight应用程序中打开。它会要求重新加载应用程序,因为内容在当前环境外被修改了。
以下是Silverlight用户界面的XAML代码:
<!--
<Setter Property="MinWidth" Value="150" />
<Setter Property="MaxWidth" Value="150" />
<Setter Property="HorizontalAlignment" Value="Left" />
-->
<!--
<Setter Property="HorizontalAlignment" Value="Right" />
<Setter Property="Foreground" Value="Orange" />
-->
现在,我们 完成了界面设计。 可以按“F5”运行一下,看看用户界面的样子。
上图就是我们设计的Silverlight应用程序。它托管在ASP.NET Web应用程序里。 现在就可以使用 SharePoint 客户端对象模型来从SharePoint服务器中读取任务列表数据了。
因为我们要通过类来读取列表的信息,所以首先要创建一个任务类型的类,作为任务的容器。下面是任务类代码。
public class Tasks
{
public string Title { get; set; }
public string DueDate { get; set; }
public string Status { get; set; }
public string Priority { get; set; }
public double PercentComplete { get; set; }
}
打开MainPage.XAML.CS文件,添加如下的命名空间
using Microsoft.SharePoint.Client;
添加好命名空间后就可以调用对象模型API了。
下面的示例代码可以从特定的SharePoint站点中获取某列表实例。
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
using (ClientContext SharePointContext = new ClientContext(this.SPWebSiteURL))
{
this.query = new CamlQuery();
SharePointContext.Load(SharePointContext.Web);
this.task = SharePointContext.Web.Lists.GetByTitle("Tasks");
this.strQuery = @" ";
query.ViewXml = this.strQuery;
this.taskLists = this.task.GetItems(this.query);
SharePointContext.Load(this.taskLists);
SharePointContext.ExecuteQueryAsync(this.OnSiteLoadSuccess, this.OnSiteLoadFailure);
}
}
SharePointContext.ExecuteQueryAsync方法的执行是异步的。 该方法使用两个回调函数分别处理成功和失败的返回结果。
如上面的代码所示,如果我们的程序成功执行,它会调用OnSiteLoadSuccess,否则调用 OnSiteLoadFailure。下面是这两个函数实现代码。
private void OnSiteLoadSuccess(object sender, ClientRequestSucceededEventArgs e)
{
foreach (ListItem item in this.taskLists)
{
Tasks objTask = new Tasks();
objTask.Title = item["Title"].ToString();
objTask.DueDate = item["DueDate"].ToString();
objTask.Status = item["Status"].ToString();
objTask.Priority = item["Priority"].ToString();
double fraction = Convert.ToDouble(item["PercentComplete"]);
objTask.PercentComplete = fraction * 100;
this.SharePointTasks.Add(objTask);
}
AddTaskList( this.SharePointTasks);
}
private void OnSiteLoadFailure(object sender, ClientRequestFailedEventArgs e)
{
MessageBox.Show(e.Message + e.StackTrace);
}
接下来,我们需要创建一个委托来更新UI。使用Dispatcher.BeginInvoke ,以避免跨线程调用的异常。
private void AddTaskList()
{
this.Dispatcher.BeginInvoke(new UpdateSilverLightUI(this.AddItemsToLists), this.SharePointTasks);
}
private void AddItemsToLists(List tasks)
{
foreach (Tasks t in tasks)
{
TaskList.Items.Add(t.Title);
}
}
现在,所有的任务已被添加到Silverlight的Task List中,然后我们要处理的ListBox的SelectionChanged事件,并在不同的文本框中显示相应的值。
private void TaskList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var v = this.SharePointTasks.FirstOrDefault(item => item.Title.Equals(TaskList.SelectedItem.ToString()));
if (v != null)
{
txtTitle.Text = v.Title;
txtDueDate.Text = v.DueDate;
txtPriority.Text = v.Priority;
txtStatus.Text = v.Status;
txtPercentage.Value = v.PercentComplete;
}
}
OK,到这里所有的代码编写部分就完成了。但如果你现在尝试运行该应用程序,会得到一个跨域访问异常。因为SharePoint网站宿主在IIS中,而正在运行的应用程序却是在VS里。为了解决这个问题,你必须把clientAccessPolicy.xml文件放到SharePoint站点的根目录。
按F5运行该应用程序。没错,所显示的Silverlight风格的任务列表和前面我们创建的SharePoint列表完全一致。可以点击List中的一个任务来显示详细信息。
至此,我们完成了一个在单独的网站中运行的Silverlight应用,并与SharePoint集成。你可以把这个应用宿主在任何ASP.NET Web应用程序中 。
接下来,让我们把这个Silverlight应用程序变得更有趣些,使其可以在浏览器外运行。事实上仅仅是通过VS2010自带的配置工具做一个小小的修改就OK了。
在解决方案管理器中右键点击Silverlight应用程序 >“属性”,然后勾选“允许在浏览器外运行应用程序” 复选框,如下图所示。
点击“浏览器外设置...”可以做更细的配置。 您可以修改窗口 的高度,宽度和标题等。
完成浏览器外设置后,再运行该应用程序,你会发现它现在和Windows应用程序运行效果很相似.
我们已经实现了在浏览器中和在浏览器外的Silverlight应用与SharePoint 集成。
如何将Silverlight应用作为一个SharePoint Web部件宿主在SharePoint中呢。 其实和在一般网站中一样,SharePoint也是通过Silverlight的XAP文件实现宿主的,之前我已经在上次讲地图控件的时候提到过。
首先,我们在与上面的例子相同的解决方案下,新建一个SharePoint 2010项目。选择“ 空白SharePoint项目 ”模板。
为项目命名,然后单击“ 确定 ”。接下来将显示如下的部署向导。
要求输入作为调试的SharePoint网站的位置和部署类型。 你可以使用默认的选择。 点击“ 确定 ”, 完成对SharePoint项目的创建。
现在,我们需要添加一个SharePoint项——模块。 模块包含一个待部署的文件,本身需要包含在一个SharePoint项目中。 要添加一个模块,可以在SharePoint项目上右击,并点击添加新项。
在SharePoint 2010分类下,选择“模块”,为其命名,点击“ 添加 ”。 然后右击该模块, 点击“ 属性 ”。
在属性窗口的“ 项目输出引用 ”选择器中,做如下图的设置。
请注意,你需要选择部署类型为“ElementFile”,项目名称应该是Silverlight解决方案的名称 。点击确定 。这是SharePoint模块的“Element.XML”文件中,会添加到Silverlight的xap文件的路径。通过这种方式可以把Silverlight应用添加到SharePoint网站中,使其成为SharePoint的一部分。
完成我们的SharePoint项目后,就可以编译部署了。 右键单击SharePoint项目,选择部署。这样就完成了部署操作。
接下来,我们将其宿主到SharePoint网站的Silverlight Web部件。
Silverlight Web部件和其他Web部件的使用一样。首先你需要打开SharePoint页面的编辑模式,转到插入,选择Web部件。 选择“ 媒体与内容 ”类别,选择SharePoint 自带的Silverlight Web部件。 点击添加 。
你会看到一个Ajax弹出对话框,要求输入Silverlight 应用程序包(XAP )文件的URL。这里填写上面我们在SharePoint模块的Element. XML文件中指定的URL。
点击确定。运行成功的话,Silverlight Web部件的显示如下图所示。
如果没有写对URL,保存后会看到如下的错误信息。 提示你可能提供的XAP文件路径有错误,请重新配置。
这时,你必须首先确保你提供的XAP文件路径是有效的。 如果路径有效,再检查一下相应的功能是否已经被激活(可以从网站操作>网站设置中找到管理功能的链接)。
如果愿意,我们可以把SharePoint的任务列表和 Silverlight WebPart放在一个页面上。
这样当我们在任务列表中添加一项新的任务后,新任务同时会反映在我们的Silverlight任务控件中。
如果不想这么麻烦的部署一个XAP文件,也可以简单的把XAP上传到一个文档库中。然后在Web部件中直接指定其在文档库中的路径即可。
当然,你还可以创建一个SharePoint 2010项目,包含一个自定义Web部件宿主Silverlight应用,然后再部署该Web部件。
希望对你有帮助!
参考资料:
Silverlight Task Control For SharePoint 2010 - Example of Hight Touch Integration