逐步解說:在伺服器總管擴充功能中呼叫 SharePoint 用戶端物件模型
本逐步解說將示範如何從 [伺服器總管] 中 [SharePoint 連接] 節點的擴充功能呼叫 SharePoint 用戶端物件模型。 如需使用 SharePoint 用戶端物件模型的詳細資訊,請參閱呼叫 SharePoint 物件模型。
本逐步解說將示範下列工作:
建立 Visual Studio 擴充功能,該擴充功能會透過下列方式擴充 [伺服器總管] 的 [SharePoint 連接] 節點:
在 [伺服器總管] 中的每個 SharePoint 網站節點下方加入新的 [Web 組件庫] 節點。 這個新節點包含的子節點代表網站上 Web 組件庫中的每一個 Web 組件。
定義代表 Web 組件執行個體的新節點類型。 這個新節點類型是新的 [Web 組件庫] 節點底下子節點的基礎。 新的 Web 組件節點類型會在 [屬性] 視窗中,顯示所代表 Web 組件的相關資訊。
建置 Visual Studio Extension (VSIX) Package 以部署擴充功能。
偵錯和測試擴充功能。
注意事項 |
---|
您在本逐步解說中建立的擴充功能,類似於在逐步解說:擴充伺服器總管以顯示 Web 組件中建立的擴充功能。 不過,該逐步解說使用 SharePoint 伺服器物件模型,而本逐步解說則使用用戶端物件模型完成相同的工作。 |
必要條件
開發電腦上需要下列元件才能完成此逐步解說:
支援的 Microsoft Windows、SharePoint 和 Visual Studio 版本。 如需詳細資訊,請參閱開發 SharePoint 方案的要求。
Visual Studio 2010 SDK。 本逐步解說使用 SDK 中的 [VSIX 專案] 範本建立 VSIX 套件,以部署擴充功能。 如需詳細資訊,請參閱擴充 Visual Studio 中的 SharePoint 工具。
了解下列概念有助於完成此逐步解說 (但非必要):
使用 SharePoint 用戶端物件模型。 如需詳細資訊,請參閱 Managed 用戶端物件模型 (英文)。
Microsoft SharePoint Services 中的 Web 組件。 如需詳細資訊,請參閱 Web 組件概觀 (英文)。
建立專案
若要完成這個逐步解說,您必須建立兩個專案:
VSIX 專案,用於建立 VSIX 套件以部署 [伺服器總管] 擴充功能。
類別庫專案,用於實作 [伺服器總管] 擴充功能。
從建立這些專案開始進行此逐步解說。
若要建立 VSIX 專案
啟動 Visual Studio。
在 [檔案] 功能表上,指向 [新增],然後按一下 [專案]。
在 [新增專案] 對話方塊中,展開 [Visual C#] 或 [Visual Basic] 節點,然後按一下 [擴充性]。
注意事項 [擴充性] 節點只有在安裝 Visual Studio 2010 SDK 時才可使用。 如需詳細資訊,請參閱上方的<必要條件>一節。
在對話方塊上方的下拉式方塊中,選取 [.NET Framework 4]。 SharePoint 工具擴充功能需要這版的 .NET Framework 功能。
按一下 [VSIX 專案] 範本。
在 [名稱] 方塊中,輸入 WebPartNode。
按一下 [確定]。
Visual Studio 會將 [WebPartNode] 專案加入至 [方案總管]。
若要建立擴充功能專案
在 [方案總管] 中,以滑鼠右鍵按一下方案節點,按一下 [加入],再按一下 [新增專案]。
注意事項 在 Visual Basic 專案中,方案節點只有在已選取選項對話方塊、專案和方案、一般中的 [永遠顯示方案] 核取方塊時,才會出現在 [方案總管] 中。
在 [新專案] 對話方塊中展開 [Visual C#] 或 [Visual Basic] 節點,然後按一下 [Windows]。
在對話方塊上方的下拉式方塊中,選取 [.NET Framework 4]。
選取 [類別庫] 專案範本。
在 [名稱] 方塊中,輸入 WebPartNodeExtension。
按一下 [確定]。
Visual Studio 會將 [WebPartNodeExtension] 專案加入至方案,然後開啟預設的 Class1 程式碼檔。
從專案刪除 Class1 程式碼檔。
設定擴充功能專案
在您撰寫程式碼以建立擴充功能之前,必須先將程式碼檔和組件參考加入至專案,並且更新預設命名空間。
若要設定專案
在 [WebPartNodeExtension] 專案中,加入具有下列名稱的兩個程式碼:
SiteNodeExtension
WebPartNodeTypeProvider
在 [專案] 功能表上,按一下 [加入參考]。
在 [.NET] 索引標籤上,按 CTRL,然後選取下列組件,再按一下 [確定]:
Microsoft.SharePoint.Client
Microsoft.SharePoint.Client.Runtime
Microsoft.VisualStudio.SharePoint
System.ComponentModel.Composition
System.Windows.Forms
在 [專案] 功能表上,選取 [WebPartNodeExtension 屬性]。
[專案設計工具] 隨即開啟。
按一下 [應用程式] 索引標籤。
在 [預設命名空間] 方塊 (C#) 或 [根命名空間] 方塊 (Visual Basic) 中,輸入 ServerExplorer.SharePointConnections.WebPartNode。
建立新節點的圖示
為 [伺服器總管] 擴充功能建立兩個圖示:一個圖示用於新的 [Web 組件庫] 節點,另一個圖示用於 [Web 組件庫] 節點底下的每個 Web 組件子節點。 稍後在本逐步解說中,您將寫入讓這些圖示與節點產生關聯的程式碼。
若要建立節點的圖示
在 WebPartNodeExtension 專案的 [專案設計工具] 中,按一下 [資源] 索引標籤。
按一下 [這個檔案未包含預設的資源檔。請按這裡建立資源檔。]
Visual Studio 會建立資源檔並在設計工具中將它開啟。
在設計工具頂端,按一下 [加入] 按鈕上的下拉箭號,然後按一下 [加入新圖示]。
輸入 WebPartsNode 做為新圖示的名稱,然後按一下 [加入]。
新圖示隨即開啟於 [影像編輯器] 中。
編輯 16x16 版的圖示,以便能夠輕鬆辨識其設計。
按一下 32x32 版的圖示。
按一下 [影像] 功能表上的 [刪除影像類型]。
重複步驟 3 到 7,將另一個圖示加入至專案資源。 將此圖示命名為 WebPart。
在 [方案總管] 中 [WebPartNodeExtension] 專案的 [資源] 資料夾底下,選取 WebPartsNode.ico。
在 [屬性] 視窗中,按一下 [建置動作] 旁的下拉式清單,然後選取 [內嵌資源]。
針對 WebPart.ico 重複最後兩個步驟。
將 Web 組件庫節點加入至伺服器總管
建立一個將新的 [Web 組件庫] 節點加入至每個 SharePoint 網站節點的類別。 為了加入新節點,此類別會實作 IExplorerNodeTypeExtension 介面。 在您要擴充 [伺服器總管] 中現有節點的行為時實作此介面,例如將新的子節點加入至節點。
若要將 Web 組件庫節點加入至伺服器總管
在 WebPartNodeExtension 專案中,按兩下 SiteNodeExtension 程式碼檔。
將下列程式碼貼到這個檔案。
注意事項 加入這段程式碼後,專案會出現一些編譯錯誤。 在後續步驟中加入程式碼時,這些錯誤將不存在。
Imports System.Collections.Generic Imports System.ComponentModel.Composition Imports Microsoft.SharePoint.Client Imports Microsoft.VisualStudio.SharePoint Imports Microsoft.VisualStudio.SharePoint.Explorer Namespace ServerExplorer.SharePointConnections.WebPartNode ' Export attribute: Enables Visual Studio to discover and load this extension. ' ExplorerNodeType attribute: Indicates that this class extends SharePoint site nodes in Server Explorer. ' SiteNodeExtension class: Represents an extension of SharePoint site nodes in Server Explorer. <Export(GetType(IExplorerNodeTypeExtension))> _ <ExplorerNodeType(ExplorerNodeTypes.SiteNode)> _ Friend Class SiteNodeExtension Implements IExplorerNodeTypeExtension Private siteUrl As System.Uri = Nothing Private Sub Initialize(ByVal nodeType As IExplorerNodeType) _ Implements IExplorerNodeTypeExtension.Initialize ' The NodeChildrenRequested event is raised when the user expands the ' SharePoint site node in Server Explorer. AddHandler nodeType.NodeChildrenRequested, AddressOf NodeChildrenRequested End Sub ' Creates the new Web Part Gallery node with the specified icon. Private Sub NodeChildrenRequested(ByVal Sender As Object, ByVal e As ExplorerNodeEventArgs) ' Get the site URL so that it can be used later to access the site ' by using the SharePoint client object model. siteUrl = e.Node.Context.SiteUrl ' The CreateWebPartNodes argument is a delegate that Visual Studio calls ' to create the child nodes under the Web Part Gallery node. e.Node.ChildNodes.AddFolder("Web Part Gallery", My.Resources.WebPartsNode.ToBitmap(), _ AddressOf CreateWebPartNodes) End Sub ' Creates individual Web Part nodes under the new Web Part Gallery node. Private Sub CreateWebPartNodes(ByVal parentNode As IExplorerNode) ' Use the SharePoint client object model to get items from the Web Part gallery. Dim Context As ClientContext = New ClientContext(siteUrl.AbsoluteUri) Dim WebPartsGallery As List = Context.Web.GetCatalog(CType(ListTemplateType.WebPartCatalog, Integer)) Dim WebParts As ListItemCollection = WebPartsGallery.GetItems(New CamlQuery()) ' Request the FieldValuesAsText property values with the Web Part items. Context.Load(WebParts, Function(listItems) listItems.Include(Function(i) i.FieldValuesAsText)) Context.ExecuteQuery() If WebParts IsNot Nothing Then For Each WebPart As ListItem In WebParts ' Create a new annotation object to store the current Web Part item with the new node. Dim Annotations = New Dictionary(Of Object, Object)() Annotations.Add(GetType(ListItem), WebPart) ' Create the new node for the current Web Part item. parentNode.ChildNodes.Add(WebPartNodeTypeProvider.WebPartNodeTypeId, _ WebPart.FieldValuesAsText.FieldValues("Title"), Annotations) Next End If End Sub End Class End Namespace
using System.Collections.Generic; using System.ComponentModel.Composition; using Microsoft.SharePoint.Client; using Microsoft.VisualStudio.SharePoint; using Microsoft.VisualStudio.SharePoint.Explorer; namespace ServerExplorer.SharePointConnections.WebPartNode { // Enables Visual Studio to discover and load this extension. [Export(typeof(IExplorerNodeTypeExtension))] // Indicates that this class extends SharePoint site nodes in Server Explorer. [ExplorerNodeType(ExplorerNodeTypes.SiteNode)] // Represents an extension of SharePoint site nodes in Server Explorer. internal class SiteNodeExtension : IExplorerNodeTypeExtension { private System.Uri siteUrl = null; public void Initialize(IExplorerNodeType nodeType) { // The NodeChildrenRequested event is raised when the user expands the // SharePoint site node in Server Explorer. nodeType.NodeChildrenRequested += NodeChildrenRequested; } // Creates the new Web Part Gallery node with the specified icon. private void NodeChildrenRequested(object sender, ExplorerNodeEventArgs e) { // Get the site URL so that it can be used later to access the site // by using the SharePoint client object model. siteUrl = e.Node.Context.SiteUrl; // The CreateWebPartNodes argument is a delegate that Visual Studio calls // to create the child nodes under the Web Part Gallery node. e.Node.ChildNodes.AddFolder("Web Part Gallery", Properties.Resources.WebPartsNode.ToBitmap(), CreateWebPartNodes); } // Creates individual Web Part nodes under the new Web Part Gallery node. private void CreateWebPartNodes(IExplorerNode parentNode) { // Use the SharePoint client object model to get items from the Web Part gallery. ClientContext context = new ClientContext(siteUrl.AbsoluteUri); List webPartsGallery = context.Web.GetCatalog((int)ListTemplateType.WebPartCatalog); ListItemCollection webParts = webPartsGallery.GetItems(new CamlQuery()); // Request the FieldValuesAsText property values with the Web Part items. context.Load(webParts, listItems => listItems.Include(i => i.FieldValuesAsText)); context.ExecuteQuery(); if (webParts != null) { foreach (ListItem webPart in webParts) { // Create a new annotation object to store the current Web Part item with the new node. var annotations = new Dictionary<object, object>() { { typeof(ListItem), webPart } }; // Create the new node for the current Web Part item. parentNode.ChildNodes.Add(WebPartNodeTypeProvider.WebPartNodeTypeId, webPart.FieldValuesAsText.FieldValues["Title"], annotations); } } } } }
定義代表 Web 組件的節點類型
建立類別,該類別會定義代表 Web 組件的新節點類型。 Visual Studio 會使用這個新節點類型顯示 [Web 組件庫] 節點底下的子節點。 這些子節點每一個都代表 SharePoint 網站上的單一 Web 組件。
為了定義新的節點類型,此類別會實作 IExplorerNodeTypeProvider 介面。 在您要於 [伺服器總管] 中定義新的節點類型時實作此介面。
若要定義 Web 組件節點類型
在 WebPartNodeExtension 專案中,按兩下 WebPartNodeTypeProvider 程式碼檔。
將下列程式碼貼到這個檔案。
Imports System Imports System.Collections.Generic Imports System.Windows.Forms Imports System.ComponentModel.Composition Imports Microsoft.SharePoint.Client Imports Microsoft.VisualStudio.SharePoint Imports Microsoft.VisualStudio.SharePoint.Explorer Namespace ServerExplorer.SharePointConnections.WebPartNode ' Export attribute: Enables Visual Studio to discover and load this extension. ' ExplorerNodeType attribute: Specifies the ID for this new node type. ' WebPartNodeTypeProvider class: Defines a new node type that represents a Web Part on a SharePoint site. <Export(GetType(IExplorerNodeTypeProvider))> _ <ExplorerNodeType(WebPartNodeTypeProvider.WebPartNodeTypeId)> _ Friend Class WebPartNodeTypeProvider Implements IExplorerNodeTypeProvider Friend Const WebPartNodeTypeId As String = "Contoso.WebPart" Private Sub InitializeType(ByVal typeDefinition As IExplorerNodeTypeDefinition) _ Implements IExplorerNodeTypeProvider.InitializeType typeDefinition.DefaultIcon = My.Resources.WebPart.ToBitmap() typeDefinition.IsAlwaysLeaf = True AddHandler typeDefinition.NodePropertiesRequested, AddressOf NodePropertiesRequested AddHandler typeDefinition.NodeMenuItemsRequested, AddressOf NodeMenuItemsRequested End Sub ' Retrieves properties that are displayed in the Properties window when ' a Web Part node is selected. Private Sub NodePropertiesRequested(ByVal Sender As Object, _ ByVal e As ExplorerNodePropertiesRequestedEventArgs) Dim webPart = e.Node.Annotations.GetValue(Of ListItem)() Dim propertySource = e.Node.Context.CreatePropertySourceObject( _ webPart.FieldValuesAsText.FieldValues) e.PropertySources.Add(propertySource) End Sub Private Sub NodeMenuItemsRequested(ByVal Sender As Object, _ ByVal e As ExplorerNodeMenuItemsRequestedEventArgs) Dim WebPartNodeMenuItem As IMenuItem = e.MenuItems.Add("Display Message") AddHandler WebPartNodeMenuItem.Click, AddressOf MenuItemClick End Sub Private Sub MenuItemClick(ByVal Sender As Object, ByVal e As MenuItemEventArgs) Dim ParentNode As IExplorerNode = TryCast(e.Owner, IExplorerNode) If ParentNode IsNot Nothing Then Dim webPart = ParentNode.Annotations.GetValue(Of ListItem)() MessageBox.Show("You clicked the context menu for the following Web part: " & _ webPart.FieldValuesAsText.FieldValues("Title") + ".", "Web Part Menu Command") End If End Sub End Class End Namespace
using System; using System.Collections.Generic; using System.Windows.Forms; using System.ComponentModel.Composition; using Microsoft.SharePoint.Client; using Microsoft.VisualStudio.SharePoint; using Microsoft.VisualStudio.SharePoint.Explorer; namespace ServerExplorer.SharePointConnections.WebPartNode { // Enables Visual Studio to discover and load this extension. [Export(typeof(IExplorerNodeTypeProvider))] // Specifies the ID for this new node type. [ExplorerNodeType(WebPartNodeTypeProvider.WebPartNodeTypeId)] // Defines a new node type that represents a Web Part on a SharePoint site. internal class WebPartNodeTypeProvider : IExplorerNodeTypeProvider { internal const string WebPartNodeTypeId = "Contoso.WebPart"; public void InitializeType(IExplorerNodeTypeDefinition typeDefinition) { typeDefinition.DefaultIcon = Properties.Resources.WebPart.ToBitmap(); typeDefinition.IsAlwaysLeaf = true; typeDefinition.NodePropertiesRequested += NodePropertiesRequested; typeDefinition.NodeMenuItemsRequested += NodeMenuItemsRequested; } // Retrieves properties that are displayed in the Properties window when // a Web Part node is selected. private void NodePropertiesRequested(object sender, ExplorerNodePropertiesRequestedEventArgs e) { var webPart = e.Node.Annotations.GetValue<ListItem>(); object propertySource = e.Node.Context.CreatePropertySourceObject( webPart.FieldValuesAsText.FieldValues); e.PropertySources.Add(propertySource); } private void NodeMenuItemsRequested( object sender, ExplorerNodeMenuItemsRequestedEventArgs e) { e.MenuItems.Add("Display Message").Click += MenuItemClick; } private void MenuItemClick(object sender, MenuItemEventArgs e) { IExplorerNode parentNode = e.Owner as IExplorerNode; if (parentNode != null) { var webPart = parentNode.Annotations.GetValue<ListItem>(); MessageBox.Show("You clicked the context menu for the following Web part: " + webPart.FieldValuesAsText.FieldValues["Title"] + ".", "Web Part Menu Command"); } } } }
檢查點
進行到逐步解說中的這個步驟時,[Web 組件庫] 節點的所有程式碼現在都會位於專案中。 建置方案,以確定專案在編譯時未發生任何錯誤。
若要建置方案
- 在 [建置] 功能表上,選取 [建置方案]。
建立 VSIX 套件以部署擴充功能
若要部署擴充功能,請在您的方案中使用 VSIX 專案,以建立 VSIX 套件。 首先,修改專案包含的 source.extension.vsixmanifest 檔案來設定 VSIX 套件。 接著,建置方案來建立 VSIX 套件。
若要設定 VSIX 套件
在 [方案總管] 的 [WebPartNode] 專案底下,按兩下其中的 source.extension.vsixmanifest 檔案。
Visual Studio 會在資訊清單編輯器中開啟檔案。 source.extension.vsixmanifest 檔案是所有 VSIX 套件所需要 extension.vsixmanifest 檔案的基準。 如需這個檔案的詳細資訊,請參閱VSIX Extension Schema Reference。
在 [產品名稱] 方塊中,輸入伺服器總管的 Web 組件庫節點。
在 [作者] 方塊中,輸入 Contoso。
在 [描述] 方塊中,輸入將自訂 Web 組件庫節點加入至伺服器總管中的 SharePoint 連接節點。
在編輯器的 [內容] 區段中,按一下 [加入內容] 按鈕。
在 [加入內容] 對話方塊的 [選取內容類型] 清單方塊中,選取 [MEF 元件]。
注意事項 這個值對應於 extension.vsixmanifest 檔案中的 MefComponent 項目。 這個項目指定 VSIX 套件中的擴充組件名稱。 如需詳細資訊,請參閱 MEFComponent Element (VSX Schema)。
按一下 [選取來源] 底下的 [專案] 選項按鈕,並選取其旁邊清單方塊中的 [WebPartNodeExtension]。
按一下 [確定]。
在 [建置] 功能表上,按一下 [建置方案]。 請確定方案編譯作業未發生錯誤。
開啟 WebPartNode 專案的建置輸出資料夾。 確定此資料夾現在包含 WebPartNode.vsix 檔。
根據預設,建置輸出資料夾為 .. \bin\Debug 資料夾,其位於專案檔案包含的資料夾下。
測試擴充功能
現在您可以測試 [伺服器總管] 中新的 [Web 組件庫] 節點。 首先,在 Visual Studio 的實驗執行個體中開始偵錯擴充功能專案。 接著在 Visual Studio 的實驗執行個體中使用新的 [Web 組件] 節點。
若要啟動對擴充功能的偵錯
以系統管理員權限重新啟動 Visual Studio 並且開啟 [WebPartNode] 專案。
在 WebPartNodeExtension 專案中,開啟 SiteNodeExtension 程式碼檔,然後將中斷點加入至 NodeChildrenRequested 和 CreateWebPartNodes 方法內最前面幾行程式碼中。
按 F5 鍵啟動偵錯作業。
Visual Studio 會將擴充功能安裝至 %UserProfile%\AppData\Local\Microsoft\VisualStudio\10.0Exp\Extensions\Contoso\Web Part Gallery Node Extension for Server Explorer\1.0,並啟動 Visual Studio 的實驗執行個體。 您將會在 Visual Studio 的這個執行個體中測試專案項目。
若要測試擴充功能
在 Visual Studio 的實驗執行個體中,按一下 [檢視] 功能表上的 [伺服器總管]。
確認要用來進行測試的 SharePoint 網站出現在 [伺服器總管] 中的 [SharePoint 連接] 節點底下。 如果網站未列出,請執行下列步驟:
以滑鼠右鍵按一下 [SharePoint 連接],然後按一下 [加入連接]。
在 [加入 SharePoint 連接] 對話方塊中,輸入要連接的 SharePoint 網站 URL。 若要指定開發電腦上的 SharePoint 網站,請輸入 https://localhost。
按一下 [確定]。
展開網站連接節點 (即顯示網站之 URL 的節點),然後展開子網站節點 (例如 [Team 網站])。
確認另一個 Visual Studio 執行個體中的程式碼在您之前於 NodeChildrenRequested 方法中設定的中斷點停止。 按 F5 繼續偵錯專案。
在 Visual Studio 的實驗執行個體中,確認名為 [Web 組件庫] 的新節點出現在最上層網站節點底下。 展開 [Web 組件庫] 節點。
確認另一個 Visual Studio 執行個體中的程式碼在您之前於 CreateWebPartNodes 方法中設定的中斷點停止。 按 F5 繼續偵錯專案。
在 Visual Studio 的實驗執行個體中,確認所連接網站上的所有 Web 組件都出現在 [伺服器總管] 中的 [Web 組件庫] 節點底下。
以滑鼠右鍵按一下其中一個 Web 組件,然後按一下 [屬性]。
確認關於 Web 組件的詳細資料出現在 [屬性] 視窗中。
在 [伺服器總管] 中,再次以滑鼠右鍵按一下相同的 Web 組件,然後按一下 [顯示訊息]。
確認訊息方塊是否出現。 按一下訊息方塊中的 [確定]。
從 Visual Studio 解除安裝擴充功能
完成測試擴充功能之後,解除安裝 Visual Studio 中的擴充功能。
若要解除安裝擴充功能
在 Visual Studio 的實驗執行個體中,按一下 [工具] 功能表上的 [擴充管理員]。
[擴充管理員] 對話方塊隨即開啟。
在擴充功能清單中,按一下 [伺服器總管的 Web 組件庫節點擴充功能],然後按一下 [解除安裝]。
在所顯示的對話方塊中,按一下 [是],確認您要解除安裝擴充功能。
按一下 [立即重新啟動] 完成解除安裝。 專案項目也會解除安裝。
關閉 Visual Studio 的兩個執行個體 (Visual Studio 的實驗執行個體,以及其中有開啟 WebPartNode 專案的執行個體)。