When iterating the fields of a list how do you know which columns are yours and which are built-in ?

I know a solution for "classic" SDK using SPField.SourceId (https://sharepoint.stackexchange.com/questions/95488/retrieving-columns-created-by-user-not-built-in-columns) but I can't find one for CSOM. I thought UserCreated was the way to go for but it looks like it's not

So how do you tell apart theirs and mine ? Using a combination of Hidden CanBeDeleted FromBaseType ? Checking for a list of special internalNames ?

        ClientContext context = new ClientContext(siteUrl);
        context.Credentials = creds;
        Web web = context.Web;
        var list = web.Lists.GetByTitle(listName);


        foreach (Field field in list.Fields)
        bool thisColumnWasCreatedByUser =   
                    field .FromBaseType == false &&
                    //this.InternalName != "Title" && // builtin but I'd rather keep it
                    field .InternalName != "_dlc_DocId" && // probably safe
                    field .InternalName != "_dlc_DocIdUrl" &&
                    field .InternalName != "_dlc_DocIdPersistId" &&
                    field .InternalName != "Combine" && // sucks
                    field .InternalName != "RepairDocument" // sucks too


Mixing suggestions by Viraj Gorajia and Dikesh Gandhi, my current solution is

bool thisColumnWasCreatedByUser = 
field .FromBaseType == false &&
(!field .SchemaXml.Contains(" SourceID=\"http")) && // remove "Title", "Combine", "RepairDocument" 
(!field .EntityPropertyName.StartsWith("OData__")) // field .Sealed == true could be working too but I don't know if it could exclude valid results
  • Possible duplicate of Retrieving columns created by user not built in columns Commented Nov 23, 2016 at 10:42
  • NO. It is not a duplicate. I already cited this link as not being applicable to CSOM.
    – frenchone
    Commented Nov 23, 2016 at 10:56
  • In fact you can get a SourceId (like for a MS.sharepoint.spfield) by parsing SchemaXml (of your MS.sharepoint.client.spfield)
    – frenchone
    Commented Nov 23, 2016 at 13:36

3 Answers 3


Set condition as shown below:

  • Yes that's a starting point. But I still have built-in columns after that. "Title" "_dlc_DocId" "_dlc_DocIdUrl" "_dlc_DocIdPersistId" "Combine" "RepairDocument"
    – frenchone
    Commented Nov 23, 2016 at 10:57
  • Try with this condition like if(!field.FromBaseType && field.ShowInEditForm == null) Commented Nov 23, 2016 at 11:10
  • There's no ShowInEditForm property but only a SetShowInEditForm(bool) (which is quite strange by the way)
    – frenchone
    Commented Nov 23, 2016 at 11:27
  • Try this one !field.Sealed Commented Nov 23, 2016 at 11:35
  • this doesn't filter "Combine" and "RepairDocument"
    – frenchone
    Commented Nov 23, 2016 at 13:29

Right now this is my best answer

bool thisColumnWasCreatedByUser = 
field .FromBaseType == false &&
(!field .SchemaXml.Contains(" SourceID=\"http")) &&
(!field .EntityPropertyName.StartsWith("OData__"))

!field .SchemaXml.Contains(" SourceID=\"http") will remove "Title", "Combine", "RepairDocument"

!field .EntityPropertyName.StartsWith("OData__") will remove "_dlc_DocId", "_dlc_DocIdUrl", "_dlc_DocIdPersistId"


Try this:

if (!field.SourceId.StartsWith("http://"))
   // do your action for completely custom fields

You will get Url, starting with "http://schemas.microsoft.com" for standard built-in fields.

Hope this will help you.

  • 1
    This is for CSOM (Microsoft.sharepoint.client.Field and not Microsoft.Sharepoint.SPField) . You don't have SourceId on Field. I managed to get one by parsing SchemaXml property. But the filter is still incomplete => this filters out "Title" column (and "RepairDocument" and "Combine") but not _dlc_DocId, _dlc_DocIdUrl, _dlc_DocIdPersistId
    – frenchone
    Commented Nov 23, 2016 at 13:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.