Basically, I want to create a list content type
Basically, that's your problem, because there is no such thing.
As opposed to columns that can be created on both list and site level, content types are always created on web level and later added to list.
This can be confusing for two reasons:
- In CSOM both
Web
and List
contain property ContentTypes
represented by the same class ContentTypeCollection
. This is inherited from SSOM (SPWeb
, SPList
, SPContentTypeCollection
respectively).
In SharePoint SPContentTypeCollection
has different behavior when it's parent is web and list. This is bad design and lazy programming done by SharePoint team as early as WSS 3.0. Now we need to work with API that sometimes behaves in unexpected way.
- Id of content type added to list suggests, it's a child content type.
We can create multiple content types with the same parent, but we can only add them once to a list. This behavior matches what you can do using UI. Try adding Document
content type to document library - it's not even available in the picker.
Ok, ranting over. What you need to do is create it on web first:
var web = context.Web;
var list = web.Lists.GetByTitle("Documents");
var baseCT = web.ContentTypes.GetById("0x0101");
var creationInfo1 = new ContentTypeCreationInformation
{
Name = "Document1",
ParentContentType = baseCT
};
var creationInfo2 = new ContentTypeCreationInformation
{
Name = "Document2",
ParentContentType = baseCT
};
var childCT1 = web.ContentTypes.Add(creationInfo1);
var childCT2 = web.ContentTypes.Add(creationInfo2);
list.ContentTypes.AddExistingContentType(childCT1);
list.ContentTypes.AddExistingContentType(childCT2);
//You can also use list.ContentTypes.Add() method, but it takes few lines more
context.ExecuteQuery();
And yes, this is working code. There's no context.Load()
. There's no Update()
. Single ExecuteQuery()
is all you need.