4

Is it possible to create fields in SharePoint with CSOM, not using XML?

I've seen many examples using XML, but none with just setting properties for the field programmatically?

fields.Add(new **FieldCreationInformation** {
    InternalName = "Test",
   etc..
});
Robin
  • 740
  • 3
  • 12
  • 30

2 Answers2

8

That's doable, in the following example is introduced a FieldCreationInformation class:

[XmlRoot("Field")]
public class FieldCreationInformation
{
    [XmlAttribute("ID")]
    public Guid Id { get; set; }

    [XmlAttribute()]
    public string DisplayName { get; set; }

    [XmlAttribute("Name")]
    public string InternalName { get; set; }

    [XmlIgnore()]
    public bool AddToDefaultView { get; set; }


    //public IEnumerable<KeyValuePair<string, string>> AdditionalAttributes { get; set; }

    [XmlAttribute("Type")]
    public FieldType FieldType { get; set; }

    [XmlAttribute()]
    public string Group { get; set; }

    [XmlAttribute()]
    public bool Required { get; set; }


    public string ToXml()
    {
        var serializer = new XmlSerializer(GetType());
        var settings = new XmlWriterSettings();
        settings.Indent = true;
        settings.OmitXmlDeclaration = true;
        var emptyNamepsaces = new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty });

        using (var stream = new StringWriter())
        using (var writer = XmlWriter.Create(stream, settings))
        {
            serializer.Serialize(writer, this, emptyNamepsaces);
            return stream.ToString();
        }
    }



    public FieldCreationInformation()
    {
        Id = Guid.NewGuid();
    }

}

and then extension method for creating a new field:

public static class FieldCollectionExtensions
{
    public static Field Add(this FieldCollection fields, FieldCreationInformation info)
    {
        var fieldSchema = info.ToXml();
        return fields.AddFieldAsXml(fieldSchema, info.AddToDefaultView, AddFieldOptions.AddFieldToDefaultView);
    }
}

Usage

var fieldInfo = new FieldCreationInformation();
fieldInfo.FieldType = FieldType.Geolocation;
fieldInfo.InternalName = "ContactsLocation";
fieldInfo.DisplayName = "Contacts Location";
ctx.Site.RootWeb.Fields.Add(fieldInfo);
ctx.ExecuteQuery();
Vadim Gremyachev
  • 57,952
  • 20
  • 129
  • 193
  • 1
    Would deserve a lot more than 3 votes! Just one note: add `AddFieldOptions.AddFieldInternalNameHint` in the `fields.AddFieldAsXml` call: `return fields.AddFieldAsXml(fieldSchema, info.AddToDefaultView, AddFieldOptions.AddFieldToDefaultView | AddFieldOptions.AddFieldInternalNameHint);` – Evariste Feb 28 '19 at 20:34
0

When I add fields with CSOM/JSOM I use the method on the FieldCollection AddFieldAsXml. This requires you to build a string of xml with all of the properties for the desired field, but it works. I included an excerpt of the related cpde below:

Microsoft.SharePoint.Client.Web web = _context.Web;
FieldCollection fields = web.Fields;
_context.Load(fields);
_context.ExecuteQuery();

Field field = fields.FirstOrDefault(f => f.StaticName == _staticName);

if (field == null)
{
    Field createdField = fields.AddFieldAsXml(xml, false, AddFieldOptions.AddToNoContentType);
    _context.Load(createdField);
    _context.ExecuteQuery();

}

Similar code is used if you would like to add a field directly to an existing list.

Alex
  • 325
  • 1
  • 7
  • Yes, I've used that. The question tho was if it was possible without XML (AddFieldAsXml). – Robin Jan 11 '16 at 14:48
  • I apologize - misread your question. To my knowledge there isn't a good way to do it. the FieldCollection has a method for `Add` which takes a Field object, but the [constructor](https://msdn.microsoft.com/EN-US/library/microsoft.sharepoint.client.field.field.aspx) for Field does not provide a happy way to instantiate one (requires Context and ObjectPath) Is there a reason why you need to add a Field in that manner? – Alex Jan 11 '16 at 15:33
  • No, just wanted to get away from XML, thats all :) – Robin Jan 12 '16 at 07:19