Das ContentEditorWebPart ist eigentlich eine feine Sache um bei einer SharePoint Applikation Content auf eine Seite zu packen, den der User nachträglich noch anpassen kann. Man findet auch einige Beispiele im Netz, wie dies programmatisch gemacht werden muss, aber alle Beispiele beschränken sich darauf, unformatierten Text zu setzen. Hier möchte ich zeigen wie man XHTML Content setzen kann.

 

Zur Erinnerung, der prinzipielle Vorgang beim Erzeugen und Hinzufügen ist wie folgt:

public void AddEditableContent(SPWeb web, string pageName, string zone, string title, string content)
{
    using (var elevatedSite = new SPSite(web.Site.ID))
    using (SPWeb elevatedWeb = elevatedSite.AllWebs[CurrentWeb.ID])
    using (SPLimitedWebPartManager webPartManager =
            elevatedWeb.GetLimitedWebPartManager(
                SPUtility.ConcatUrls(elevatedWeb.Url, pageName), 
                PersonalizationScope.Shared))
    {
        var xmlDoc = new XmlDocument();
        XmlElement container = xmlDoc.CreateElement("container");
        container.InnerText = content;

        var editable = new ContentEditorWebPart { Title = title, Content = container };

        webPartManager.AddWebPart(editable, zone, 1);
        webPartManager.SaveChanges(editable);
        web.Update();
    }
}

Content erwartet ein XmlElement, dabei ist der Elementname völlig egal. Logische Annahme wäre also, man setzt (X-)Html als InnerXml statt InnerText. Ersetzen wir also container.InnerText durch container.InnerXml und probieren als content Parameter mal einen Html String:

<h2>Willkommen</h2><p><b>Fettes</b> Hallo!</p>

mit dem Ergebnis:

Willkommen Fettes Hallo! ohne jede Formatierung.  Grummel! Offensichtlich wird der Value des Xml/Html in das Content Element des Webparts kopiert, dabei geht dann jede Struktur verloren Trauriges Smiley

Nach ein bisschen Rumprobieren kam ich schließlich auf die Lösung. Damit die Formatierung nicht verloren geht, muss man sie vor der Interpretation durch XML schützen. Dies geht entweder via SPEncode.XmlRemoveControlChars oder durch eine CDATA Section. Die endgültige Version von Zeile 12 lautet daher:

container.InnerXml = string.Format("<![CDATA[{0}]]>", content);

Jetzt kriegen wir:

Willkommen


Fettes Hallo!

Man macht also relativ aufwändig ein XmlDokument, kapselt die Html Struktur in einer Xml sicheren Textversion und übergibt dann ein XmlElement… Wer hat das entworfen???? Was hat der geraucht??? Wieviel sinnvoller wäre es doch, einfach einen String zu übergeben!

Advertisements