another technical blog...technically

Tuesday, September 13, 2016

Field validation formulas... and folder creation via CSOM

Lately i'm working on sandbox solutions, it seems customer prefers OOB solutions.
Indeed i created (inspired from some blog posts written by people who knows things for real) those formulas for phone number and email:
  • Phone (+39 080-1234567):
  • =AND(
    (FIND("+";[Phone];1)=1);
    (ISNUMBER(VALUE(MID([Phone];2;FIND(" ";[Phone];1)-2))));
    (ISNUMBER(VALUE(MID([Phone];FIND(" ";[Phone];1);FIND("-";[Phone];1)-FIND(" ";[Phone];1)))));
    (ISNUMBER(VALUE(MID([Phone];FIND("-";[Phone];1)+1;LEN([Phone]))))))
  • Email formula:
  • =AND(NOT(ISERROR(FIND("@";[Email])));NOT(ISERROR(FIND(".";[Email])));ISERROR(FIND(" ";[Email]));NOT(ISERROR(FIND(".";[Email];FIND("@";[Email];1)))))

SharePoint validation does not provide regular expression support (doh!) so you need to have fun with excel formula. The pro is that you can unit test formulas with excel, the con is that you have less power than regex.
But this post deals with another problem: when you set validation on a document library and you try to create a folder via CSOM on it (maybe also with SSOM but i haven't tested it) you have a very fun error: "List data validation failed."
So what to do? The right code is the following one, indeed forcing the ContentTypeId during folder generation
// Get content type instance ID
ContentTypeCollection listContentTypes = list.ContentTypes;
context.Load(listContentTypes, types => types.Include
     (type => type.Id, type => type.Name,
     type => type.Parent));
var result = context.LoadQuery(listContentTypes.Where
  (c => c.Name == "Folder" || c.Name == "Cartella"));
context.ExecuteQuery();
ContentType folderContentType = result.FirstOrDefault();

// Get author ID
FieldUserValue userValue = new FieldUserValue();
userValue.LookupId = owner.Id;

// Creating folder
ListItemCreationInformation newItemInfo = new ListItemCreationInformation();
newItemInfo.UnderlyingObjectType = FileSystemObjectType.Folder;
newItemInfo.LeafName = folderName;
ListItem newListItem = list.AddItem(newItemInfo);

newListItem["ContentTypeId"] = folderContentType.Id.ToString();
newListItem["Author"] = userValue;
newListItem["Title"] = folderName;
newListItem.Update();
context.Load(list);
context.ExecuteQuery();
Are you saying "Eureka"? Mmm now try to break role inheritance on this folder or try to make whatever update on the ListItem associated to this folder and... BAM... "List data validation failed" once again.
newListItem.BreakRoleInheritance(false, true);
RoleDefinitionBindingCollection role = new RoleDefinitionBindingCollection(context);
role.Add(context.Web.RoleDefinitions.GetByType(RoleType.Reader));
newListItem.RoleAssignments.Add(owner, role);
newListItem.Update();
context.ExecuteQuery();
The funny part is that the role inheritance was broken and the old roles cleared so, sadly, i've solved this managing the validation exception when i work on folder... not so elegant but it is what it is.
Have fun.
Share:

Me, myself and I

My Photo
I'm just another IT guy sharing his knowledge with all of you out there.
Wanna know more?