Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I extract the type from a field?

In SharePoint Server side code, you can write something like:

field.fieldvalueType

Which will sometimes give you the type (DateTime, or whatever). Annoyingly, sometimes, it just returns Null (for example, the ID field).

In CSOM, you don't have that field. However, there's TypeAsString which gives SharePoint types such as:

  • Computed
  • Integer
  • Note

What I'd like to do is grab this huge table from MSDN:

And Extract "Int32" when I know that I'm dealing with an "Integer" field, and extract "System.String" from SharePoint's note.

This kinda works, but it's the mother of all hacks:

var myTempItem = list.AddItem(new ListItemCreationInformation());
myTempItem.Update();
context.ExecuteQuery();

context.Load(myTempItem);
context.ExecuteQuery();

After creation, you can use:

myTempItemCreated[fieldImTryingToGetTypeOf.Title].GetType().FullName -> Gives-> System.Int32

Now, what's the proper way to do it? I'm just hoping the answer isn't a ten foot long switch case statement.

like image 749
David Avatar asked Sep 11 '15 11:09

David


2 Answers

Since there is no SPField.FieldValueType property counterparts in SharePoint CSOM API, the following extension method demonstrates how to perform it:

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.SharePoint.Client;
using Field = Microsoft.SharePoint.Client.Field;

namespace SharePoint.Client.Extensions
{
    public static class FieldExtensions
    {


        public static Type GetFieldValueType(this Field field)
        {
            var table = new Dictionary<FieldType, Type>();
            table[FieldType.Guid] = typeof(Guid);
            table[FieldType.Attachments] = typeof(bool);
            table[FieldType.Boolean] = typeof(bool);
            table[FieldType.Choice] = typeof (string);
            table[FieldType.CrossProjectLink] = typeof(bool);
            table[FieldType.DateTime] = typeof(DateTime);
            table[FieldType.Lookup] = typeof(FieldLookupValue);
            table[FieldType.ModStat] = typeof(int);
            table[FieldType.MultiChoice] = typeof(string[]);
            table[FieldType.Number] = typeof(double);
            table[FieldType.Recurrence] = typeof(bool);
            table[FieldType.Text] = typeof(string);
            table[FieldType.URL] = typeof(FieldUrlValue);
            table[FieldType.URL] = typeof(FieldUrlValue);
            table[FieldType.User] = typeof(FieldUserValue);
            table[FieldType.WorkflowStatus] = typeof(int);
            table[FieldType.ContentTypeId] = typeof(ContentTypeId);
            table[FieldType.Note] = typeof(string);
            table[FieldType.Counter] = typeof(int);
            table[FieldType.Computed] = typeof(string);
            table[FieldType.Integer] = typeof(int);
            table[FieldType.File] = typeof(string);

            if (!table.ContainsKey(field.FieldTypeKind))
                throw new NotSupportedException(string.Format("Unknown field type: {0}", field.FieldTypeKind));
            return table[field.FieldTypeKind];
        }
    }
}

Usage

var list = ctx.Web.Lists.GetByTitle(listTitle);
var fields = list.Fields;
ctx.Load(fields);
ctx.ExecuteQuery();

foreach (var field in fields)
{
    if (field.FieldTypeKind != FieldType.Invalid)
    {
         var fieldValueType = field.GetFieldValueType();
         Console.WriteLine("{0} : {1}", field.InternalName, fieldValueType);    
    }        
}
like image 61
Vadim Gremyachev Avatar answered Oct 22 '22 23:10

Vadim Gremyachev


Expanding on @Vadim's answer, here is a version that does not construct a new dictionary every time the extension method is called;

namespace SharePoint.Client.Extensions
{
    public static class FieldExtensions
    {
        private static Dictionary<FieldType, Type> _fieldTypes = new Dictionary<FieldType, Type>()
        {
            { FieldType.Guid, typeof(Guid) },
            { FieldType.Attachments, typeof(bool)},
            {FieldType.Boolean, typeof(bool)},
            {FieldType.Choice, typeof(string)},
            {FieldType.CrossProjectLink, typeof(bool)},
            {FieldType.DateTime, typeof(DateTime)},
            {FieldType.Lookup, typeof(FieldLookupValue)},
            {FieldType.ModStat, typeof(int)},
            {FieldType.MultiChoice, typeof(string[])},
            {FieldType.Number, typeof(double)},
            {FieldType.Recurrence, typeof(bool)},
            {FieldType.Text, typeof(string)},
            {FieldType.URL, typeof(FieldUrlValue)},
            {FieldType.User, typeof(FieldUserValue)},
            {FieldType.WorkflowStatus, typeof(int)},
            {FieldType.ContentTypeId, typeof(ContentTypeId)},
            {FieldType.Note, typeof(string)},
            {FieldType.Counter, typeof(int)},
            {FieldType.Computed, typeof(string)},
            {FieldType.Integer, typeof(int)},
            {FieldType.File, typeof(string)}
        };

        public static Type GetFieldValueType(this Field field)
        {
            if (!_fieldTypes.ContainsKey(field.FieldTypeKind))
                throw new NotSupportedException(string.Format("Unknown field type: {0}", field.FieldTypeKind));
            return _fieldTypes[field.FieldTypeKind];
        }
    }
}
like image 33
johnnycardy Avatar answered Oct 23 '22 00:10

johnnycardy