上次修改时间: 2015年3月9日
适用范围: SharePoint Server 2010
本文内容
自定义数据提供程序
Visio Services API
创建自定义数据提供程序
创建示例文件
创建自定义数据提供程序并将它部署到 SharePoint Server
创建和编译 Visual Studio 2010 解决方案
创建和运行 PowerShell 脚本
向 Visio Graphics Service 添加新的受信任数据提供程序
测试示例自定义数据提供程序
使用 Visio Services 可以显示在 Microsoft SharePoint Server 2010 的 Visio Web Access Web 部件中作为 .vdw 文件发布的 Microsoft Visio 2010 绘图。您可以使用 Visio Services 类库生成自定义 Visio Services 数据模块或自定义数据提供程序,它允许您以编程方式刷新从位于 Microsoft SharePoint Server 2010 网站上的 Visio 2010 Web 绘图中的自定义数据源派生的数据。
本主题介绍 Visio Services 类库中最重要的类和方法,如何创建和部署使用来自 XML 文件中数据的示例自定义数据提供程序,以及如何创建包含与可由自定义数据提供程序刷新的数据的连接的示例 Visio .vdw 文件。
自定义数据提供程序
Visio 绘图可以使用来自各种标准数据提供程序的数据,包括 Microsoft Excel 文件、SharePoint 列表、SQL 数据库以及任何其他与 ODBC 兼容的数据源。此功能扩展到 Visio 客户端中显示的绘图以及 SharePoint 网页上 Visio Web Access Web 部件中显示的 Visio 绘图(.vdw 文件)。在希望绘图从前面的数据源以外的其他数据源派生数据的情况下,可以创建自定义数据提供程序。自定义数据提供程序可以连接到来自 XML 文件的数据,如本文中"创建自定义数据提供程序"一节开始的示例中所示,并且可以连接到来自 Web 服务、OLAP 多维数据集和许多其他数据源的数据。您必须编写代码才能创建自定义数据提供程序,在已安装 SharePoint Server 2010 并运行 Visio Services 的服务器上安装此自定义数据提供程序,然后将自定义数据提供程序添加到 Visio Services 的受信任数据提供程序的列表中。
Visio Services API
Visio Services API 由两个类及其关联方法组成:AddonDataHandler 抽象基类和 AddonDataHandlerException 类。这些类构成 Microsoft.Office.Visio.Server 命名空间,并且分布在文件 Microsoft.Office.Visio.Server.dll 中。例如,在您的解决方案代码中创建一个名为 VisioCustomDataProvider 的类,它继承自并实现 AddonDataHandler 基类和 IAsyncResult 接口。本文中描述的 VisioCustomDataProvider.cs 文件提供如何实现此接口的示例。
AddonDataHandler 基类
自定义数据模块用于查询服务器对其没有内置支持的数据源。自定义数据模块由公共类表示,该类从 AddonDataHandler 继承并实现其抽象成员以及 IAsyncResult 接口。本文中介绍的示例解决方案提供如何实现这些成员的示例。
表 1. AddonDataHandler 基类成员
成员名称 |
说明 |
|---|---|
由 Visio Services 调用,以便开始从由自定义数据提供程序指定的数据源检索数据。在实现此方法时,请将它设计为尽快返回,因为自定义数据提供程序需要异步运行。 |
|
在此自定义数据提供程序已完成检索数据时,由 Visio Services 调用。此方法必须以 ADO.NET DataSet 对象的形式向 Visio Services 返回由自定义数据提供程序检索的数据。 |
|
Cancel() 方法 |
在检测错误或者为检索数据分配的最大时间已过但数据检索没有完成时,由 Visio Services 调用以停止数据的异步处理。 |
Data 属性 |
指定自定义数据提供程序必须为其填充更新的数据并返回到 Visio Services 的 ADO.NET DataSet 对象。 |
QueryString 属性 |
指定与自定义数据提供程序正在刷新的 Visio DataRecordset 对象关联的命令字符串。当刷新绘图时,Visio Services 从 Web 绘图(.vdw 文件)中分析出此字符串,然后为此属性指定其值。此字符串是以分号分隔的键/值对的列表。每一对包含键和值,以等号分隔。字符串应为如下格式:"DataModule=ClassFullName, SimpleAssemblyName; Key1=Value1;Key2=Value2;…",此处 ClassFullName 是类的名称,包含命名空间;SimpleAssemblyName 是程序集的名称,没有任何其他标识信息。作为开发人员,您可以随意使用字符串(键/值对)的其余部分。有关此字符串的详细信息,请参阅本文中"在 .vdw 文件中指定在服务器上使用的数据模块"一节。 此属性的值等于关联的 Visio DataRecordset 对象的 CommandString 属性的值。 备注 有关此字符串的示例,请参阅本文中的代码。 |
指定与自定义数据提供程序正在刷新的 Visio DataRecordset 对象关联的连接字符串。当刷新绘图时,Visio Services 从 Web 绘图(.vdw 文件)分析出此字符串,然后为此属性指定其值。此字符串的格式是以分号分隔的键/值对的列表。每一对包含键和值,以等号分隔。 此属性的值等于关联的 VisioDataRecordset 对象的 ConnectionString 属性的值。 |
|
Error 属性 |
返回一个异常对象,它描述在此自定义数据提供程序无法从其关联的外部数据源检索数据时发生的错误。此属性可用于将有关异步处理过程中发生的故障的错误信息传播到调用程序。如果此异常的类型是 AddonDataHandlerException,则向用户原样显示该异常消息;否则,向用户显示常规消息。 |
AddonDataHandlerException 类
AddonDataHandlerException 基类表示一个异常,Visio Services 可引发此异常以向用户通知错误消息。
您可以将 AddonDataHandler 类的 Error 属性设置为任意类型的异常。如果异常的类型是 AddonDataHandlerException,则向用户显示描述此异常的错误消息(包含传递到 AddonDataHandlerException 对象的构造函数的 message 参数的值);否则,显示常规错误消息。
创建自定义数据提供程序
按照这些常规步骤创建自定义数据提供程序。在本文后面(从下一节"创建示例文件"开始)详细介绍了每个步骤。
创建自定义数据提供程序
创建示例文件并将其部署到 SharePoint Server 2010 计算机。
这些示例文件包含存储服务器数据的 XML 文件和要在 SharePoint 网站上显示的 Visio 2010 Web 绘图(.vdw)文件。此绘图将显示自定义数据提供程序从 Visio 2010 本身不支持的数据源检索的数据。
在 SharePoint Server 2010 计算机上,创建和编译可实现 Visio Services API 的 Visual Studio 2010 解决方案来创建自定义数据提供程序。
使用 Windows PowerShell 脚本或其他方法将自定义提供程序部署到 SharePoint Server 2010 计算机。
在 SharePoint 管理中心中,将自定义数据提供程序添加到 Visio Graphics Service 受信任数据源的列表。
通过在服务器上的 Visio Web Access Web 部件中呈现 Visio 绘图,测试示例自定义数据提供程序。
现在,当您更改数据源中数据并刷新 Visio 绘图时,将使用来自服务器的数据刷新当前 Web 绘图页,这最终反映您所做的更改。
备注
刷新绘图并非始终会立即反映在数据源中所做的更改,这是因为在服务器上缓存数据的方式造成的。
创建示例文件
必须创建 XML 数据文件和示例 Visio .vdw 文件才能发布到 SharePoint Server 计算机。通过 Visual Basic for Applications (VBA) 代码,示例 .vdw 文件将显示导入绘图中的初始数据。在 Visio Web Access Web 部件中呈现绘图后,您可以修改 XML 文件中的数据(它最初与绘图中的数据相同),然后刷新绘图以显示修改的数据。
图 1 显示 Visio 绘图在完成时的外观。
图 1. 完成的 Visio 绘图
.jpg)
创建发布到服务器上的 XML 数据文件
若要创建发布到服务器上的 XML 数据文件,请按照以下步骤操作。
创建发布到服务器上的 XML 数据文件
在 Notepad 或其他文本编辑器中,创建一个文件。
将以下代码粘贴到文件中。
<?xml version="1.0" standalone="yes"?> <DemoDataDataSet> <xs:schema id="NewDataSet" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xs:element name="DemoDataDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true"> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="SuperMarketData"> <xs:complexType> <xs:sequence> <xs:element name="Name" minOccurs="0"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:maxLength value="50" /> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="IP" minOccurs="0"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:maxLength value="50" /> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="Status" minOccurs="0"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:maxLength value="50" /> </xs:restriction> </xs:simpleType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> </xs:element> </xs:schema> <SuperMarketData> <Name>sql-sales-01</Name> <IP>10.0.5.1</IP> <Status>Online</Status> </SuperMarketData> <SuperMarketData> <Name>sql-sales-02</Name> <IP>10.0.5.2</IP> <Status>Online</Status> </SuperMarketData> <SuperMarketData> <Name>filestore-sales-01</Name> <IP>10.0.5.3</IP> <Status>Online</Status> </SuperMarketData> <SuperMarketData> <Name>webserver-01</Name> <IP>10.0.5.0</IP> <Status>Online</Status> </SuperMarketData> </DemoDataDataSet>将文件命名为 VisioCustomData.xml,然后将它保存到可以轻松访问的位置。
在前面的 XML 代码中,要显示的实际数据包含在文件末尾附近的 <SuperMarketData> 标记的集合中,如表 2 中所示。
表 2. 要在 Visio 文件中显示的数据
计算机名称 |
IP 地址 |
状态 |
|---|---|---|
sql-sales-01 |
10.0.5.1 |
联机 |
sql-sales-02 |
10.0.5.2 |
联机 |
filestore-sales-01 |
10.0.5.3 |
脱机 |
webserver-01 |
10.0.5.0 |
联机 |
在构建 Visio 2010 图表时,使用下一节中显示的 VBA 代码将此数据直接导入图表中以建立要显示的初始数据。接下来,在 SharePoint Server 2010 中显示图表后,可以修改服务器上 XML 文件中的数据,然后使用来自服务器的数据刷新呈现的绘图。
创建示例 Visio .vdw 文件
首先,结合使用 Visio 用户界面 (UI) 和 Visio 的 Visual Basic 编辑器中的 VBA 代码来创建要显示数据的 Visio 绘图。接下来,使用 VBA 将数据导入 Visio 的数据记录集中,然后将该数据记录集中的数据链接到绘图页上的形状。另外,为新创建的数据记录集分配连接发布的绘图和服务器上自定义数据提供程序的命令字符串。最后,使用 Visio 用户界面自定义数据图形以显示与单个形状关联的数据。
在 ImportData 过程中,VBA 代码使用 DataRecordset.AddFromXML 方法将数据添加到绘图中。如果在自己的项目中使用此方法,则发布到服务器的 XML 文件必须包含与使用 VBA 导入绘图中的数据相同的数据并具有相同的数据结构:这就是说,它必须具有相同的列数、相同的行数并且每个列的数据类型相同。
创建示例 Visio .vdw 文件
在 Visio 2010 中,创建一个空绘图。单击"文件",然后单击"新建"。在"开始使用的其他方式"下,单击"空绘图",然后单击"创建"。
将绘图保存为 .vdw 文件。单击"文件",然后单击"保存"。浏览到希望保存该文件的位置。对于文件名,键入 SampleDiagram。在"保存类型"列表中,单击"Web 绘图(*.vdw)",然后单击"保存"。
按 ALT+F11 打开 Visual Basic 编辑器。
在项目资源管理器窗格中,双击"ThisDocument(SampleDiagram)"项目。
将以下代码粘贴到代码窗格中。
备注
以下代码打开具有美国单位的模具。如果要使用具有公制单位的模具,请分别将模具名称修改为"COMPS_M.VSS"、"NETLOC_M.VSS"和"SERVER_M.VSS"。
Sub ChangeOrientationAndOpenStencils() 'Enable diagram services. Dim DiagramServices As Integer DiagramServices = ActiveDocument.DiagramServicesEnabled ActiveDocument.DiagramServicesEnabled = visServiceVersion140 Application.ActiveWindow.ViewFit = visFitPage Application.ActiveWindow.Page.PageSheet.CellsSRC(visSectionObject, visRowPage, visPageWidth).FormulaU = "11 in" Application.ActiveWindow.Page.PageSheet.CellsSRC(visSectionObject, visRowPage, visPageHeight).FormulaU = "8.5 in" Application.ActiveWindow.Page.PageSheet.CellsSRC(visSectionObject, visRowPrintProperties, visPrintPropertiesPageOrientation).FormulaForceU = "2" Application.EndUndoScope UndoScopeID1, True Application.Documents.OpenEx "server_u.vss", visOpenRO + visOpenDocked Application.Documents.OpenEx "netloc_u.vss", visOpenRO + visOpenDocked Application.Documents.OpenEx "comps_u.vss", visOpenRO + visOpenDocked 'Restore diagram services ActiveDocument.DiagramServicesEnabled = DiagramServices End Sub Sub DropAndConnectShapes() Dim DiagramServices As Integer Dim vsoShapeServer1 As Shape Dim vsoShapeServer2 As Shape Dim vsoShapeServer3 As Shape Dim vsoShapeWebServer As Shape Dim vsoShapeCloud As Shape Dim vsoShapePC As Shape Dim vsoSelection As Selection 'Enable diagram services. DiagramServices = ActiveDocument.DiagramServicesEnabled ActiveDocument.DiagramServicesEnabled = visServiceVersion140 Set vsoShapePC = Application.ActiveWindow.Page.Drop(Application.Documents.Item("COMPS_U.VSS").Masters.ItemU("PC"), 10#, 4.5) Set vsoShapeCloud = Application.ActiveWindow.Page.Drop(Application.Documents.Item("NETLOC_U.VSS").Masters.ItemU("Cloud"), 8#, 4.5) vsoShapeCloud.AutoConnect vsoShapePC, visAutoConnectDirRight Set vsoShapeWebServer = Application.ActiveWindow.Page.Drop(Application.Documents.Item("SERVER_U.VSS").Masters.ItemU("Web Server"), 6#, 4.5) vsoShapeWebServer.AutoConnect vsoShapeCloud, visAutoConnectDirRight Set vsoShapeServer1 = Application.ActiveWindow.Page.Drop(Application.Documents.Item("SERVER_U.VSS").Masters.ItemU("Server"), 2#, 2) vsoShapeServer1.AutoConnect vsoShapeWebServer, visAutoConnectDirRight Set vsoShapeServer2 = Application.ActiveWindow.Page.Drop(Application.Documents.Item("SERVER_U.VSS").Masters.ItemU("Server"), 2#, 4.5) vsoShapeServer2.AutoConnect vsoShapeWebServer, visAutoConnectDirRight Set vsoShapeServer3 = Application.ActiveWindow.Page.Drop(Application.Documents.Item("SERVER_U.VSS").Masters.ItemU("Server"), 2#, 7) vsoShapeServer3.AutoConnect vsoShapeWebServer, visAutoConnectDirRight ActiveWindow.DeselectAll ActiveWindow.Select vsoShapeWebServer, visSelect Application.ActiveWindow.Selection.Move 1.5, 0# 'Restore diagram services. ActiveDocument.DiagramServicesEnabled = DiagramServices End Sub Sub ImportData() 'Enable diagram services Dim DiagramServices As Integer DiagramServices = ActiveDocument.DiagramServicesEnabled ActiveDocument.DiagramServicesEnabled = visServiceVersion140 Application.ActiveWindow.Windows.ItemFromID(visWinIDExternalData).Visible = True Dim strXML As String Dim strXML1 As String Dim strXML2 As String Dim strName As String Dim vsoDataRecordset As Visio.DataRecordset strName = "Server Data" strXML1 = "<xml xmlns:s='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882'" + Chr(10) _ & "xmlns:dt='uuid:C2F41010-65B3-11d1-A29F-00AA00C14882'" + Chr(10) _ & "xmlns:rs='urn:schemas-microsoft-com:rowset'" + Chr(10) _ & "xmlns:z='#RowsetSchema'><s:Schema id='RowsetSchema'>" + Chr(10) _ & "<s:ElementType name='row' content='eltOnly' rs:updatable='true'>" + Chr(10) _ & "<s:AttributeType name='c0' rs:name='_Visio_RowID_' rs:number='1'" + Chr(10) _ & "rs:nullable='true' rs:maydefer='true' rs:write='true'>" + Chr(10) _ & "<s:datatype dt:type='int' dt:maxLength='4' rs:precision='0'" + Chr(10) _ & "rs:fixedlength='true'/></s:AttributeType>" + Chr(10) _ & "<s:AttributeType name='Name' rs:number='2' rs:nullable='true'" + Chr(10) _ & "rs:maydefer='true' rs:write='true'>" + Chr(10) _ & "<s:datatype dt:type='string' dt:maxLength='255' rs:precision='0'/>" + Chr(10) _ & "</s:AttributeType>" + Chr(10) _ & "<s:AttributeType name='IP' rs:number='3' rs:nullable='true'" + Chr(10) _ & "rs:maydefer='true' rs:write='true'>" + Chr(10) _ & "<s:datatype dt:type='string' dt:maxLength='255' rs:precision='0'/>" + Chr(10) _ & "</s:AttributeType>" strXML2 = " <s:AttributeType name='Status' rs:number='4' rs:nullable='true'" + Chr(10) _ & "rs:maydefer='true' rs:write='true'>" + Chr(10) _ & "<s:datatype dt:type='string' dt:maxLength='255' rs:precision='0'/>" + Chr(10) _ & "</s:AttributeType>" + Chr(10) _ & "<s:extends type='rs:rowbase'/>" + Chr(10) _ & "</s:ElementType></s:Schema>" + Chr(10) _ & "<rs:data>" + Chr(10) _ & "<z:row c0='1' Name='sql-sales-01' IP='10.0.5.1' Status='Online'/>" + Chr(10) _ & "<z:row c0='2' Name='sql-sales-02' IP='10.0.5.2' Status='Online'/>" + Chr(10) _ & "<z:row c0='3' Name='filestore-sales-01' IP='10.0.5.3' Status='Offline'/>" + Chr(10) _ & "<z:row c0='4' Name='webserver-01' IP='10.0.5.0' Status='Online'/>" + Chr(10) _ & "</rs:data></xml>" strXML = strXML1 + strXML2 ' Create a new DataRecordset object. For more information about ' connecting to data in Visio, see "About Connecting to Data" ' in the Visio Developer Reference. Set vsoDataRecordset = ThisDocument.DataRecordsets.AddFromXML(strXML, 0, strName) vsoDataRecordset.CommandString = "DataModule=DataModules.VisioCustomDataProvider,VisioCustomDataProvider;File=c:\VisioCustomData.xml" 'Restore diagram services. ActiveDocument.DiagramServicesEnabled = DiagramServices End Sub ' Link the data in the DataRecordset object to the shapes on the page. ' For more information about linking data to shapes in Visio, ' see "About Linking Shapes to Data" in the Visio Developer Reference. Sub LinkDataToShapes() 'Enable diagram services. Dim DiagramServices As Integer DiagramServices = ActiveDocument.DiagramServicesEnabled ActiveDocument.DiagramServicesEnabled = visServiceVersion140 ActiveWindow.DeselectAll ActiveWindow.Select Application.ActiveWindow.Page.Shapes(10), visSelect Application.ActiveWindow.Selection.LinkToData 1, 1, True ActiveWindow.DeselectAll ActiveWindow.Select Application.ActiveWindow.Page.Shapes(8), visSelect Application.ActiveWindow.Selection.LinkToData 1, 2, True ActiveWindow.DeselectAll ActiveWindow.Select Application.ActiveWindow.Page.Shapes(6), visSelect Application.ActiveWindow.Selection.LinkToData 1, 3, True ActiveWindow.DeselectAll ActiveWindow.Select Application.ActiveWindow.Page.Shapes(4), visSelect Application.ActiveWindow.Selection.LinkToData 1, 4, True 'Restore diagram services. ActiveDocument.DiagramServicesEnabled = DiagramServices End Sub按列出的顺序运行前面代码中的每个过程。
保存该文件。
增强示例 Visio .vdw 文件中的数据图形
此时,您的基础示例文件基本完整。它包含以数据图形形式链接到 XML 数据并显示该数据的形状。不过,您可能希望自定义 Visio 应用的标准数据图形,它们覆盖连接符并缺少有关服务器状态的信息。您可以轻松增强外观和功能并改进数据图形相对于其关联形状的位置。若要增强示例 Visio .vdw 文件中的数据图形以显示如图 1 中的外观,请按照以下步骤操作。
增强示例 Visio .vdw 文件中的数据图形
右键单击三个服务器形状中任意一个,指向"数据",然后单击"编辑数据图形"。
在"默认位置"下的"水平"列表中,选择"最左边",然后单击"应用"。
选择"名称"数据字段,然后单击"编辑项目"。
在"样式"列表中,选择"标题 3",单击"确定",然后单击"应用"以应用更改。
单击"新项目"。
在"数据字段"列表中,选择"状态",然后在"显示为"列表中,选择"按值显示颜色"。
对于"联机"状态,在"填充颜色"列表中的"标准颜色"下,选择"绿色",单击"确定",然后单击"应用"。
右键单击 Webserver 形状,指向"数据",然后单击"编辑数据图形"。
在"默认位置"下的"水平"列表中,选择"居中",然后在"垂直"列表中,选择"形状下方"。
在"将更改应用于"下,选择"仅所选形状",单击"应用",然后单击"确定"。
在 .vdw 文件中指定在服务器上使用的数据模块
当您创建要在 SharePoint Server 2010 计算机上显示的 Visio .vdw 文件时,可以指定要在该计算机上使用的数据模块,如下所示。可使用格式为"DataModule=ClassFullName,SimpleAssemblyName;"的字符串指定数据模块。可以通过在 DataRecordset.DataConnection.ConnectionString 属性值中包含该字符串来指定数据模块,该属性值与服务器上的 ConnectionString 属性的值相对应。当 DataRecordset 对象没有 DataConnection 引用时,可以通过在 DataRecordset.CommandString 属性值中包含该字符串来指定数据模块,该属性值与服务器上的 QueryString 属性相对应。在此情况下,还在 ConnectionString 中复制了字符串。服务器从 ConnectionString 分析出数据模块字符串,然后使用它加载模块。运行模块之前,服务器从 ConnectionString 值中删除数据模块字符串。通常可由开发人员决定在查询字符串中指定有关数据模块的其他信息,格式为"Key1=Value1;Key2=Value2;..."等等。
将示例文件部署到 SharePoint Server 计算机
在完成 Visio .vdw 文件(包含要发布到 SharePoint 网页的外部数据)后,将它和前面创建的 XML 文件发布到运行 Visio Services 的 SharePoint Server 2010 计算机。
将示例文件部署到 SharePoint Server 计算机
将前面创建的源 XML 数据文件复制到 SharePoint Server 2010 计算机上的位置(在 Visio 绘图的命令字符串中指定了该位置)。在本文的示例中,该位置是 c:\ 驱动器的根目录。
将包含外部 XML 数据的示例 Visio .vdw 文件复制到服务器上的文档库中。
创建自定义数据提供程序并将它部署到 SharePoint Server
按照这些通用步骤创建自定义数据提供程序并将其部署到运行 Visio Services 的 SharePoint Server 2010 计算机。
创建自定义数据提供程序并将其部署到 SharePoint Server
在 SharePoint Server 2010 计算机上,创建本文中介绍的 Microsoft Visual Studio 2010 解决方案,然后编译它。
这会将 SharePoint 解决方案包(.wsp 文件)保存到项目中指定的位置。在本文的示例中,该位置是 c:\ 驱动器的根目录。
根据此处显示的文本,在 SharePoint Server 2010 计算机上的位置(在 Visio 绘图的命令字符串中指定了该位置)创建一个 Windows PowerShell 脚本文件。同样,在本文的示例中,该位置是 c:\ 驱动器的根目录。
运行 Windows PowerShell 脚本。
将新的受信任的提供程序添加到 SharePoint Server 2010 管理中心中受信任的提供程序的列表。
双击 Visio .vdw 文件以便在 Visio Web Access Web 部件中呈现它。
以下过程详细解释如何执行更复杂的步骤。
创建和编译 Visual Studio 2010 解决方案
在编译后,您在此处创建的 Visual Studio 2010 解决方案会在 c:\ 驱动器根目录生成一个解决方案包,已在该目录存放示例的其他重要文件。Visual Studio 2010 解决方案引用 Visio Services 和 SharePoint。
创建和编译 Visual Studio 2010 解决方案
在 SharePoint Server 2010 计算机上的 Visual Studio 2010 中,新建一个 Visual C# 类库项目,然后将解决方案保存为 CustomDataProvider。
添加对 System.Web 命名空间的引用。在"解决方案资源管理器"中,右键单击"引用",单击"添加引用",单击".NET",选择"System.Web",然后单击"确定"。
添加对 Visio Services 的引用。在"解决方案资源管理器"中,右键单击"引用",单击"添加引用",然后单击"浏览"。导航到您的计算机上 Windows 文件夹的路径\assembly\GAC_MSIL\Microsoft.Office.Visio.Server\ 14.0.0.0__71e9bce111e9429c,选择"Microsoft.Office.Visio.Server.dll",然后单击"确定"。
将 Visual Studio 2010 创建的泛型 Class1.cs 类文件重命名为 VisioCustomDataProvider.cs。
在"项目"菜单上,单击"CustomDataProvider 属性"。将"程序集名称"更改为 VisioCustomDataProvider,然后将"默认命名空间"更改为 DataModules。
打开 VisioCustomDataProvider.cs 文件,选择现有内容,然后粘贴以下代码以覆盖文件中现有文本。代码注释提供有关代码执行的操作的文档。
/* VisioCustomDataProviders.cs * <copyright>Copyright (c) Microsoft Corporation. All rights reserved.</copyright> * <summary>This class demonstrates how to add support for a custom * data source to Visio Services by creating a custom data provider. * In this sample, the data source is an XML text file saved on the hard disk * of the computer running this custom data provider, typically a SharePoint Server * front-end Web server.</summary> * */ using System; using System.Data; using System.Threading; using System.Web; using System.Xml; using Microsoft.Office.Visio.Server; namespace DataModules { /// <summary> /// This class demonstrates how to add support for a custom data source /// to Visio Services by creating a custom data provider. The class must /// inherit from the AddonDataHandler abstract class, which includes the /// following members: /// /// this.Data: The ADO.NET DataSet that describes the data required by the /// Visio Graphics Server. /// The custom data provider can fill this DataSet with updated /// data and return it to Visio Services. It is up to the /// implementation to specify the type of each DataColumn and /// to ensure data type compatibility with Visio Services. /// /// this.ConnectionString: The connection string associated with the Visio /// DataRecordset being refreshed by this custom /// data provider. This string is parsed out of the /// Web drawing at refresh time and its value is then /// assigned to this property. The format of this string /// is a semicolon-delimited list of key/value pairs. /// Each pair contains the key and value, separated by an /// equals sign. /// /// this.QueryString: The query string associated with the Visio /// DataRecordset being refreshed by this custom data /// provider. This string is parsed out of the Web drawing /// at refresh time and its value is then assigned to this /// property. The format is a semicolon-delimited list of /// key/value pairs. Each pair contains the key and value, /// separated by an equal sign. /// /// this.Error: The exception object that describes an error that occurred if this /// custom data provider failed to retrieve data from its associated /// external data source. This property can be used to propagate error /// information to the caller about a failure that occurred during the /// asynchronous processing. If the type of this exception is /// AddonDataHandlerException, the exception message is presented /// to the end user as is; otherwise, a generic message will be used. /// /// this.BeginGetData(): This method is called by Visio Services to /// start data retrieval in this custom data /// provider. /// /// this.EndGetData(): This method is called by Visio Services when /// the custom data provider finished retrieving data from /// the associated data source. This method must return /// the data retrieved in the form of an ADO.NET DataSet. /// /// this.Cancel(): This method is called by Visio Services to stop the async /// processing when an error was detected or the maximum time /// allocated for retrieving data has passed and the custom data /// provider did not complete. /// /// This class also implements the IAsyncResult interface as described at /// https://msdn.microsoft.com/zh-cn/library/system.iasyncresult.aspx. /// </summary> public class VisioCustomDataProvider : AddonDataHandler, IAsyncResult { // Fields used to support the implementation of the IAsyncResult interface. private object asyncState; //Used to maintain a reference to this custom //data provider. private bool completed; //Used to notifiy Visio Services that the //the custom data provider has finished //retrieving data. #region Implementation of the IAsyncResult Interface /// <summary> /// This property implements the equivalent AsyncWaitHandle property of /// the IAsyncResult interface. More details on this member can /// be found at https://msdn.microsoft.com/zh-cn/library/system.iasyncresult_properties.aspx /// Visio Services does not use this property. /// </summary> WaitHandle IAsyncResult.AsyncWaitHandle { get { return null; } } /// <summary> /// This property implements the equivalent AsyncState property of /// the IAsyncResult interface. More details on this member can /// be found at https://msdn.microsoft.com/zh-cn/library/system.iasyncresult_properties.aspx /// Visio Services requires this property to return the asyncState object /// passed to the BeginGetData method by its caller. /// </summary> object IAsyncResult.AsyncState { get { return this.asyncState; } } /// <summary> /// This property implements the equivalent IsCompleted property of the /// IAsyncResult interface. This property gets a value that indicates whether /// the asynchronous operation has completed. More details on this member can /// be found at https://msdn.microsoft.com/zh-cn/library/system.iasyncresult_properties.aspx /// </summary> bool IAsyncResult.IsCompleted { get { return this.completed; } } /// <summary> /// This property implements the equivalent CompleteSynchronously property /// of the IAsyncResult interface. This property gets a value that indicates /// whether the asyncrhonous operation has completed. More details on this member can /// be found at https://msdn.microsoft.com/zh-cn/library/system.iasyncresult_properties.aspx /// </summary> bool IAsyncResult.CompletedSynchronously { get { return false; } } #endregion #region Implementation of the AddonDataHandler abstract class /// <summary> /// BeginGetData is called by Visio Services to start data retrieval in /// this custom data provider. This method should return as quickly as possible /// because custom data providers are meant to be run asynchronously. /// </summary> /// <param name="context">The HTTP context of user viewing /// the Web drawing.</param> /// <param name="callback">A reference to a Visio Services method that /// the custom data provider must call when it is finished retrieving /// data from its associated external data source.</param> /// <param name="asyncState">Async state passed-in by the caller. Visio Services /// requires the implementation to store this state into the AsyncState member /// of the returned IAsyncResult without changes. /// </param> /// <returns>An IAsyncResult that contains information about the status of /// the operation.</returns> public override IAsyncResult BeginGetData( System.Web.HttpContext context, AsyncCallback callback, object asyncState) { //Store the async state. this.asyncState = asyncState; // Start data retrieval. This is done on a separate thread because // BeginGetData() should return as soon as possible. // When the ThreadTask function finishes, the thread makes // a call to the callback method, which indicates to Visio Services // that the data retrieval step is complete. ThreadPool.QueueUserWorkItem( new WaitCallback(ThreadTask), callback); return this; } /// <summary> /// EndGetData is the method called by Visio Services when this /// custom data provider has finished retrieving data. /// </summary> /// <param name="result">An IAsyncResult that contains information /// about the status of the operation.</param> /// <returns>This method must return the data retrieved by this /// custom data provider to Visio Services in the form of an ADO.NET /// DataSet.</returns> public override DataSet EndGetData(IAsyncResult result) { // Return an ADO.NET DataSet containing the data retrieved by this // custom data provider to Visio Services. In this example, // this.Data was updated in the ThreadTask method with the // appropriate data. return this.Data; } /// <summary> /// Cancel is the method called by Visio Services to stop the asynchronous /// processing when an error was detected or the maximum time /// allocated for retrieving data has passed and the custom data /// provider did not complete. /// </summary> public override void Cancel() { //This example does not require an implementation of this method. } #endregion #region Data retrieval method /// <summary> /// This is the worker method which is lauched by BeginGetData(). /// Typically this method should: /// (1) parse the the connection and query strings /// (2) implement authentication measures /// (3) connect to a custom data source, query, and retrieve data /// (4) format the retrieved data and update this.Data /// (5) in case of errors, set this.Error accordingly. /// (6) set this.completed and call the Visio Services callback method /// </summary> /// <param name="state">A reference to Visio Services callback /// that must be called at the end of this task.</param> private void ThreadTask(object state) { // Get a reference to the Visio Services callback AsyncCallback callback = (AsyncCallback) state; // A string to hold the file name of the data source once // it is parsed out of this.QueryString string filename = String.Empty; try { // (1) Parse ConnectionString and QueryString. // // When configuring the Web drawing for custom data providers, the user // can choose whether to pass information in the ConnectionString, QueryString, // or both, depending on the data source and preferences. // // In this example, the significant content of ConnectionString // and QueryString is the same and formatted as "File=<File>". // // Where: // <File>" is the path to the xml file that contains the data. const string FileKey = "File="; int fileNameStart = this.QueryString.IndexOf(FileKey) + FileKey.Length; filename = this.QueryString.Substring(fileNameStart); // (2) Authenticate // This code is running in the security context of the end user. // If the end user account does not have access to the disk where // the text data source is stored, implement the required authentication // mechanisms below. // (3,4) Retrieve and format data // This custom data provider expects the file to contain an // ADO.NET DataSet XML description of the data to load; therefore it's // easy to load into this.Data, which is itself an ADO.NET DataSet. // In this case, Reset must be called first to clear the DataSet. this.Data.Reset(); this.Data.ReadXml(filename, XmlReadMode.Auto); } catch (Exception error) { // (5) In case of errors when retrieving data, send feedback // to the user. This error will also force cancellation of // all other external data refresh operations. String message = String.Format( "There was an error reading: {0}. Error details: {1}", filename, error.ToString()); this.Error = new AddonDataHandlerException(message); } // (6) Set this.completed to indicate that the async processing is complete // and invoke the Visio Services callback method passing a reference to this // custom data provider. this.completed = true; callback(this); } #endregion } }在"解决方案资源管理器"中,右键单击解决方案名称,然后单击"生成解决方案"。
向解决方案添加 CAB 项目。为此,请右键单击该解决方案,指向"添加",然后单击"新建项目"。
单击"已安装的模板",依次展开"其他项目类型"和"安装和部署",单击"Visual Studio 安装程序",然后单击"CAB 项目"。
将项目命名为"CustomDataProviderDeploymentPackage",然后单击"确定"。
向部署项目添加项目输出组:右键单击该项目,指向"添加",然后单击"项目输出"。
选择"主输出",然后单击"确定"。
向部署项目添加其他项目输出组:右键单击该项目,指向"添加",然后单击"项目输出"。
选择"内容文件",然后单击"确定"。
向两个项目添加公钥 (.snk) 文件以便为程序集指定强名称。为此,请依次单击"开始"、"所有程序"、"Microsoft Visual Studio 2010"、"Visual Studio 工具"和"Visual Studio 命令提示(2010)"。
在命令提示符窗口中,导航到项目文件夹。
在命令提示符下,键入 sn /k VisioCustomDataProvider.snk,然后按 ENTER。
右键单击 CustomDataProvider 项目,指向"添加",单击"现有项目",选择 VisioCustomDataProvider.snk 文件,然后单击"添加"。
右键单击 CustomDataProviderDeploymentPackage 项目,指向"添加",单击"文件",导航到项目文件夹,选择 VisioCustomDataProvider.snk 文件,然后单击"打开"。
选择部署项目,然后在"属性"窗口中,选择"PostBuildEvent",然后单击显示的按钮。
在"生成后事件命令行"窗口中,粘贴以下代码,然后单击"确定"。
copy "$(BuiltOuputPath)" "$(ProjectDir)\$(Configuration)\VisioCustomDataProvider.wsp" del "$(BuiltOuputPath)"向解决方案添加清单文件。为此,请右键单击 CustomDataProvider 项目,指向"添加",然后单击"新项目"。
在"已安装的模板"下,选择"数据",选择"XML 文件",将文件命名为 manifest.xml,然后单击"添加"。
将下面的代码附加到该文件。
<Solution xmlns="https://schemas.microsoft.com/sharepoint/" SolutionId="DE30781F-2B54-4513-A921-4EEA58C10868" > <Assemblies> <Assembly DeploymentTarget="GlobalAssemblyCache" Location="VisioCustomDataProvider.dll"/> </Assemblies> </Solution>打开 AssemblyInfo.cs 文件,然后向该文件附加以下行。
[assembly: AssemblyKeyFile("VisioCustomDataProvider.snk")]右键单击 CustomDataProviderDeploymentPackage 项目,然后单击"生成"以编译该项目。
编译部署项目会在 c:\ 驱动器的根目录生成一个 .wsp 文件。
创建和运行 PowerShell 脚本
创建然后运行 Windows PowerShell 脚本会将您在 Visual Studio 2010 中创建的自定义数据提供程序(.wsp 文件)部署到 SharePoint Server 2010。
创建和运行 Windows PowerShell 脚本
在 SharePoint Server 2010 计算机上,单击"开始",然后单击"SharePoint 2010 Management Shell"。
在命令提示符下,键入 cd c:\,然后按 ENTER 以导航到 c:\ 驱动器的根目录。
在命令提示符下,键入以下内容,然后按 ENTER。
Add-SPSolution c:\visiocustomdataprovider.wsp在命令提示符下,键入以下内容,然后按 ENTER。
Install-SPSolution visiocustomdataprovider.wsp -GACDeployment脚本运行完成后,关闭命令行管理程序窗口。
如果以后需要卸载自定义数据提供程序,请使用以下脚本。
Get-SPSolution visiocustomdataprovider.wsp | Uninstall-SPSolution
Remove-SPSolution visiocustomdataprovider.wsp
向 Visio Graphics Service 添加新的受信任数据提供程序
在此步骤中,向 SharePoint Server 2010 中 Visio Graphics Service 的受信任数据提供程序的列表添加新的受信任数据提供程序。这样便可以根据 SharePoint Server 2010 计算机上数据提供程序中存储的数据刷新 Visio 绘图。输入的提供程序 ID 应为以下形式:
Namespace.ClassSimpleName,AssemblySimpleName, Version=version, Culture=culture, PublicKeyToken= token
以下过程说明如何添加新的受信任数据提供程序。
向 Visio Graphics Service 添加新的受信任数据提供程序
在 SharePoint Server 2010 计算机上,单击"开始",然后单击"SharePoint 2010 管理中心"。
在"应用程序管理"下,单击"管理服务应用程序"。
单击"Visio Graphics Service",然后单击"受信任数据提供程序"。
单击"添加一个新的受信任数据提供程序"。
对于"受信任数据提供程序 ID",键入 DataModules.VisioCustomDataProvider,VisioCustomDataProvider, Version=1.0.0.0, Culture=Neutral, PublicKeyToken= yourPublicKeyToken。
您可以在 c:\Windows\Assembly 文件夹中查找自定义数据提供程序的条目,从而查找公钥标记的值。
对于"受信任数据提供程序类型",键入 6。
对于可选的"受信任数据提供程序类型说明",键入 Visio Web Services。
测试示例自定义数据提供程序
此时,如果尚未将创建的 Visio .vdw 文件上载到 SharePoint Server 2010 文档库,则应执行此操作。如果尚未将创建的 XML 文件保存到 c:\ 驱动器的根文件夹,则也应执行此操作。
在上载 .vdw 文件并将自定义数据提供程序和 XML 数据文件部署到运行 Visio Services 的服务器后,您可以测试示例。请使用以下过程。
测试示例自定义数据提供程序
在上载 .vdw 文件的文档库中,单击该文件以呈现它。
单击"启用(此会话)"或"启用(始终)"以启用刷新。
打开保存到服务器的 XML 文件,然后更改一些数据。
在呈现的绘图中单击"刷新",然后观察图表如何更改以反映您在 XML 数据中所做的更改。