I am attempting to update metadata for documents in a document library (or List) using the client object model. I have whittled down a number of the error messages I was getting and now I am hitting a new problem:
A number of metadata fields in the content type for these items are lookup fields, and a number of those lookups are multi-select. Most of them are not required, however when I test the application I get errors from SharePoint telling me that "Metadata property [Sales Model Number] is required" which is just not true.
How do I put a blank value into a multi-select lookup field or otherwise avoid this error?
private void DoMetadataUpdateEx(DataRow row, ListItem item) { if (item.File != null || _sharePoint.CurrentList.ForceCheckout) { try { item.File.CheckOut(); _sharePoint.Context.ExecuteQuery(); } catch (Exception) { } } foreach (MetaMap mm in _metaMapping) { if (mm.ForceUse) { //Field f = _sharePoint.CurrentList.Fields.GetByInternalNameOrTitle(mm.SharePointColumn); Field f = _sharePoint.GetCurrentFieldByTitle(mm.SharePointColumn); switch (f.FieldTypeKind) { case FieldType.MultiChoice: string[] mcvals = row[mm.ExcelColumn].ToString().Split(',', ';'); item[f.InternalName] = mcvals; break; case FieldType.Lookup: if((f as FieldLookup).AllowMultipleValues) { string[] mlvals = row[mm.ExcelColumn].ToString().Split(',', ';'); List<FieldLookupValue> newVals = new List<FieldLookupValue>(); FieldLookupValue[] oitemsalesmodelnum = (FieldLookupValue[])item[f.InternalName]; foreach (string ev in mlvals) { ListItem li = _sharePoint.GetLookupValue(f as FieldLookup, ev); if (li == null) { continue; } FieldLookupValue flv = new FieldLookupValue(); flv.LookupId = li.Id; newVals.Add(flv); } if (newVals.Count > 0) { item[f.InternalName] = newVals.ToArray<FieldLookupValue>(); } else { newVals.Add(new FieldLookupValue()); item[f.InternalName] = newVals.ToArray<FieldLookupValue>(); } } else { ListItem li = _sharePoint.GetLookupValue(f as FieldLookup, row[mm.ExcelColumn].ToString()); if (li != null) { FieldLookupValue flv = new FieldLookupValue(); flv.LookupId = li.Id; item[f.InternalName] = flv; } } break; case FieldType.Computed: throw new NotImplementedException("Computed columns are not yet implemented"); case FieldType.Integer: item[f.InternalName] = Int32.Parse(row[mm.ExcelColumn].ToString()); break; default: item[f.InternalName] = row[mm.ExcelColumn].ToString(); break; } } } item.Update(); //_sharePoint.Context.Load(item); item.Context.ExecuteQuery(); if (item.File != null || _sharePoint.CurrentList.ForceCheckout) { try { item.File.CheckOut(); _sharePoint.Context.ExecuteQuery(); } catch (Exception) // ignore checkout exception { } item.File.CheckIn("Modified by SP2010 Excel List Updater", CheckinType.MajorCheckIn); _sharePoint.Context.ExecuteQuery(); } }// end DoMetadataUpdateEx() * UPDATE *
SO, I made some changes, notably by adding the value that was missing from the lookup before to the lookup list, and got the same error. So, the field was being assigned a legitimate value now, and it still is throwing this "field is required" error. Not fun. I am of the impression perhaps there's something wrong with the field itself... Does anybody out there have thoughts? I'll probably poke around a little more then delete and recreate the field altogether.
* UPDATE 2 *
Doing some more debugging has led me to the following discovery: After the Update() and ExecuteQuery() calls, the item reverts back to its original metadata, so when I try to check it in it's applying invalid values, thus the error message. Now I'm really confused. Maybe I need to do the update and the checkin during the same ExecuteQuery() instead of trying to do the update first and then check in later?
Thanks,
- Matt
_sharePointobject? It isn'tClientContext?ClientContextaround as a parameter when it's needed, but all inside a using block... this is an interesting style.