Question

I am creating a custom Document Set content type through server-side/C# code as follows:

SPContentType docSet = web.AvailableContentTypes["Document Set"];
SPContentType newCType = new SPContentType(docSet, web.ContentTypes, "My Custom Doc Set");
newCType = web.ContentTypes.Add(newCType);
newCType.Group = "My Content Types";
newCType.Update();

I then proceed to add some fields by creating new FieldLink objects and adding them to the newCType.FieldLinks collection.

I then proceed to update the WelcomePageFields XML document in the newCType.XmlDocuments as follows:

Dictionary<string, string> welcomPageFieldsList = new Dictionary<string, string>()
{
    "Field1InternalName", "field-1-guid",
    "Field2InternalName", "field-2-guid"
    // etc
}

XNamespace xlmns = "http://schemas.microsoft.com/office/documentsets/welcomepagefields";
XElement welcomPageFieldsXML = new XElement(xlmns + "WelcomePageFields");

foreach (KeyValuePair<string, string> fieldInfo in welcomPageFieldsList)
{
    XElement fieldElement = new XElement("WelcomePageField",
        new XAttribute("Name", fieldInfo.Key),
        new XAttribute("id", fieldInfo.Value)
    );
    welcomPageFieldsXML.Add(fieldElement);
}

List<XElement> xmlDocs = newCType.XmlDocuments.Cast<string>().Select(doc => XElement.Parse(doc)).ToList();
XElement oldXmlDoc = xmlDocs.Find(oldDoc => oldDoc.Name.LocalName == welcomPageFieldsXML.Name.LocalName);
newCType.XmlDocuments.Delete(oldXmlDoc.Name.NamespaceName);
XmlDocument newXMLDoc = new XmlDocument();
newXMLDoc.Load(welcomPageFieldsXML.CreateReader());
newCType.XmlDocuments.Add(newXMLDoc);
newCType.Update();

This all works fine, but when I try to create a new document set instance based on that content type in a document library, I get a NullReferenceException from the Welcome Page Fields webpart on the document set homepage. I thought maybe I forgot to actually add one of the fields to the content type that I reference in the XML Documents, but no, they all match up. So I dug into the ULS logs, and I see that actually the error is thrown because some part of the process is accessing the welcome page fields from the document set template, and that's what's throwing the exception.

So I tried adding code to get the template, and add the fields to the WelcomPageFields on the template, but that also threw a NullReferenceException.

So I did a little digging with Powershell, got my custom content type, and then got the DocumentSetTemplate object associated with my custom document set, and I see that the WelcomePageFields property is apparently null:

Powershell screenshot

According to the documentation about the DocumentSetTemplate.WelcomePageFields property, it's a read-only property, so I can't new up a WelcomePageFieldCollection and assign it to the template so everything gets hooked up properly.

So - how do you properly create a custom content type based on Document Set using server-side/C# code so that the WelcomePageFields property of the template is initialized properly?


Update:

It seems like the WelcomePageFields property on the template is an empty collection (not null) when the content type is initially created, and it's the process of deleting the old WelcomePageFields XML document from the content type that clears out the property on the template - even though I replace the XML document with another WelcomePageFields XML document before I call Update() on the content type?

Will be doing more research/experimentation, but could still use any pointers or suggestions for how to get this done...

Was it helpful?

Solution

Well, it turns out that it was indeed caused by deleting the WelcomePageFields XML document from the content type's XmlDocuments property. Somehow that triggers the deleting of the WelcomePageFieldCollection on the template, making the template's WelcomePageFields property null, even though I had re-added a WelcomePageFields XML document to the XmlDocuments before I called Update() on the content type.

But, as it turns out, if you edit/update the WelcomePageFields on the template, it will automatically update the XmlDocuments on the content type. So in the end all I needed to do was to add the fields I wanted to be on the Document Set homepage to the template and not touch the XmlDocuments at all.

Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top