Exemplarische Vorgehensweise: Erweitern eines SharePoint-Elementtyps

Mithilfe des Projektelements Business Data Connectivity-Modell können Sie ein Modell für den Business Data Connectivity (BDC)-Dienst in SharePoint erstellen. Wenn Sie mit diesem Projektelement ein Modell erstellen, werden die Daten Benutzern im Modell standardmäßig nicht angezeigt. Sie müssen zusätlzlich eine externe Liste in SharePoint erstellen, damit Benutzer die Daten einsehen können.

In dieser exemplarischen Vorgehensweise erstellen Sie eine Erweiterung für das Projektelement Business Data Connectivity-Modell. Entwickler können mithilfe der Erweiterung eine externe Liste in ihrem Projekt erstellen, die die Daten im BDC-Modell anzeigt. Diese exemplarische Vorgehensweise enthält die folgenden Aufgaben:

  • Erstellen einer Visual Studio-Erweiterung, die zwei Hauptaufgaben ausführt:

    • Es wird eine externe Liste generiert, die die Daten in einem BDC-Modell anzeigt. Die Erweiterung verwendet das Objektmodell für das SharePoint-Projektsystem, um eine Datei Elements.xml zu generieren, die die Liste definiert. Außerdem wird die Datei zum Projekt hinzugefügt, damit sie zusammen mit dem BDC-Modell bereitgestellt werden kann.

    • Den Projektelementen für das Business Data Connectivity-Modell im Projektmappen-Explorer wird ein Kontextmenüelement hinzugefügt. Entwickler können auf dieses Menüelement klicken, um eine externe Liste für das BDC-Modell zu generieren.

  • Erstellen eines Visual Studio-Erweiterungspakets (VSIX) zum Bereitstellen der Erweiterungsassembly.

  • Testen der Erweiterung.

Vorbereitungsmaßnahmen

Zum Durchführen dieser exemplarischen Vorgehensweise werden auf dem Entwicklungscomputer die folgenden Komponenten benötigt:

Kenntnisse der folgenden Konzepte sind hilfreich, wenn auch für die Durchführung der exemplarischen Vorgehensweise nicht erforderlich:

  • Den BDC-Dienst in Microsoft SharePoint Server 2010. Weitere Informationen finden Sie im Thema zur BDC-Architektur (möglicherweise in englischer Sprache).

  • Das XML-Schema für BDC-Modelle. Weitere Informationen finden Sie im Thema zur BDC-Modellinfrastruktur (möglicherweise in englischer Sprache).

Erstellen der Projekte

Zum Abschließen dieser exemplarischen Vorgehensweise müssen Sie zwei Projekte erstellen:

  • Ein VSIX-Projekt für die Erstellung des VSIX-Pakets zum Bereitstellen der Projektelementerweiterung

  • Ein Klassenbibliotheksprojekt, das die Projektelementerweiterung implementiert

Beginnen Sie mit der exemplarischen Vorgehensweise, indem Sie beide Projekte erstellen.

So erstellen Sie das VSIX-Projekt

  1. Starten Sie Visual Studio.

  2. Zeigen Sie im Menü Datei auf Neu, und klicken Sie dann auf Projekt.

  3. Erweitern Sie im Dialogfeld Neues Projekt den Knoten Visual C# oder Visual Basic, und klicken Sie dann auf den Knoten Erweiterungen.

    Tipp

    Der Knoten Erweiterungen ist nur verfügbar, wenn Sie Visual Studio 2010 SDK installieren. Weitere Informationen finden Sie im Abschnitt zu den erforderlichen Komponenten und Voraussetzungen weiter oben.

  4. Wählen Sie im Kombinationsfeld am oberen Rand des Dialogfelds .NET Framework 4 aus. Für SharePoint-Tools-Erweiterungen werden Funktionen aus dieser .NET Framework-Version benötigt.

  5. Klicken Sie auf die Vorlage VSIX Project.

  6. Geben Sie im Feld Name die Zeichenfolge GenerateExternalDataLists ein.

  7. Klicken Sie auf OK.

    Visual Studio fügt dem Projektmappen-Explorer das Projekt GenerateExternalDataLists hinzu.

So erstellen Sie das Erweiterungsprojekt

  1. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf den Projektmappenknoten, klicken Sie auf Hinzufügen und dann auf Neues Projekt.

    Tipp

    In Visual Basic-Projekten wird der Projektmappenknoten nur im Projektmappen-Explorer angezeigt, wenn das Kontrollkästchen Projektmappe immer anzeigen in Allgemein, Projekte und Projektmappen, Dialogfeld "Optionen" aktiviert ist.

  2. Erweitern Sie im Dialogfeld Neues Projekt den Knoten Visual C# oder Visual Basic, und klicken Sie anschließend auf Windows.

  3. Wählen Sie im Kombinationsfeld am oberen Rand des Dialogfelds die Option .NET Framework 4 aus.

  4. Wählen Sie die Projektvorlage Klassenbibliothek aus.

  5. Geben Sie im Feld Name den Namen BdcProjectItemExtension ein.

  6. Klicken Sie auf OK.

    Visual Studio fügt das Projekt BdcProjectItemExtension der Projektmappe hinzu und öffnet die Class1-Codedatei.

  7. Löschen Sie die Class1-Codedatei aus dem Projekt.

Konfigurieren des Erweiterungsprojekts

Bevor Sie Code zum Erstellen der Projektelementerweiterung schreiben, fügen Sie dem Erweiterungsprojekt Codedateien und Assemblyverweise hinzu.

So konfigurieren Sie das Projekt

  1. Fügen Sie im Projekt "BdcProjectItemExtension" zwei Codedateien mit den folgenden Namen hinzu:

    • ProjectItemExtension

    • GenerateExternalDataLists

  2. Klicken Sie im Menü Projekt auf Verweis hinzufügen.

  3. Halten Sie auf der Registerkarte .NET die Taste STRG gedrückt, und klicken Sie auf die folgenden Assemblys. Klicken Sie anschließend auf OK:

    • Microsoft.VisualStudio.SharePoint

    • System.ComponentModel.Composition

    • WindowsBase

Definieren der Projektelementerweiterung

Erstellen Sie eine Klasse, die die Erweiterung für das Projektelement Business Data Connectivity-Modell definiert. Die Klasse implementiert die ISharePointProjectItemTypeExtension-Schnittstelle, um die Erweiterung zu definieren. Implementieren Sie diese Schnittstelle immer dann, wenn Sie einen vorhandenen Projektelementtyp erweitern möchten.

So definieren Sie eine Projektelementerweiterung

  1. Doppelklicken Sie auf die ProjectItemExtension-Codedatei.

  2. Fügen Sie folgenden Code in die Datei ein.

    Tipp

    Nach dem Hinzufügen dieses Codes weist das Projekt mehrere Kompilierungsfehler auf. Diese Fehler werden durch Code behoben, den Sie in späteren Schritten hinzufügen.

    Imports Microsoft.VisualStudio.SharePoint
    Imports System.ComponentModel.Composition
    
    Namespace Contoso.SharePointProjectItemExtensions.GenerateExternalDataLists
    
        ' Export attribute: Enables Visual Studio to discover and load this extension.
        ' SharePointProjectItemType attribute: Specifies the ID of the project item to extend.
        ' GenerateExternalDataListsExtension class: Defines the extension for the BDC project item.
        '     The other part of the partial class contains the logic for generating the external data lists. 
        <Export(GetType(ISharePointProjectItemTypeExtension))> _
        <SharePointProjectItemType("Microsoft.VisualStudio.SharePoint.BusinessDataConnectivity")> _
        Partial Friend Class GenerateExternalDataListsExtension
            Implements ISharePointProjectItemTypeExtension
    
            ' Creates the new shortcut menu item that the user clicks to generate the external data lists.
            Private Sub Initialize(ByVal SharePointProjectItemType As ISharePointProjectItemType) _
                Implements ISharePointProjectItemTypeExtension.Initialize
                AddHandler SharePointProjectItemType.ProjectItemMenuItemsRequested,
                    AddressOf SharePointProjectItemMenuItemsRequested
            End Sub
    
            Private Sub SharePointProjectItemMenuItemsRequested(ByVal Sender As Object, _
                ByVal e As SharePointProjectItemMenuItemsRequestedEventArgs)
                Dim generateListMenuItem As IMenuItem = e.ViewMenuItems.Add("Generate External Data List")
                AddHandler generateListMenuItem.Click, AddressOf GenerateExternalDataLists_Execute
            End Sub
        End Class
    End Namespace
    
    using Microsoft.VisualStudio.SharePoint;
    using System.ComponentModel.Composition;
    
    namespace Contoso.SharePointProjectItemExtensions.GenerateExternalDataLists
    {
        // Enables Visual Studio to discover and load this extension.
        [Export(typeof(ISharePointProjectItemTypeExtension))]
    
        // Specifies the ID of the project item to extend.
        [SharePointProjectItemType("Microsoft.VisualStudio.SharePoint.BusinessDataConnectivity")]
    
        // Defines the extension for the BDC project item. The other part of the partial class contains
        // the logic for generating the external data lists. 
        internal partial class GenerateExternalDataListsExtension : ISharePointProjectItemTypeExtension
        {
            // Implements IProjectItemTypeExtension.Initialize. Creates the new shortcut menu item that
            // the user clicks to generate the external data lists.
            public void Initialize(ISharePointProjectItemType projectItemType)
            {
                projectItemType.ProjectItemMenuItemsRequested += ProjectItemMenuItemsRequested;
            }
    
            private void ProjectItemMenuItemsRequested(object sender, SharePointProjectItemMenuItemsRequestedEventArgs e)
            {
                e.ViewMenuItems.Add("Generate External Data List").Click += GenerateExternalDataLists_Execute;
            }
        }
    }
    

Erstellen der externen Datenlisten

Fügen Sie eine partielle Definition der GenerateExternalDataListsExtension-Klasse hinzu, die im BDC-Modell eine externe Datenliste für jede Entität erstellt. Um die externe Datenliste zu erstellen, werden im Code zuerst die Entitätsdaten aus dem BDC-Modell gelesen, indem die XML-Daten in der BDC-Modelldatei analysiert werden. Anschließend wird eine Listeninstanz basierend auf dem BDC-Modell erstellt und zum Projekt hinzugefügt.

So erstellen Sie die externen Datenlisten

  1. Doppelklicken Sie auf die GenerateExternalDataLists-Codedatei.

  2. Fügen Sie folgenden Code in die Datei ein.

    Imports Microsoft.VisualStudio.SharePoint
    Imports Microsoft.VisualBasic
    Imports System
    Imports System.Collections.Generic
    Imports System.IO
    Imports System.Linq
    Imports System.Text
    Imports System.Xml.Linq
    
    Namespace Contoso.SharePointProjectItemExtensions.GenerateExternalDataLists
    
        ' Creates the external data lists for the BDC item. The other part of the partial class 
        ' defines the BDC project item extension.
        Partial Friend Class GenerateExternalDataListsExtension
    
            Private Const ModelFileNameString As String = "ModelFileName"
            Private Const EXTENSION_BDCM As String = ".bdcm"
            Private Const NamespaceString As String = "https://schemas.microsoft.com/windows/2007/BusinessDataCatalog"
            Private Shared ReadOnly BdcNamespace As XNamespace = XNamespace.Get(NamespaceString)
    
            ' Generates an external data list for each Entity in the BDC model. This event handler is called
            ' when the developer clicks the shortcut menu item that the extension adds to the BDC project item.
            Private Sub GenerateExternalDataLists_Execute(ByVal Sender As Object, ByVal e As MenuItemEventArgs)
    
                Dim projectItem As ISharePointProjectItem = CType(e.Owner, ISharePointProjectItem)
                Dim bdcmFile As ISharePointProjectItemFile = GetModelFile(projectItem)
    
                Dim doc As XDocument = XDocument.Load(bdcmFile.FullPath)
                Dim skippedEntities As List(Of XElement) = New List(Of XElement)()
    
                ' Try to generate an external data list for each entity defined in the BDC model file.
                For Each entity As XElement In doc.Root.Elements(BdcNamespace + "LobSystems").Elements( _
                    BdcNamespace + "LobSystem").Elements(BdcNamespace + "Entities").Elements(BdcNamespace + "Entity")
    
                    If False = GenerateExternalDataList(projectItem, entity) Then
                        skippedEntities.Add(entity)
                    End If
                Next
    
                ' Report skipped entities.
                If skippedEntities.Count <> 0 Then
                    Dim entityNameList As StringBuilder = Nothing
                    skippedEntities.ForEach(Function(entity As XElement)
                                                If (entityNameList Is Nothing) Then
                                                    entityNameList = New StringBuilder()
                                                Else
                                                    entityNameList.AppendLine(",")
                                                End If
                                                entityNameList.Append(entity.Attribute("Name").Value)
                                            End Function)
    
                    Dim message As String = String.Format("The following Entities were skipped because " &
                        "either a LobSystemInstance, SpecificFinder, or Finder was not found for them. \r\n{0}", _
                        entityNameList)
                    projectItem.Project.ProjectService.Logger.WriteLine(message, LogCategory.Warning)
                End If
            End Sub
    
            ' Gets the ISharePointProjectItemFile object for the BDC model file.
            Private Function GetModelFile(ByVal projectItem As ISharePointProjectItem) As ISharePointProjectItemFile
    
                Dim modelFileName As String = Nothing
                If projectItem.FeatureProperties.TryGetValue(ModelFileNameString, modelFileName) Then
                    modelFileName = Path.GetFileName(modelFileName)
                    Return (From file In projectItem.Files _
                            Where String.Compare(file.Name, modelFileName, StringComparison.OrdinalIgnoreCase) = 0 _
                            Select file).FirstOrDefault()
                Else
                    ' If we can't find the ModelFileName through the FeatureProperties, 
                    ' get the first file that has a '.bdcm' extension
                    Return (From file In projectItem.Files _
                            Where file.Name.EndsWith(EXTENSION_BDCM, StringComparison.OrdinalIgnoreCase) _
                            Select file).FirstOrDefault()
                End If
            End Function
    
            ' Boilerplate XML for the new list instance that is based on the BDC model.
            Private Const externalDataListContent As String = _
                "<?xml version=""1.0"" encoding=""utf-8""?>" & vbCrLf & _
                "        <Elements https://schemas.microsoft.com/sharepoint/"">" & vbCrLf & _
                "          <ListInstance Title=""$EntityName$DataList""" & vbCrLf & _
                "                        OnQuickLaunch=""TRUE""" & vbCrLf & _
                "                        TemplateType=""104""" & vbCrLf & _
                "                        FeatureId=""$SharePoint.Feature.Id$""" & vbCrLf & _
                "                        Url=""Lists/$EntityName$DataList""" & vbCrLf & _
                "                        Description=""Default List for $EntityName$."">" & vbCrLf & _
                "            <DataSource>" & vbCrLf & _
                "              <Property Name=""LobSystemInstance"" Value=""$LobSystemInstance$"" />" & vbCrLf & _
                "              <Property Name=""EntityNamespace"" Value=""$EntityNamespace$"" />" & vbCrLf & _
                "              <Property Name=""Entity"" Value=""$EntityName$"" />" & vbCrLf & _
                "              <Property Name=""SpecificFinder"" Value=""$SpecificFinder$"" />" & vbCrLf & _
                "              <Property Name=""Finder"" Value=""$Finder$"" />" & vbCrLf & _
                "            </DataSource>" & vbCrLf & _
                "          </ListInstance>" & vbCrLf & _
                "        </Elements>"
    
            ' Tries to generate an external data list for the specified BDC model project item and entity.
            Private Function GenerateExternalDataList(ByVal projectItem As ISharePointProjectItem, ByVal entity As XElement) As Boolean
    
                Dim lobSystemInstanceName As String = GetLobSystemInstanceName(entity)
                Dim specificFinderName As String = GetSpecificFinderName(entity)
                Dim finderName As String = GetFinderName(entity)
                Dim entityName As String = entity.Attribute("Name").Value
    
                If String.IsNullOrEmpty(lobSystemInstanceName) Or String.IsNullOrEmpty(specificFinderName) Or _
                    String.IsNullOrEmpty(finderName) Then
                    Return False
                End If
    
                Dim newExternalDataListName As String = entityName & "DataList"
                Dim existingProjectItem As ISharePointProjectItem = (From existingItem As ISharePointProjectItem In projectItem.Project.ProjectItems
                                                    Where existingItem.Name = newExternalDataListName
                                                    Select existingItem).FirstOrDefault()
    
                ' Add a new list instance and populate it with data from the BDC model.
                If existingProjectItem Is Nothing Then
                    Dim newExternalDataList As ISharePointProjectItem = projectItem.Project.ProjectItems.Add(newExternalDataListName, _
                        "Microsoft.VisualStudio.SharePoint.ListInstance")
    
                    Dim newExternalDataListString As String = externalDataListContent
                    newExternalDataListString = newExternalDataListString.Replace("$EntityName$", entityName)
                    newExternalDataListString = newExternalDataListString.Replace("$LobSystemInstance$", lobSystemInstanceName)
                    newExternalDataListString = newExternalDataListString.Replace("$EntityNamespace$", entity.Attribute("Namespace").Value)
                    newExternalDataListString = newExternalDataListString.Replace("$SpecificFinder$", specificFinderName)
                    newExternalDataListString = newExternalDataListString.Replace("$Finder$", finderName)
    
                    Dim elementsXmlPath As String = Path.Combine(newExternalDataList.FullPath, "Elements.xml")
                    File.WriteAllText(elementsXmlPath, newExternalDataListString)
                    Dim elementsFile As ISharePointProjectItemFile = newExternalDataList.Files.AddFromFile(elementsXmlPath)
                    elementsFile.DeploymentType = DeploymentType.ElementManifest
                End If
    
                Return True
            End Function
    
            Private Function GetLobSystemInstanceName(ByVal entity As XElement) As String
    
                Dim lobSystemInstances As XElement = entity.Parent.Parent.Element(BdcNamespace + "LobSystemInstances")
                If lobSystemInstances IsNot Nothing Then
                    Dim lobSystemInstance As XElement = lobSystemInstances.Elements(BdcNamespace + "LobSystemInstance").FirstOrDefault()
                    If lobSystemInstance IsNot Nothing Then
                        Return lobSystemInstance.Attribute("Name").Value
                    End If
                End If
                Return Nothing
            End Function
    
            Private Function GetSpecificFinderName(ByVal entity As XElement) As String
                Return GetMethodInstance(entity, "SpecificFinder")
            End Function
    
            Private Function GetFinderName(ByVal entity As XElement) As String
                Return GetMethodInstance(entity, "Finder")
            End Function
    
            Private Function GetMethodInstance(ByVal entity As XElement, ByVal methodInstanceType As String) As String
                Dim methods As XElement = entity.Element(BdcNamespace + "Methods")
                If methods IsNot Nothing Then
                    For Each method As XElement In methods.Elements(BdcNamespace + "Method")
                        Dim methodInstances As XElement = method.Element(BdcNamespace + "MethodInstances")
                        If methodInstances IsNot Nothing Then
                            For Each methodInstance As XElement In methodInstances.Elements(BdcNamespace + "MethodInstance")
                                If methodInstance.Attribute("Type").Value = methodInstanceType Then
                                    Return methodInstance.Attribute("Name").Value
                                End If
                            Next
                        End If
                    Next
                End If
                Return Nothing
            End Function
    
        End Class
    End Namespace
    
    using Microsoft.VisualStudio.SharePoint;
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Xml.Linq;
    
    namespace Contoso.SharePointProjectItemExtensions.GenerateExternalDataLists
    {
        // Creates the external data lists for the BDC item. The other part of the partial class 
        // defines the BDC project item extension.
        internal partial class GenerateExternalDataListsExtension
        {
            private const string ModelFileNameString = "ModelFileName";
            private const string EXTENSION_BDCM = ".bdcm";
            private const string NamespaceString = "https://schemas.microsoft.com/windows/2007/BusinessDataCatalog";
            private static readonly XNamespace BdcNamespace = XNamespace.Get(NamespaceString);
    
            // Generates an external data list for each Entity in the BDC model. This event handler is called
            // when the developer clicks the shortcut menu item that the extension adds to the BDC project item.
            private void GenerateExternalDataLists_Execute(object sender, MenuItemEventArgs e)
            {
                ISharePointProjectItem projectItem = (ISharePointProjectItem)e.Owner;
                ISharePointProjectItemFile bdcmFile = GetModelFile(projectItem);
    
                XDocument doc = XDocument.Load(bdcmFile.FullPath);
                List<XElement> skippedEntities = new List<XElement>();
    
                // Try to generate an external data list for each entity defined in the BDC model file.
                foreach (XElement entity in doc.Root.Elements(BdcNamespace + "LobSystems").Elements(
                    BdcNamespace + "LobSystem").Elements(BdcNamespace + "Entities").Elements(BdcNamespace + "Entity"))
                {
                    if (!GenerateExternalDataList(projectItem, entity))
                    {
                        skippedEntities.Add(entity);
                    }
                }
    
                // Report skipped entities.
                if (skippedEntities.Count != 0)
                {
                    StringBuilder entityNameList = null;
                    skippedEntities.ForEach(delegate(XElement entity)
                    {
                        if (entityNameList == null)
                        {
                            entityNameList = new StringBuilder();
                        }
                        else
                        {
                            entityNameList.AppendLine(",");
                        }
                        entityNameList.Append(entity.Attribute("Name").Value);
                    });
    
                    string message = string.Format("The following Entities were skipped because either a LobSystemInstance, " +
                        "SpecificFinder, or Finder was not found for them. \r\n{0}", entityNameList);
                    projectItem.Project.ProjectService.Logger.WriteLine(message, LogCategory.Warning);
                }
            }
    
            // Gets the ISharePointProjectItemFile object for the BDC model file.
            private ISharePointProjectItemFile GetModelFile(ISharePointProjectItem projectItem)
            {
                string modelFileName;
                if (projectItem.FeatureProperties.TryGetValue(ModelFileNameString, out modelFileName))
                {
                    modelFileName = Path.GetFileName(modelFileName);
                    return (from file in projectItem.Files
                            where string.Compare(file.Name, modelFileName, StringComparison.OrdinalIgnoreCase) == 0
                            select file).FirstOrDefault();
                }
                else
                {
                    // if we can't find the ModelFileName through the FeatureProperties, 
                    // get the first file that has a '.bdcm' extension
                    return (from file in projectItem.Files
                            where file.Name.EndsWith(EXTENSION_BDCM, StringComparison.OrdinalIgnoreCase)
                            select file).FirstOrDefault();
                }
            }
    
            // Boilerplate XML for the new list instance that is based on the BDC model.
            private const string externalDataListContent =
                @"<?xml version=""1.0"" encoding=""utf-8""?>
                <Elements https://schemas.microsoft.com/sharepoint/"">
                  <ListInstance Title=""$EntityName$DataList""
                                OnQuickLaunch=""TRUE""
                                TemplateType=""104""
                                FeatureId=""$SharePoint.Feature.Id$""
                                Url=""Lists/$EntityName$DataList""
                                Description=""Default List for $EntityName$."">
                    <DataSource>
                      <Property Name=""LobSystemInstance"" Value=""$LobSystemInstance$"" />
                      <Property Name=""EntityNamespace"" Value=""$EntityNamespace$"" />
                      <Property Name=""Entity"" Value=""$EntityName$"" />
                      <Property Name=""SpecificFinder"" Value=""$SpecificFinder$"" />
                      <Property Name=""Finder"" Value=""$Finder$"" />
                    </DataSource>
                  </ListInstance>
                </Elements>";
    
            // Tries to generate an external data list for the specified BDC model project item and entity.
            private bool GenerateExternalDataList(ISharePointProjectItem projectItem, XElement entity)
            {
                string lobSystemInstanceName = GetLobSystemInstanceName(entity);
                string specificFinderName = GetSpecificFinderName(entity);
                string finderName = GetFinderName(entity);
                string entityName = entity.Attribute("Name").Value;
    
                if (string.IsNullOrEmpty(lobSystemInstanceName) || string.IsNullOrEmpty(specificFinderName) || 
                    string.IsNullOrEmpty(finderName))
                {
                    return false;
                }
    
                string newExternalDataListName = entityName + "DataList";
                ISharePointProjectItem existingProjectItem = (from ISharePointProjectItem existingItem in projectItem.Project.ProjectItems
                                                    where existingItem.Name == newExternalDataListName
                                                    select existingItem).FirstOrDefault();
    
                // Add a new list instance and populate it with data from the BDC model.
                if (existingProjectItem == null)
                {
                    ISharePointProjectItem newExternalDataList = projectItem.Project.ProjectItems.Add(newExternalDataListName, 
                        "Microsoft.VisualStudio.SharePoint.ListInstance");
    
                    string newExternalDataListString = externalDataListContent;
                    newExternalDataListString = newExternalDataListString.Replace("$EntityName$", entityName);
                    newExternalDataListString = newExternalDataListString.Replace("$LobSystemInstance$", lobSystemInstanceName);
                    newExternalDataListString = newExternalDataListString.Replace("$EntityNamespace$", entity.Attribute("Namespace").Value);
                    newExternalDataListString = newExternalDataListString.Replace("$SpecificFinder$", specificFinderName);
                    newExternalDataListString = newExternalDataListString.Replace("$Finder$", finderName);
    
                    string elementsXmlPath = Path.Combine(newExternalDataList.FullPath, "Elements.xml");
                    File.WriteAllText(elementsXmlPath, newExternalDataListString);
                    ISharePointProjectItemFile elementsFile = newExternalDataList.Files.AddFromFile(elementsXmlPath);
                    elementsFile.DeploymentType = DeploymentType.ElementManifest;
                }
    
                return true;
            }
    
            private string GetLobSystemInstanceName(XElement entity)
            {
                XElement lobSystemInstances = entity.Parent.Parent.Element(BdcNamespace + "LobSystemInstances");
                if (lobSystemInstances != null)
                {
                    XElement lobSystemInstance = lobSystemInstances.Elements(BdcNamespace + "LobSystemInstance").FirstOrDefault();
                    if (lobSystemInstance != null)
                    {
                        return lobSystemInstance.Attribute("Name").Value;
                    }
                }
                return null;
            }
    
            private string GetSpecificFinderName(XElement entity)
            {
                return GetMethodInstance(entity, "SpecificFinder");
            }
    
            private string GetFinderName(XElement entity)
            {
                return GetMethodInstance(entity, "Finder");
            }
    
            private string GetMethodInstance(XElement entity, string methodInstanceType)
            {
                XElement methods = entity.Element(BdcNamespace + "Methods");
                if (methods != null)
                {
                    foreach (XElement method in methods.Elements(BdcNamespace + "Method"))
                    {
                        XElement methodInstances = method.Element(BdcNamespace + "MethodInstances");
                        if (methodInstances != null)
                        {
                            foreach (XElement methodInstance in methodInstances.Elements(BdcNamespace + "MethodInstance"))
                            {
                                if (methodInstance.Attribute("Type").Value == methodInstanceType)
                                {
                                    return methodInstance.Attribute("Name").Value;
                                }
                            }
                        }
                    }
                }
    
                return null;
            }
        }
    }
    

Checkpoint

Ab diesem Punkt in der exemplarischen Vorgehensweise wurde der gesamte für die Projektelementerweiterung benötigte Code in das Projekt eingefügt. Erstellen Sie die Projektmappe, um sicherzustellen, dass das Projekt ohne Fehler kompiliert wird.

So erstellen Sie die Projektmappe

  • Klicken Sie im Menü Erstellen auf Projektmappe erstellen.

Erstellen eines VSIX-Pakets, um die Projektelementerweiterung bereitzustellen

Zum Bereitstellen der Erweiterung erstellen Sie anhand des VSIX-Projekts in der Lösung ein VSIX-Paket. Konfigurieren Sie zuerst das VSIX-Paket, indem Sie die im VSIX-Projekt enthaltene Datei "source.extension.vsixmanifest" ändern. Erstellen Sie anschließend das VSIX-Paket, indem Sie die Lösung erstellen.

So erstellen und konfigurieren Sie das VSIX-Paket

  1. Doppelklicken Sie im Projektmappen-Explorer im Projekt "GenerateExternalDataLists" auf die Datei source.extension.vsixmanifest.

    Die Datei wird von Visual Studio im Manifest-Editor geöffnet. Die Datei "source.extension.vsixmanifest" bildet die Grundlage für die Datei "extension.vsixmanifest", die für alle VSIX-Pakete erforderlich ist. Weitere Informationen zu dieser Datei finden Sie unter VSIX Extension Schema Reference.

  2. Geben Sie im Feld Produktname den Namen External Data List Generator ein.

  3. Geben Sie im Feld Autor den Namen Contoso ein.

  4. Geben Sie im Feld Beschreibung die Beschreibung An extension for Business Data Connectivity Model project items that can be used to generate external data lists ein.

  5. Klicken Sie im Editor im Abschnitt Inhalt auf die Schaltfläche Inhalt hinzufügen.

  6. Wählen Sie im Dialogfeld Inhalt hinzufügen im Listenfeldzum Auswählen eines Inhaltstyps die Option MEF-Komponente aus.

    Tipp

    Dieser Wert entspricht dem MefComponent-Element in der Datei "extension.vsixmanifest". Von diesem Element wird der Name einer Erweiterungsassembly im VSIX-Paket angegeben. Weitere Informationen finden Sie unter MEFComponent Element (VSX Schema).

  7. Aktivieren Sie unter Quelle auswählen das Optionsfeld Projekt, und wählen Sie im zugehörigen Listenfeld den Eintrag BdcProjectItemExtension aus.

  8. Klicken Sie auf OK.

  9. Klicken Sie im Menü Erstellen auf Projektmappe erstellen. Vergewissern Sie sich, dass das Projekt fehlerfrei kompiliert wird.

  10. Öffnen Sie den Buildausgabeordner für das Projekt GenerateExternalDataLists. Stellen Sie sicher, dass dieser Ordner jetzt die Datei GenerateExternalDataLists.vsix enthält.

    Standardmäßig ist der Buildausgabeordner der Ordner "\bin\Debug" im Ordner mit der Projektdatei.

Testen der Projektelementerweiterung

Jetzt können Sie die Projektelementerweiterung testen. Debuggen Sie das Erweiterungsprojekt zunächst in der experimentellen Instanz von Visual Studio. Verwenden Sie die Erweiterung dann in der experimentellen Instanz von Visual Studio, um eine externe Liste für ein BDC-Modell zu generieren. Öffnen Sie abschließend die externe Liste auf der SharePoint-Website, um sicherzustellen, dass die Liste einwandfrei funktioniert.

So debuggen Sie die Erweiterung

  1. Starten Sie Visual Studio erneut mit Administratorrechten, und öffnen Sie die Projektmappe "GenerateExternalDataLists".

  2. Öffnen Sie im Projekt "BdcProjectItemExtension" die ProjectItemExtension-Codedatei, und fügen Sie der Codezeile in der Initialize-Methode einen Haltepunkt hinzu.

  3. Öffnen Sie die GenerateExternalDataLists-Codedatei, und fügen Sie der ersten Codezeile in der GenerateExternalDataLists_Execute-Methode einen Haltepunkt hinzu.

  4. Drücken Sie die Taste F5, um mit dem Debuggen zu beginnen.

    Die Erweiterung wird unter "%UserProfile%\AppData\Local\Microsoft\VisualStudio\10.0Exp\Extensions\Contoso\External Data List Generator\1.0" installiert, und eine experimentelle Instanz von Visual Studio wird gestartet. Sie testen das Projektelement in dieser Instanz von Visual Studio.

So testen Sie die Erweiterung

  1. Zeigen Sie in der experimentellen Instanz von Visual Studio im Menü Datei auf Neu, und klicken Sie dann auf Projekt.

  2. Erweitern Sie Visual C#, erweitern Sie SharePoint, und klicken Sie dann auf 2010.

  3. Stellen Sie im Kombinationsfeld am oberen Rand des Dialogfelds sicher, dass .NET Framework 3.5 ausgewählt ist. Projekte für Microsoft SharePoint Server 2010 erfordern diese Version von .NET Framework.

  4. Klicken Sie in der Liste der Projektvorlagen auf Business Data Connectivity-Modell.

  5. Geben Sie im Feld Name den Namen TestBDCModel ein.

  6. Klicken Sie auf OK.

  7. Geben Sie im Assistenten zum Anpassen von SharePoint die URL der Website ein, die Sie zum Debuggen verwenden möchten, und klicken Sie auf Fertig stellen.

  8. Überprüfen Sie, ob die Codeausführung in der anderen Instanz von Visual Studio an dem Haltepunkt unterbrochen wird, den Sie zuvor in der Initialize-Methode festgelegt haben. Drücken Sie in dieser Instanz von Visual Studio F5, um das Projekt weiter zu debuggen.

  9. Drücken Sie in der experimentellen Instanz von Visual Studio F5, um das Projekt "TestBDCModel" zu erstellen, bereitzustellen und auszuführen. Im Webbrowser wird die Standardseite der SharePoint-Website geöffnet, die zum Debugging verwendet wird.

  10. Überprüfen Sie, dass der Bereich Listen im Schnellstartbereich noch keine Liste enthält, die auf dem BDC-Standardmodell im Projekt basiert. Sie müssen zuerst eine externe Datenliste erstellen, entweder mit der SharePoint-Benutzeroberfläche oder mit der Projektelementerweiterung.

  11. Schließen Sie den Webbrowser.

  12. Klicken Sie in der Instanz von Visual Studio, in der das Projekt "TestBDCModel" geöffnet ist, im Projektmappen-Explorer mit der rechten Maustaste auf den Knoten BdcModel1, und klicken Sie dann auf GenerateExternalDataLists.

  13. Überprüfen Sie, ob die Codeausführung in der anderen Instanz von Visual Studio an dem Haltepunkt unterbrochen wird, den Sie zuvor in der GenerateExternalDataLists_Execute-Methode festgelegt haben. Drücken Sie F5, um mit dem Debuggen des Projekts fortzufahren.

  14. Die experimentelle Instanz von Visual Studio fügt dem Projekt "TestBDCModel" eine Listeninstanz mit dem Namen Entity1DataList hinzu und generiert außerdem eine Funktion mit dem Namen Feature2 für die Listeninstanz.

  15. Drücken Sie F5, um das Projekt TestBDCModel zu erstellen, bereitzustellen und auszuführen. Im Webbrowser wird die Standardseite der SharePoint-Website geöffnet, die zum Debugging verwendet wird.

  16. Stellen Sie sicher, dass im Schnellstart im Abschnitt Listen jetzt eine Liste mit dem Namen Entity1DataList angezeigt wird.

  17. Klicken Sie auf die Liste Entity1DataList.

  18. Überprüfen Sie, ob die Liste Spalten mit den Namen Identifier1 und Message sowie ein Element mit dem Identifier1-Wert "0" und dem Message-Wert "Hello World" enthält. All diese Daten werden vom BDC-Standardmodell bereitgestellt, das von der Projektvorlage Business Data Connectivity-Modell generiert wird.

  19. Schließen Sie den Webbrowser.

Bereinigen des Entwicklungscomputers

Nachdem Sie die Tests der Projektelementerweiterung abgeschlossen haben, entfernen Sie die externe Liste und das BDC-Modell von der SharePoint-Website, und entfernen Sie die Projektelementerweiterung aus Visual Studio.

So entfernen Sie die externe Datenliste von der SharePoint-Website

  1. Klicken Sie im Schnellstartbereich der SharePoint-Website auf die Liste Entity1DataList.

  2. Klicken Sie im Menüband auf der SharePoint-Website auf die Registerkarte Liste.

  3. Klicken Sie auf der Registerkarte Liste in der Gruppe Einstellungen auf Listeneinstellungen.

  4. Klicken Sie unter Berechtigungen und Verwaltung auf Diese Liste löschen. Klicken Sie auf OK, um zu bestätigen, dass Sie die Liste an den Papierkorb senden möchten.

  5. Schließen Sie den Webbrowser.

So entfernen Sie das BDC-Modell von der SharePoint-Website

  • Klicken Sie in der experimentellen Instanz von Visual Studio im Menü Erstellen auf Zurückziehen.

    Das BDC-Modell wird aus der SharePoint-Website entfernt.

So entfernen Sie die Projektelementerweiterung aus Visual Studio

  1. Klicken Sie in der experimentellen Instanz von Visual Studio im Menü Extras auf Erweiterungs-Manager.

    Das Dialogfeld Erweiterungs-Manager wird geöffnet.

  2. Klicken Sie in der Liste der Erweiterungen auf External Data List Generator und anschließend auf Deinstallieren.

  3. Klicken Sie im angezeigten Dialogfeld auf Ja, um zu bestätigen, dass Sie die Erweiterung deinstallieren möchten.

  4. Klicken Sie auf Jetzt neu starten, um die Deinstallation abzuschließen.

  5. Schließen Sie beide Instanzen von Visual Studio (die experimentelle Instanz und die Instanz von Visual Studio, in der die Projektmappe "GenerateExternalDataLists" geöffnet ist).

Siehe auch

Konzepte

Erweitern des SharePoint-Projektsystems

Weitere Ressourcen

Erstellen eines Business Data Connectivity-Modells

Entwerfen eines Business Data Connectivity-Modells