我们将要编写的头条新闻筛选消费者WebPart是要从Microsoft.SharePoint.WebPartPages.WebPart类继承而来。因此,必须添加Windows SharePoint Services的程序集;由于使用到了Excel Services,还要引用Excel Services的程序集,以便允许使用其中的类。
下面的步骤是展示了如何直接连接到Excel Web Serivces库。之所以如此是因为头条新闻WebPart运行域SharePoint环境中,这与使用SOAP通过HTTP访问Web service的方式不同。在我们的这种场景下直接连接可以提供更高的性能和安全性,并允许我们的头条新文WebPart可以工作在所有的SharePoint拓扑结构下。而当我们创建独立的Web应用程序(Web应用程序并不运行在SharePoint中)时,实际上是真正用到Web service的接口。关于何时选择使用SOAP方式通过HTTP访问,何时直接连接到Excel Web Services DLL,您可以参考这篇MOSS SDK文章:Loop-back SOAP Calls and Direct Linking
如果Visual Studio运行在Office SharePoint Server 2007服务器上,请以下面的步骤进行引用:
项目->添加引用,出现添加引用对话框。
点击.NET标签,选择Excel Web Service 组件(Microsoft.Office.Excel.Server.WebServics.dll)。接着向下滚动,找到Windows SharePoint Services组件(Microsoft.SharePoint.dll),按住Ctrl键,再选择。
确定,完成引用的添加。
如果Visual Studio与Office SharePoint Server 2007不在同一台机器上,我们需要从一台装有Office SharePoint Server 2007的机器上拷贝该文件到我们的开发环境所在机器的项目文件夹下。默认情况下,Microsoft.SharePoint.dll和Microsoft.Office.Excel.Server.WebServics.dll位于装有SharePoint的机器的以下目录中:
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\ISAPI 拷贝过来后,将这两个文件添加到引用中。
添加到本地拷贝的程序集的引用
项目->添加引用,出现添加引用对话框。
点击浏览,导航到放Windows SharePoint Services和Excel Web Service程序集文件的目录
选中Microsoft.SharePoint.dll 和Microsoft.Office.Excel.Server.WebServices.dll 文件。
确定,完成引用的添加。
如果要使Excel Web Service正常工作,还需要添加到System.Web.Services程序集的引用:
using wsswebparts = Microsoft.SharePoint.WebPartPages;
using aspnetwebparts = System.Web.UI.WebControls.WebParts;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Collections.ObjectModel;
using Microsoft.Office.Excel.Server.WebServices; 引用这些命名空间可以使我们方便的使用其中的类库和类型,而不必通过使用完整的命名空间路径来访问。
// Get the list of headlines from the Excel workbook by calling
// Excel Web Services.
// Initialize Excel Web Services.
ExcelService es = new ExcelService();
// Open the workbook. This actionloads the workbook from the
// specified URL and returns a sessionId that can be used to
// perform further operations on the workbook. Replace the
// <TrustedLocation> placeholder with a full Windows SharePoint
// Services location, network file share, or Web folder address
// of the trusted location of the Excel workbook containing
// the news headlines. Replace the <Workbook>
// placeholder with the name of the Excel workbook containing
// the news headlines.
try
{
sessionId =
es.OpenWorkbook("<TrustedLocation>/<Workbook>.xlsx",
string.Empty, string.Empty, out status);
}
catch
{
sessionId = null;
}
// Ensure that the workbook has been successfully opened on the
// server. If not, show an error message to the user.
if (sessionId == null)
{
ShowError("Error opening workbook. Check the URL in " +
"OpenWorkbook, and be sure that the workbook is in " +
"a trusted location");
return;
}
// Retrieve the headlines/regions currently defined in the
// workbook from Excel Services and add them to the collection of
// headlines. Or, if there is a problem getting the headlines,
// show an error to the user.
// The code shown below assumes the following:
//
// - The opened workbook contains a worksheet named "Sheet1".
// - The "Sheet1" worksheet contains a range named "Headlines".
// - The "Headlines" range is two columns wide with the first
// column containing a news headline and the second column
// containing a region.
object[] AllHeadlines = es.GetRangeA1(sessionId, "Sheet1",
"Headlines", true, out status);
if (AllHeadlines != null)
{
unfilteredHeadlines = new List<Headline>();
foreach (object[] HeadlineRow in AllHeadlines)
{
unfilteredHeadlines.Add(
new Headline(Convert.ToString(HeadlineRow[0]),
Convert.ToString(HeadlineRow[1])));
}
}
else
{
ShowError("Error getting headlines from workbook.");
return;
}
}
private void ShowError(string message)
{
// Show an error message to the user, and remove all other
// controls from the Web Part.
lblError.Text = message;
this.Controls.Clear();
this.Controls.Add(lblError);
}
// Use the ConnectionConsumer attribute to specify a callback
// method that the Web Part framework can use to provide filter
// provider instances.
[aspnetwebparts.ConnectionConsumer("News Headlines",
"IFilterValues", AllowsMultipleConnections = true)]
public void SetConnectionInterface(
wsswebparts.IFilterValues filterProvider)
{
if (filterProvider != null)
{
// Add the filter provider to the list of providers.
this.filterProviders.Add(filterProvider);
// Tell the provider the parameter we are looking for.
List<wsswebparts.ConsumerParameter> l =
new List<wsswebparts.ConsumerParameter>();
l.Add(new wsswebparts.ConsumerParameter("Region",
wsswebparts.ConsumerParameterCapabilities.SupportsMultipleValues |
wsswebparts.ConsumerParameterCapabilities.SupportsAllValue));
filterProvider.SetConsumerParameters(
new ReadOnlyCollection<wsswebparts.ConsumerParameter>(l));
}
}
// Call Excel Web Services to get the list of all
// news headlines.
GetHeadlinesUsingWebService();
// The filtering logic performs a union of all of the
// filters (a logical OR). If we didn't get any filter
// providers or if any of the filters send the "All" value
// (that is, provider.ParameterValues == null), we don't
// need to filter and we can return all of the
// headlines.
List<Headline> filteredHeadlines = null;
bool shouldFilter = true;
if (this.filterProviders.Count == 0)
{
shouldFilter = false;
}
else if (this.filterProviders.Count > 0)
{
foreach (wsswebparts.IFilterValues filterProvider in
this.filterProviders)
{
if (filterProvider.ParameterValues == null)
{
// Some filter sent "All"--don't bother with the
// rest of the filtering.
shouldFilter = false;
break;
}
}
}
if (!shouldFilter)
{
// The "filtered" headlines are unfiltered.
filteredHeadlines = this.unfilteredHeadlines;
}
else
{
// Just fill in the headlines that match the filters.
filteredHeadlines = new List<Headline>();
// Create a lookup from region to a list of headlines that
// correspond to that region.
Dictionary<string, List<Headline>> regionHeadlineMap =
new Dictionary<string, List<Headline>>();
foreach (Headline headline in this.unfilteredHeadlines)
{
List<Headline> headlinesForRegion = null;
if (!regionHeadlineMap.TryGetValue(headline.Region,
out headlinesForRegion))
{
headlinesForRegion = new List<Headline>();
regionHeadlineMap.Add(headline.Region,
headlinesForRegion);
}
headlinesForRegion.Add(headline);
}
foreach (wsswebparts.IFilterValues filterProvider in
this.filterProviders)
{
ReadOnlyCollection<String> values =
filterProvider.ParameterValues;
if (values != null)
{
foreach (string v in values)
{
if (v == null)
{
// This indicates the "Empty" value, which
// doesn't apply to headlines, because
// they all have regions.
}
else
{
List<Headline> matchedHeadlines;
if (regionHeadlineMap.TryGetValue(v,
out matchedHeadlines))
{
foreach (Headline matchedHeadline in
matchedHeadlines)
{
if
(!filteredHeadlines.Contains(matchedHeadline))
{
filteredHeadlines.Add(matchedHeadline);
}
}
}
}
}
}
}
}
// Display the filtered headlines.
headlinesDataGrid.DataSource = filteredHeadlines;
headlinesDataGrid.DataBind();