Freigeben über


Erstellen eines Add-In-Ereignisempfängers in SharePoint-Add-Ins

Es ist hilfreich, wenn Sie sich zunächst mit vom Anbieter gehosteten SharePoint-Add-Ins vertraut machen. Außerdem sollten Sie ein paar Add-Ins entwickelt haben, die über das Niveau von „Hello World“ hinausgehen. Weitere Informationen finden Sie unter Erste Schritte beim Erstellen von von einem Anbieter gehosteten SharePoint-Add-Ins.

Darüber hinaus sollten Sie mit dem Behandeln von Ereignissen in SharePoint-Add-Ins vertraut sein.

Abrufen weiterer Codebeispiele

Wenn Sie das fortlaufende Beispiel in diesem Artikel durcharbeiten, haben Sie ein fertiges Codebeispiel. Im Folgenden finden Sie einige weitere Beispiele. Sie folgen nicht alle der in diesem Artikel beschriebenen Architektur. Es gibt mehr als eine gute Möglichkeit, einen Add-In-Ereignisempfänger zu entwerfen, und bedenken Sie auch, dass sich die Anleitungen von Microsoft im Laufe der Zeit weiterentwickeln können.

Hinzufügen eines Ereignisempfängers für das installierte Add-In

  1. Öffnen Sie in Visual Studio das Projekt für das vom Anbieter gehostete SharePoint-Add-In. (Wenn Sie einen Add-In-Ereignishandler für ein in SharePoint gehostetes Add-In hinzufügen, wird sie von den Office-Entwicklertools für Visual Studio in ein vom Anbieter gehostetes Add-In umgewandelt.)

  2. Wählen Sie im Projektmappen-Explorer den Knoten für das SharePoint-Add-In aus.

  3. Legen Sie im Fenster Eigenschaften den Wert von Installiertes Add-In behandeln auf True fest.

    Add-In-Ereignisse im Eigenschaftenfenster

    Von den Office Developer Tools für Visual Studio wird Folgendes ausgeführt:

    • Eine Datei „AppEventReceiver.svc“ mit grundlegendem C#- (oder VB.NET-)Code wird hinzugefügt. Dies ist der Dienst, der das Add-In-Ereignis behandelt.

    • Fügen Sie den folgenden Eintrag zum Abschnitt Eigenschaften der Datei „AppManifest.xml“ hinzu: <InstalledEventEndpoint>~remoteAppUrl/AppEventReceiver.svc</InstalledEventEndpoint>. Dieser Eintrag registriert den Add-In-Ereignisempfänger für SharePoint.

      Hinweis

      Das ~remoteAppUrl-Token ist identisch mit dem für die Webanwendung im vom Anbieter gehosteten verwendeten SharePoint-Add-In. Die Office Developer Tools für Visual Studio gehen davon aus, dass die Domäne der Webanwendung und der Ereignishandler identisch sind. Sollte dies ausnahmsweise einmal nicht der Fall sein, müssen Sie das Token ~remoteAppUrl durch die tatsächliche Domäne Ihres Diensts ersetzen.

    • Erstellen Sie ein Web-Projekt, wenn das SharePoint-Add-In-Projekt nicht bereits über eines verfügt. Die Tools stellen außerdem sicher, dass ein Add-In-Manifest für ein vom Anbieter gehostetes Add-In konfiguriert wird. Sie fügen auch Seiten, Skripts, CSS-Dateien und andere Artefakte hinzu. Wenn der Ereignishandle-Webdienst die einzige Remotekomponente ist, die Ihr Add-In benötigt, können Sie diese aus dem Projekt löschen. Außerdem sollten Sie unbedingt sicherstellen, dass das StartPage-Element im Add-In-Manifest nicht auf eine Seite zeigt, die Sie gelöscht haben.

  4. Wenn sich die SharePoint-Testfarm nicht auf dem Computer mit Visual Studio befindet, konfigurieren Sie das Projekt für das Debuggen mit dem Microsoft Azure Service Bus. Weitere Informationen finden Sie unter Debuggen und Problembehandlung eines Remoteereignisempfängers in einem SharePoint-Add-In.

  5. Wenn eine ProcessOneWayEvent-Methode in der Datei „AppEventReceiver.svc“ vorhanden ist, sollte deren Implementierung nur aus der Zeile throw new NotImplementedException(); bestehen, da diese Methode nicht in einem Add-In-Ereignishandler verwendet werden kann.

    Add-In-Ereignishandler müssen ein Objekt zurückgeben, das SharePoint anweist, ob das Ereignis abgeschlossen oder zurückgesetzt werden soll, und die ProcessOneWayEvent-Methode gibt gar nichts zurück.

  6. Die Datei enthält eine ProcessEvent-Methode, die ähnlich wie die folgende aussieht. (Möglicherweise gibt es auch einen Codeblock, der veranschaulicht, wie ein Clientkontext abgerufen wird. Löschen Sie es, oder kommentieren Sie es aus.)

    public SPRemoteEventResult ProcessEvent(SPRemoteEventProperties properties)
    {
        SPRemoteEventResult result = new SPRemoteEventResult();
    
        return result;
    }
    

    Beachten Sie Folgendes zu diesem Code:

    • Das SPRemoteEventProperties-Objekt wird an den Handlerwebdienst als SOAP-Nachricht gesendet, die Kontextinformationen von SharePoint enthält, beispielsweise eine EventType-Eigenschaft zur Identifizierung des Ereignisses.

    • Das vom Handler zurückgegebene SPRemoteEventResult-Objekt enthält eine Status-Eigenschaft mit den möglichen Werten SPRemoteEventServiceStatus.Continue, SPRemoteEventServiceStatus.CancelNoError und SPRemoteEventServiceStatus.CancelWithError. Der Standardwert der Status-Eigenschaft ist Continue und weist SharePoint an, das Ereignis abzuschließen. Die anderen beiden Werte weisen SharePoint an, Folgendes zu tun: Die beiden anderen Werte teilen SharePoint Folgendes mit:

      • Der Handler wird noch maximal drei Mal ausgeführt.
      • Wenn weiterhin ein „Cancel“-Status zurückgegeben wird, wird das Ereignis abgebrochen, und alles, was als Teil des Ereignisses ausgeführt wurde, wird zurückgesetzt.
  7. Fügen Sie direkt nach der Zeile mit der Deklaration der result-Variable die folgende Verzweigungsstruktur hinzu, um das behandelte Ereignis zu identifizieren.

    switch (properties.EventType)
    {
        case SPRemoteEventType.AppInstalled:
            break;
        case SPRemoteEventType.AppUpgraded:
            break;
        case SPRemoteEventType.AppUninstalling:
            break;
    }
    

    Hinweis

    Wenn Sie Ereignishandler für die Ereignisse AppInstalled, AppUpdated, und AppInstalling haben, erhalten diese ihre eigene URL, die im Add-In-Manifest registriert ist. Sie können also unterschiedliche Endpunkte für sie verwenden, aber in diesem Artikel (und den Office Developer Tools für Visual Studio) wird davon ausgegangen, dass sie genau denselben Endpunkt haben. Aus diesem Grund muss der Code bestimmen, welches Ereignis ihn aufgerufen hat.

  8. Wie unter Einbeziehen von Rollbacklogik und „Bereits erledigt“-Logik in Add-In-Ereignishandler erläutert wurde, möchten Sie bei einem Fehler in der Installationslogik fast immer, dass die Installation des Add-Ins abgebrochen wird und alle Installationsaktionen von SharePoint zurückgesetzt werden. Außerdem sollen die Aktionen Ihres Handlers zurückgesetzt werden.

    Eine Möglichkeit dazu besteht darin, folgenden Code in der case-Struktur für das AppInstalled-Ereignis hinzuzufügen.

    case SPRemoteEventType.AppInstalled:
    try
    {
        // Add-in installed event logic goes here.
    }
    catch (Exception e)
    {
        result.ErrorMessage = e.ErrorMessage;
        result.Status = SPRemoteEventServiceStatus.CancelWithError;
    
        // Rollback logic goes here.
    }
    break;
    

    Hinweis

    Verschieben Sie Installationscode, der länger aus 30 Sekunden dauert, in das Add-In selbst. Sie können ihn zu einer Logik für die erste Ausführung hinzufügen, die ausgeführt wird, wenn das Add-In zum ersten Mal in SharePoint ausgeführt wird. Das Add-In kann eine Meldung wie "Wir bereiten die Dinge für Sie vor". Alternativ kann das Add-In den Benutzer auffordern, den Initialisierungscode auszuführen.

    Ist „Erster Start“-Logik für Ihr Add-In nicht machbar, können Sie den Ereignishandler auch einen asynchronen Remoteprozess starten lassen und dann sofort ein SPRemoteEventResult -Objekt mit dem Status-Wert Continue zurückgeben. Ein Schwachpunkt dieser Strategie ist, dass bei einem Fehler des Remoteprozesses keine Möglichkeit besteht, SharePoint zum Zurücksetzen der Add-In-Installation aufzufordern.

  9. Wie unter Strategien für die Architektur von Add-In-Ereignishandlern erläutert, wird die Handlerdelegierungsstrategie bevorzugt, obwohl diese nicht in jedem Szenario möglich ist. Im fortlaufenden Beispiel zeigen wir Ihnen, wie Sie die Handlerdelegierungsstrategie beim Hinzufügen einer Liste zum Hostweb implementieren. Informationen zum Erstellen eines ähnlichen AppInstalled-Ereignishandlers, der nicht die Handlerdelegierungsstrategie verwendet, finden Sie im SharePoint/PnP/Samples/Core.AppEvents-Beispiel.

    Nachfolgend finden Sie die neue Version des case-Blocks von AppInstalled. Beachten Sie, dass sich Initialisierungslogik, die für alle Ereignisse gilt, oberhalb des switch-Blocks befindet. Da dieselbe Liste, die installiert wird, im AppUninstalling-Handler entfernt wird, wird die Liste hier angegeben.

    SPRemoteEventResult result = new SPRemoteEventResult();
    String listTitle = "MyList";
    
    switch (properties.EventType)
    {               
        case SPRemoteEventType.AppInstalled:
    
    try
    {
            string error = TryCreateList(listTitle, properties);
            if (error != String.Empty)
            {
                throw new Exception(error);            
            }
    }
        catch (Exception e)
    {
            // Tell SharePoint to cancel the event.
            result.ErrorMessage = e.Message;
            result.Status = SPRemoteEventServiceStatus.CancelWithError;               
        }
            break;
        case SPRemoteEventType.AppUpgraded:
        break;
        case SPRemoteEventType.AppUninstalling:
        break;
    }                      
    
  10. Fügen Sie die Listenerstellungsmethode zur AppEventReceiver-Klasse als private-Methode mit folgendem Code hinzu. Beachten Sie, dass die TokenHelper-Klasse eine besondere Methode aufweist, die für das Abrufen eines Clientkontexts für ein Add-In-Ereignis optimiert ist. Durch die Übergabe von false für den letzten Parameter wird sichergestellt, dass der Kontext für das Hostweb gilt.

    private string TryCreateList(String listTitle, SPRemoteEventProperties properties)
    {    
        string errorMessage = String.Empty;          
    
        using (ClientContext clientContext =
            TokenHelper.CreateAppEventClientContext(properties, useAppWeb: false))
        {
            if (clientContext != null)
            {
            }
        }
        return errorMessage;
    }
    
    
  11. Rollbacklogik besteht im Wesentlichen aus Ausnahmebehandlungslogik, und das SharePoint-CSOM (clientseitige Objektmodell) hat einen ExceptionHandlingScope, der es Ihrem Webdienst ermöglicht, die Ausnahmebehandlung an den SharePoint-Server zu delegieren. (Siehe auch Gewusst wie: Verwenden des Ausnahmebehandlungsbereichs.)

    Fügen Sie im vorherigen Codeausschnitt den folgenden Code zum if-Block hinzu.

    ExceptionHandlingScope scope = new ExceptionHandlingScope(clientContext); 
    
    using (scope.StartScope()) 
    { 
        using (scope.StartTry()) 
        { 
        }         
        using (scope.StartCatch()) 
        {                                 
        } 
        using (scope.StartFinally()) 
        { 
        } 
    } 
    clientContext.ExecuteQuery();
    
    if (scope.HasException)
    {
        errorMessage = String.Format("{0}: {1}; {2}; {3}; {4}; {5}", 
            scope.ServerErrorTypeName, scope.ErrorMessage, 
            scope.ServerErrorDetails, scope.ServerErrorValue, 
            scope.ServerStackTrace, scope.ServerErrorCode);
    }
    
  12. Es gibt nur einen Anruf von SharePoint (ExecuteQuery) im vorherigen Codeausschnitt, aber leider reicht einer nicht ganz aus. Jedes Objekt, auf das in unserem Ausnahmebereich verwiesen wird, muss zuerst im Client geladen werden.

    Fügen Sie den folgenden Code über dem Konstruktor für den ExceptionHandlingScope hinzu.

    ListCollection allLists = clientContext.Web.Lists;
    IEnumerable<List> matchingLists =
        clientContext.LoadQuery(allLists.Where(list => list.Title == listTitle));
    clientContext.ExecuteQuery();
    
    var foundList = matchingLists.FirstOrDefault();
    List createdList = null;
    
  13. Der Code zum Erstellen einer Hostwebliste gehört in den StartTry-Block, aber zuerst muss überprüft, ob die Liste bereits hinzugefügt wurde (wie unter Einbeziehen von Rollbacklogik und „Bereits erledigt“-Logik in Add-In-Ereignishandler erläutert). If-then-else-Logik kann über die ConditionalScope -Klasse an den SharePoint-Server delegiert werden. (Siehe auch Gewusst wie: Verwenden des bedingten Bereichs).

    Fügen Sie den folgenden Code im StartTry-Block hinzu.

    ConditionalScope condScope = new ConditionalScope(clientContext, 
            () => foundList.ServerObjectIsNull.Value == true, true);
    using (condScope.StartScope())
    {
        ListCreationInformation listInfo = new ListCreationInformation();
        listInfo.Title = listTitle;
        listInfo.TemplateType = (int)ListTemplateType.GenericList;
        listInfo.Url = listTitle;
        createdList = clientContext.Web.Lists.Add(listInfo);                                
    }
    
  14. Der StartCatch -Block sollte die Erstellung der Liste rückgängig machen, aber zuvor muss überprüft werden, ob die Liste erstellt wurde. Denn möglicherweise wurde eine Ausnahme im StartTry-Block ausgelöst, bevor die Erstellung der Liste abgeschlossen war.

    Fügen Sie den folgenden Code im StartCatch-Block hinzu.

    ConditionalScope condScope = new ConditionalScope(clientContext, 
            () => createdList.ServerObjectIsNull.Value != true, true);
    using (condScope.StartScope())
    {
        createdList.DeleteObject();
    } 
    

    Tipp

    Problembehandlung: Um zu testen, ob sich der StartCatch-Block an der richtigen Stelle befindet, müssen Sie eine Laufzeitausnahme auf dem SharePoint-Server auslösen können. Die Verwendung von throw oder eine Division durch 0 funktioniert nicht, da hierdurch clientseitige Ausnahmen verursacht werden, bevor die Clientlaufzeit den Code bündeln und an den Server senden kann (mit der ExecuteQuery-Methode).

    Fügen Sie stattdessen die folgenden Zeilen zum StartTry-Block hinzu. Die clientseitige Laufzeit akzeptiert dies, verursacht aber eine serverseitige Ausnahme, die erwünscht ist.

    List fakeList = clientContext.Web.Lists.GetByTitle("NoSuchList");

    clientContext.Load(fakeList);

Die gesamte TryCreateList-Methode sollte jetzt wie folgt aussehen. (Der StartFinally-Block ist erforderlich, auch wenn er nicht verwendet wird.)

    private string TryCreateList(String listTitle, SPRemoteEventProperties properties)
    {    
        string errorMessage = String.Empty;  

        using (ClientContext clientContext = 
            TokenHelper.CreateAppEventClientContext(properties, useAppWeb: false))
        {
            if (clientContext != null)
            {
                ListCollection allLists = clientContext.Web.Lists;
                IEnumerable<List> matchingLists = 
                    clientContext.LoadQuery(allLists.Where(list => list.Title == listTitle));
                clientContext.ExecuteQuery();
                var foundList = matchingLists.FirstOrDefault();
                List createdList = null;

                ExceptionHandlingScope scope = new ExceptionHandlingScope(clientContext); 
                using (scope.StartScope()) 
                { 
                    using (scope.StartTry()) 
                    { 
                        ConditionalScope condScope = new ConditionalScope(clientContext, 
                                () => foundList.ServerObjectIsNull.Value == true, true);  
                        using (condScope.StartScope())
                        {
                            ListCreationInformation listInfo = new ListCreationInformation();
                            listInfo.Title = listTitle;
                            listInfo.TemplateType = (int)ListTemplateType.GenericList;
                            listInfo.Url = listTitle;
                            createdList = clientContext.Web.Lists.Add(listInfo);
                        }
                    } 
                    
                    using (scope.StartCatch()) 
                    { 
                        ConditionalScope condScope = new ConditionalScope(clientContext, 
                                () => createdList.ServerObjectIsNull.Value != true, true);
                        using (condScope.StartScope())
                        {
                            createdList.DeleteObject();
                        }    
                    } 

                    using (scope.StartFinally()) 
                    { 
                    } 
                } 
                clientContext.ExecuteQuery();

                if (scope.HasException)
                {
                        errorMessage = String.Format("{0}: {1}; {2}; {3}; {4}; {5}", 
                        scope.ServerErrorTypeName, scope.ErrorMessage, 
                        scope.ServerErrorDetails, scope.ServerErrorValue, 
                        scope.ServerStackTrace, scope.ServerErrorCode);
                }
            }
        }
        return errorMessage;
    }

Tipp

DEBUGGEN: Unabhängig davon, ob Sie die Handlerdelegierungsstrategie verwenden, sollten Sie beim Durchlaufen des Codes mit dem Debugger bedenken, dass in jedem Szenario, in dem der Handler einen "Cancel"-Status zurückgibt, SharePoint den Handler erneut aufrufen wird, und das bis zu drei Mal mehr. Somit durchläuft der Debugger den Code bis zu vier Mal.

Tipp

CODEARCHITEKTUR: Da Sie Komponenten im Add-In-Web mit deklarativem Markup außerhalb Ihres Handlers installieren können, möchten Sie wahrscheinlich keine der 30 Sekunden, die dem Handler für die Interaktion mit dem Add-In-Web zur Verfügung stehen, verschwenden. Sollten Sie dies dennoch tun, beachten Sie, dass der Code ein separates ClientContext-Objekt für das Add-In-Web benötigt. Dies bedeutet, dass das Add-In-Web und das Hostweb unterschiedliche Komponenten sind, genau wie sich eine SQL Server-Datenbank davon unterscheidet. Eine Methode, die das Add-In-Web aufruft, befindet sich daher im try-Block des case-Blocks von AppInstalled, genau wie die TryCreateList-Methode im nächsten Beispiel. Ihr Handler muss jedoch keine Rollbackaktionen ausführen, die im Add-In-Web ausgeführt werden. Wenn ein Fehler auftritt, muss nur das Ereignis abgebrochen werden, da SharePoint das gesamte Add-In-Web löscht, wenn das Ereignis abgebrochen wird.

Erstellen eines Ereignisempfängers für die Deinstallation des Add-Ins

  1. Legen Sie die Eigenschaft Deinstallation des Add-Ins verarbeiten des Projekts auf True fest. Von den Tools wird keine weitere Webdienstdatei erstellt, falls eine vorhanden ist. Aber sie fügen dem Add-In-Manifest ein UninstallingEventEndpoint-Element hinzu.

  2. Code im case-Block von AppUninstalling sollte Artefakte des Add-Ins entfernen, die nicht benötigt werden, nachdem das Add-In aus dem endgültigen Papierkorb gelöscht wird, wodurch das Ereignis ausgelöst wird. Sie müssen jedoch, wann immer möglich, die Komponenten „zurückziehen“ anstatt sie vollständig zu löschen. Sie müssen sie nämlich wiederherstellen, wenn das Deinstallationsereignis zurückgesetzt werden muss. In diesem Fall befindet sich das Add-In nach wie vor im endgültigen Papierkorb und ein Benutzer könnte es wiederherstellen und erneut verwenden. Das bloße Neuerstellen einer gelöschten Komponente in Ihrer Rollbacklogik reicht möglicherweise nicht aus, um das Add-In wieder zu aktivieren, aber alle Daten oder Konfigurationseinstellungen in der Komponente würden verloren gehen.

    Diese Strategie ist für SharePoint-Komponenten verhältnismäßig einfach, da SharePoint über einen Papierkorb verfügt, aus dem Elemente wiederhergestellt werden können, und es gibt CSOM-APIs, um darauf zuzugreifen. In späteren Schritten dieses Verfahrens wird gezeigt, wie. Für andere Plattformen sind möglicherweise andere Techniken erforderlich. Wenn Sie beispielsweise eine Zeile in einer SQL Server-Tabelle im Deinstallationshandler des Add-Ins zurückziehen möchten, kann eine gespeicherte T-SQL-Prozedur in dem Handler eine IsDeleted-Spalte zu der Tabelle hinzufügen und diese für die Zeile auf True festlegen. Wenn ein Fehler auftritt, wird der Wert von der Rollbacklogik auf False zurückgesetzt. Wenn das Verfahren ohne Fehler abgeschlossen wird, kann unmittelbar, bevor ein Erfolgsflag zurückgegeben wird, ein Zeitgeberauftrag zum späteren Löschen der Zeile festgelegt werden.

    Manchmal möchten Sie Daten, wie z. B. Listen, auch nach dem Löschen des Add-Ins behalten, aber als Beispiel in diesem Artikel wird im folgenden Deinstallationsereignishandler die Liste gelöscht, die mit dem Installationsereignishandler erstellt wurde.

    case SPRemoteEventType.AppUninstalling:
    
    try
    {
        string error = TryRecycleList(listTitle, properties);
        if (error != String.Empty)
        {
            throw new Exception(error);
        }
    }
    catch (Exception e)
    {
        // Tell SharePoint to cancel the event.
        result.ErrorMessage = e.Message;
        result.Status = SPRemoteEventServiceStatus.CancelWithError;
    }
    break;
    
  3. Fügen Sie die Hilfsmethode für die Wiederverwendung der Liste hinzu. Beachten Sie Folgendes zu diesem Code:

    • Der Code verschiebt die Liste in den Papierkorb, anstatt sie dauerhaft zu löschen. Dies ermöglicht das Wiederherstellen der Liste und der zugehörigen Daten nach einem Fehler im Ereignis, was im StartCatch-Block geschieht. Wenn die Methode erfolgreich ist und das Ereignis abgeschlossen ist, wird das Add-In dauerhaft aus dem endgültigen Papierkorb gelöscht, aber die Liste befindet sich noch im Papierkorb.

    • Der Code prüft das Vorhandensein der Liste, bevor sie wieder verwendet wird, da ein Benutzer sie bereits auf der SharePoint-Benutzeroberfläche wieder verwendet haben könnte. Auf ähnliche Weise überprüft der Rollbackcode das Vorhandensein der Liste im Papierkorb, bevor sie wiederhergestellt wird, da ein Benutzer sie möglicherweise bereits wiederhergestellt haben oder in den endgültigen Papierkorb verschoben haben könnte.

    • Es gibt zwei bedingte Bereiche, die das Vorhandensein einer Liste testen, indem geprüft wird, ob ein Verweis darauf Null ist. Beide weisen jedoch einen internen if-Block auf, der genau das gleiche Objekt ein zweites Mal auf Ungültigkeit testet. Die externen Tests mit bedingten Bereichsblöcken werden auf dem Server ausgeführt, die internen Ungültigkeitstests sind aber auch erforderlich. Dies liegt daran, dass die Clientlaufzeit den Code Zeile für Zeile durchläuft, um die XML-Nachricht zu erstellen, die die ExecuteQuery-Methode an den Server sendet. Wenn die Verweise auf die Objekte FoundList und RecycledList erreicht werden, löst eine dieser Zeilen eine Nullverweis-Ausnahme aus, es sei denn, diese sind innerhalb der internen Ungültigkeitsprüfungen gekapselt.

      private string TryRecycleList(String listTitle, SPRemoteEventProperties properties)
      {
          string errorMessage = String.Empty;
      
          using (ClientContext clientContext = 
              TokenHelper.CreateAppEventClientContext(properties, useAppWeb: false))
          {
              if (clientContext != null)
              {
                  ListCollection allLists = clientContext.Web.Lists;
                  IEnumerable<List> matchingLists = 
                      clientContext.LoadQuery(allLists.Where(list => list.Title == listTitle));
                  RecycleBinItemCollection bin = clientContext.Web.RecycleBin;
                  IEnumerable<RecycleBinItem> matchingRecycleBinItems = 
                      clientContext.LoadQuery(bin.Where(item => item.Title == listTitle));        
                  clientContext.ExecuteQuery();
      
                  List foundList = matchingLists.FirstOrDefault();
                  RecycleBinItem recycledList = matchingRecycleBinItems.FirstOrDefault();    
      
                  ExceptionHandlingScope scope = new ExceptionHandlingScope(clientContext);
                  using (scope.StartScope())
                  {
                      using (scope.StartTry())
                      {
                          ConditionalScope condScope = new ConditionalScope(clientContext, 
                              () => foundList.ServerObjectIsNull.Value == false, true);
                          using (condScope.StartScope())
                          {
                              if (foundList != null)
                              {
                                  foundList.Recycle();
                              }
                          }
                      }
                      using (scope.StartCatch())
                      {
                          ConditionalScope condScope = new ConditionalScope(clientContext, 
                              () => recycledList.ServerObjectIsNull.Value == false, true);
                          using (condScope.StartScope())
                          {
                              if (recycledList != null)
                              {
                                  recycledList.Restore(); 
                              }
                          }
                      }
                      using (scope.StartFinally())
                      {
                      }
                  }
                  clientContext.ExecuteQuery();
      
                  if (scope.HasException)
                  {
                      errorMessage = String.Format("{0}: {1}; {2}; {3}; {4}; {5}", 
                          scope.ServerErrorTypeName, scope.ErrorMessage, 
                          scope.ServerErrorDetails, scope.ServerErrorValue, 
                          scope.ServerStackTrace, scope.ServerErrorCode);
                  }
              }
          }
          return errorMessage;
      }
      

So debuggen und testen Sie einen Ereignisempfänger für die Deinstallation des Add-Ins

  1. Öffnen Sie die folgenden Seiten in verschiedenen Fenstern oder Registerkarten:

    • Websiteinhalte
    • Websiteeinstellungen – Papierkorb (_layouts/15/AdminRecycleBin.aspx?ql=1)
    • Papierkorb – Endgültiger Papierkorb (_layouts/15/AdminRecycleBin.aspxView=2&?ql=1)
  2. Drücken Sie F5, und vertrauen Sie dem Add-In, wenn Sie dazu aufgefordert werden. Die Startseite des Add-Ins wird geöffnet. Wenn Sie nur den Deinstallationshandler testen möchten, können Sie dieses Browserfenster schließen. Wenn Sie den Handler debuggen, lassen Sie ihn jedoch geöffnet. Wenn sie geschlossen wird, wird die Debugsitzung beendet.

  3. Aktualisieren Sie die Seite „Websiteinhalte“, und wenn das Add-In angezeigt wird, entfernen Sie es.

  4. Aktualisieren Sie die Seite „Websiteeinstellungen – Papierkorb“. Das Add-In wird als das erste Element angezeigt. Aktivieren Sie das Kontrollkästchen daneben, und klicken Sie auf Auswahl löschen.

  5. Aktualisieren Sie die Seite „Papierkorb – Endgültiger Papierkorb“. Das Add-In wird als das erste Element angezeigt. Aktivieren Sie das Kontrollkästchen daneben, und klicken Sie auf Auswahl löschen. SharePoint ruft sofort den Deinstallationshandler für das Add-In auf.

Erstellen eines Ereignisempfängers für die Aktualisierung des Add-Ins

Ausführliche Informationen zum Erstellen eines Handlers für das aktualisierte Add-In finden Sie unter Erstellen eines Handlers für das Updateereignis in SharePoint-Add-Ins.

URL- und Hostingeinschränkungen für Add-In-Ereignisempfänger in Produktion

Der Remoteereignisempfänger kann in der Cloud oder auf einem lokalen Server gehostet werden, der nicht auch als SharePoint-Server verwendet wird. Die URL eines Produktionsempfängers kann keinen bestimmten Port angeben. Dies bedeutet, dass Sie entweder Port 443 für HTTPS verwenden müssen (empfohlen) oder Port 80 für HTTP. Wenn Sie HTTPS verwenden und der Empfänger lokal ist, das Add-In sich jedoch in SharePoint Online befindet, muss der Hostserver über ein öffentlich vertrauenswürdiges Zertifikat von einer Zertifizierungsstelle verfügen. (Ein selbst signiertes Zertifikat funktioniert nur, wenn sich das Add-In in einer lokalen SharePoint-Farm befindet.)

Siehe auch