cool IT Team-Blog

Automatischer E-Mail Verteiler als Sandboxed Web Part für SharePoint 2010

Anforderung

SharePoint Kontaktlisten werden üblicherweise benutzt, um von Mitarbeitern, Kunden, Partnern etc. Kontaktinformationen zu hinterlegen. Eine solche Kontaktinformation ist z. B. die E-Mail Adresse eines Kontaktes.

Möchte man nun eine E-Mail an alle Kontakte einer Kontaktliste oder eine Auswahl von Kontakten dieser Liste senden, so findet man in SharePoint keine einfache Möglichkeit, einen entsprechenden E-Mail Verteiler zu erstellen. 

Da wir eine solche Funktion auch in unserem SharePoint-Web benötigen, habe ich einen einfachen Web Part implementiert, welcher einen mailto-Link aus einer SharePoint Liste mit E-Mail Adressen generiert. Zusätzlich steht ein Filterkriterium zur Verfügung, um nur bestimmte E-Mail-Adressen in den Verteiler aufzunehmen.
 
Damit dieser Web Part auch von einem SiteCollection-Administrator eingespielt werden kann, der keinen Zugriff auf die SharePoint Zentraladministration besitzt, habe ich diesen Web Part als Sandboxed Solution implementiert.
 
Wichtiger Hinweis:
Damit Sandboxed Solutions in einer Share Point Umgebung verwendet werden können, muss in der SharePoint Farm das Microsoft SharePoint Foundation Sandboxed Code Service gestartet sein. Dieses Service ist standardmäßig gestoppt. Zu finden ist dieses Service in der SharePoint Zentraladministration unter "System Settings "->"Manage Services on Server".
 

Entwicklungsumgebung

Bei der Implementierung des Web Parts kam folgende Entwicklungsumgebung zum Einsatz:

- Microsoft SharePoint 2010
- Microsoft Visual Studio 2010 (C#)
- Visual Studio 2010 SharePoint Power Tools
 
Die Visual Studio 2010 SharePoint Power Tools stellen ein Item Template für Sandboxed Visual Webparts zur Verfügung und stellen auch sicher, dass nur SharePoint Objekte verwendet werden, die in einer Sandboxed Solution erlaubt sind. Für eine Sandboxed Solution unerlaubte Elemente führen zu einem Übersetzungfehler.
 
Die Visual Studio 2010 SharePoint Power Tools können hier heruntergeladen werden.
 

Implementierung

In Visual Studio wählt man als Projekt Template "Empty SharePoint Projekt":

image031.jpg
 
Nur dieses Template erlaubt im nächsten Schritt die Auswahl von "Deploy as a sandboxed solution":

image032.jpg
 
Im Solution Explorer bekommen wir nun folgenden Projektbaum:

image033.jpg
 
Nach Rechtsklick auf den Root-Knoten und Auswahl von "Add"-"New item..." können wir nun einen Sandboxed Visual Web Part zu unserem Projekt hinzufügen:

image034.jpg
 
Wir benennen den Web Part als "MailToControl" und erhalten nun folgenden Projektbaum:

image035.jpg
 
Nun können wir mit der Implementierung des Web Parts beginnen:
 
Durch Doppelklick von MailToControl.asc öffnet sich der Web Part Designer. Ich habe hier eine CheckBoxList für den Filter, einen Button zum Aktualisieren des E-Mail-Verteiler-Links und ein HyperLink-Control für den generierten E-Mail-Verteiler hinzugefügt:
 
image036.jpg
 
Der Filter wird später mit einem SharePoint Choice-Feld verknüpft. Der Filter zeigt alle Elemente des Choice-Feldes mit einer Checkbox an und erlaubt ein beliebiges Kombinieren dieser Elemente.

Der vom Designer generierte Code sieht folgendermaßen aus:
 

<p>

    <asp:CheckBoxList ID="listFilter" runat="server">

    </asp:CheckBoxList>

</p>

<p>

  <asp:Button ID="btnGenerateLink" runat="server" Text="E-Mail Verteiler aktualisieren"

        onclick="btnGenerateLink_Click" />

</p>

<p>

    <asp:HyperLink ID="linkMailTo" runat="server">mailto:</asp:HyperLink>

</p> 

 
Wie man hier sieht, habe ich auch noch einen "onclick"-Eventhandler "btnGenerateLink_Click" hinzugefügt, über den der mailto-Link aktualisiert werden kann.
 
Der Web Part soll später für beliebige Share Point Listen einsetzbar sein, d. h. wir benötigen eine Konfigurationsmöglichkeit des Namen der Shar Point Liste, des Namen der E-Mail Spalte und des Namen des Choice Feldes für den Filter.
 
Diese Konfigurationsmöglichkeiten implementieren wir in der Code-Behind Klasse unseres Web Part Controls (MailToControl.ascx.cs) als Public Properties:
 

[WebBrowsable(true),

    Category("Miscellaneous"),

    WebDisplayName("SharPoint list"),

    DefaultValue(""),

    Personalizable(PersonalizationScope.Shared),

    WebDescription("")]

public string listTitle { get; set; }

 

[WebBrowsable(true),

    Category("Miscellaneous"),

    WebDisplayName("Filter column (choice field!)"),

    DefaultValue(""),

    Personalizable(PersonalizationScope.Shared),

    WebDescription("")]

public string listFilterCol { get; set; }

 

[WebBrowsable(true),

    Category("Miscellaneous"),

    WebDisplayName("Email column"),

    DefaultValue("Email"),

    Personalizable(PersonalizationScope.Shared),

    WebDescription("")]

public string listEmailCol { get; set; }

Mit "Category("Miscellaneous")" teilen wir dem Web Part mit, dass dieses Property in einem "Miscellaneous"-Bereich der Web Part Konfiguration editierbar ist.
 
Der "WebDisplayName" wird im Label für die Property-Textbox angezeigt.
 
"Personalizable(PersonalizationScope.Shared)" gibt an, dass der konfigurierte Wert für alle Anwender gelten soll.
 
Damit der Web Part auch für Listen ohne Choice-Feld funktioniert, kann das Property "Filter column" in unserer Implementierung auch leer gelassen werden.
 
Als nächstes implementieren wir die "Page_Load"-Methode. Hier wird die CheckBoxList mit den möglichen Filterelementen initialisiert und der ungefilterte mailto-E-Mail-Verteiler-Link ausgegeben.
 
Die Initialisierungen dürfen natürlich nur beim initialen Laden der Seite, auf dem der Web Part eingebettet ist, erfolgen. Bei einem PostBack, also wenn man z. B. den "E-Mail Verteiler aktualisieren"-Button klickt, kümmert sich das ASP.NET Framework darum, dass die Daten nicht verloren gehen.
 
Fehler, die aufgrund einer falschen Konfiguration des Web Parts auftreten, werden der Einfachheit halber im HyperLink Control angezeigt.
 

protected void Page_Load(object sender, EventArgs e)

{

    if (!Page.IsPostBack)

    {

        if (String.IsNullOrEmpty(listTitle)) return;

 

        // Get current web reference from  SharePoint context

        SPWeb web = SPContext.Current.Web;

 

        // Get desired SharePoint list

        SPList list = null;

        try

        {

            list = web.Lists[listTitle];

        }

        catch

        {

            linkMailTo.Text = (String.Format("ERROR: Unknown list '{0}'.", listTitle));

            return;

        }

 

        // Shall we use a filter column?

        if (!String.IsNullOrEmpty(listFilterCol))

        {

            SPFieldChoice field = null;

            try

            {

                field = list.Fields[listFilterCol] as SPFieldChoice;

            }

            catch

            {

                linkMailTo.Text = (String.Format("ERROR: Unknown list column '{0}'.", listFilterCol));

                return;

            }

 

            if (field == null)

            {

                linkMailTo.Text = (String.Format("ERROR: List column '{0}' is not a choice field.", listFilterCol));

                return;

            }

 

            // Add choices to filter dropdown box

            foreach (string choice in field.Choices)

            {

                ListItem filter = new ListItem();

                filter.Text = choice;

                filter.Selected = true;

                listFilter.Items.Add(filter);

            }

        }

               

        // Show unfiltered 'mailto' link.

        btnGenerateLink_Click(null, EventArgs.Empty);               

    }

}

Nun benötigen wir noch die Implementierung des "btnGenerateLink_Click" Eventhandlers, welcher den E-Mail Verteiler unter Berücksichtigung des eingestellen Filters erstellt und im HyperLink-Control ausgibt.
 

protected void btnGenerateLink_Click(object sender, EventArgs e)

{

    StringBuilder filterQry = new StringBuilder();

           

    // Gnerate CAML query string from filter listbox

    bool bFirst = true;

    foreach (ListItem filter in listFilter.Items)

    {

        if (!filter.Selected) continue;

 

        if (!bFirst) filterQry.Insert(0, "<Or>");

 

        filterQry.AppendFormat("<Eq><FieldRef Name='{0}' /><Value Type='Text'>{1}</Value></Eq>",

                                listFilterCol, filter.Text);

 

        if (!bFirst) filterQry.Append("</Or>");

 

        bFirst = false;

    }

 

    // Empty filter -> show empty, inactive 'mailto' link (but only if

    // listFilter.Items.Count > 0 which means that we have a filter field

    // configured in the web part)

    if (listFilter.Items.Count > 0 && bFirst)

    {

        linkMailTo.Text = "mailto:";

        linkMailTo.NavigateUrl = String.Empty;

        return;

    }

 

    // Complete the CAML query string

    filterQry.Insert(0, "<Where>");

    filterQry.Append("</Where>");

 

    // Setup the CAML query

    SPQuery qry = new SPQuery();

    qry.Query = filterQry.ToString();

 

    // In the result set we just need the email column

    qry.ViewFields = String.Format("<FieldRef Name='{0}' />", listEmailCol);

 

    // Get SharePoint list and execute the CAML query

    SPWeb web = SPContext.Current.Web;

    SPList list = web.Lists[listTitle];

    SPListItemCollection items = list.GetItems(qry);

 

    // Build 'mailto' link

    StringBuilder mailList = new StringBuilder("mailto:");

    foreach (SPListItem item in items)

    {

        mailList.AppendFormat("{0};", item[0]);

    }

    if (mailList.Length > 7) mailList.Remove(mailList.Length - 1, 1);

 

    // Show 'mailto' link

    linkMailTo.Text = mailList.ToString();

    linkMailTo.NavigateUrl = mailList.ToString();

}

Damit ist der Web Part fertig implementiert und kann mit "F5" gleich mal getestet werden. "F5" startet die im Projekt Wizard angegebene SharePoint Site und der Web Part wird automatisch in die Web Part Gallary hochgeladen.
 
Zum Erstellen eines SharePoint Solution Packages für diesen Web Part wählt man im Visual Studio unter dem Build-Menü den Punkt "Package" aus. Visual Studio erzeugt daraufhin unter dem \bin\Release-Verzeichnis (bzw. \bin\Debug je nach eingestellter Solution Konfiguration) eine .WSP Datei, welche nun in eine SharePoint Site Collection eingespielt werden kann.
 

Einspielen der Sandboxed Solution in SharePoint

Zum Einspielen des vorhin erstellten Solution Packages ist in der Top-Level Site der gewünschten SharePoint SiteCollection der Punkt  "Site Actions"-"Site Settings" aufzurufen. Unter den Galleries befindet sich ein Link "Solutions", über den wir unser Solution Package hochladen können:
 
image037.jpg

Nach Anklicken von "Solutions" gelangt man zu:
 
image038.jpg
 
 
Damit hier der Ribbon mit dem Upload Button sichtbar wird, muss man auf den Reiter "Solutions" klicken:
 
image039.jpg
 
Nach Anklicken von "Upload Solution" erhält man den Upload Dialog:
 
image040.jpg
 
Nach Betätigen von "OK" gelangt man zu:
 
image041.jpg

Durch Anklicken von "Activate" wird das Solution Package zur Solution Gallary hinzugefügt und der Web Part kann nun auf einer beliebigen Web Part Seite in der aktuellen Site Collection hinzugefügt werden.
Hinweis:
Sollte hier der Activate-Button gesperrt sein, so ist in der Share Point Farm das Microsoft SharePoint Foundation Sandboxed Code Service  nicht gestartet.

Web Part verwenden

Der in die Site Collection importierte Web Part kann nun auf der gewünschten SharePoint Seite eingefügt werden. Dazu ist unter "Site Actions" "Edit Page" auszuwählen und unter dem Reiter "Insert" der Button "Web Part" anzuklicken. Unser Web Part ist unter der Kategorie "Custom" zu finden:
 
image042-(1).jpg
 
Auf der Seite eingefügt präsentiert sich der Web Part wie folgt:
 
image043-(1).jpg
 
Über den Punkt "Edit Web Part" im Web Part Menü lässt sich unser Web Part konfigurieren:
 
image044.jpg
 
Nach Bestätigen der Konfiguration mit "OK" erhalten wir beispielsweise:
 
image045.jpg
 
Nach Anklicken des Mailverteilers öffnet sich automatisch der standardmäßig eingestellte E-Mail Client und fügt im "An:"-Feld den Verteiler ein.
 
Ist doch cool, oder? 
 
Verfasst: 04.03.2011 13:29:32 von Roland Koller
Tags: email, sandbox, SharePoint 2010, Solution, web part

1


Kommentare
Für diesen Blogbeitrag liegen zurzeit keine Kommentare vor.
Einen Kommentar schreiben



 Security code