Клиентская объектная модель — обновление метаданных библиотеки документов — поле поиска без обязательного значения
Вопрос
Я пытаюсь обновить метаданные документов в библиотеке документов (или списке), используя клиентскую объектную модель.Я сократил количество сообщений об ошибках, которые получал, и теперь столкнулся с новой проблемой:
Ряд полей метаданных в типе контента для этих элементов являются полями поиска, и некоторые из этих поисков допускают множественный выбор.Большинство из них не требуются, однако, когда я тестирую приложение, я получаю ошибки от SharePoint, сообщающие мне, что «требуется свойство метаданных [номер модели продаж]», что не соответствует действительности.
Как поместить пустое значение в поле поиска с множественным выбором или иным образом избежать этой ошибки?
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()
* ОБНОВЛЯТЬ *
Итак, я внес некоторые изменения, в частности, добавив в список поиска значение, которое отсутствовало в поиске ранее, и получил ту же ошибку.Итак, теперь полю присвоено допустимое значение, но оно все еще выдает ошибку «поле обязательно».Не весело.У меня такое впечатление, что, возможно, что-то не так с самим полем...Есть ли у кого-нибудь мысли?Я, наверное, еще немного поковыряюсь, а потом вообще удалю и заново создам поле.
* ОБНОВЛЕНИЕ 2 *
Дальнейшая отладка привела меня к следующему открытию:После вызовов Update() и ExecuteQuery() элемент возвращается к исходным метаданным, поэтому, когда я пытаюсь его проверить, он применяет недопустимые значения, что приводит к появлению сообщения об ошибке.Теперь я действительно в замешательстве.Может быть, мне нужно выполнить обновление и возврат во время одного и того же ExecuteQuery() вместо того, чтобы сначала пытаться выполнить обновление, а затем зарегистрироваться позже?
Спасибо,
- Мэтт
Решение
ОК, думаю, я решил свою проблему.На самом деле у меня здесь было две вещи:
1) Соединение WCF передает обновления метаданных при регистрации в другое веб-приложение (ASP.NET).Область, о которой я постоянно получал сообщения ЯВЛЯЕТСЯ требуется на этом сайте.Не ожидал, что кто-то здесь это поймет.Я сделал это поле обязательным в SharePoint и установил несколько фиктивных значений по умолчанию, чтобы можно было протестировать обновление моего приложения.
2) После того, как я исправил эту проблему, я заметил, что все наконец-то начало регистрироваться, но ни одно (ну, ОДНО) поле не обновлялось.Я поигрался с этим еще немного и обнаружил, что если я сделаю Update()
call каждый раз, когда я просматриваю поля, они действительно обновляются и в SharePoint.Похоже на вызов Update()
раньше обновлял только последнее устанавливаемое поле метаданных или что-то в этом роде.
Новый код:
private void DoMetadataUpdateEx(DataRow row, ListItem item)
{
ListItem updateItem = item;
if (item.File != null || _sharePoint.CurrentList.ForceCheckout)
{
updateItem = item.File.ListItemAllFields;
_sharePoint.Context.Load(updateItem);
_sharePoint.Context.ExecuteQuery();
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(',', ';');
updateItem[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)
{
updateItem[f.InternalName] = newVals.ToArray<FieldLookupValue>();
}
else
{
newVals.Add(new FieldLookupValue());
updateItem[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;
updateItem[f.InternalName] = flv;
}
}
break;
case FieldType.Computed:
throw new NotImplementedException("Computed columns are not yet implemented");
case FieldType.Integer:
updateItem[f.InternalName] = Int32.Parse(row[mm.ExcelColumn].ToString());
break;
default:
updateItem[f.InternalName] = row[mm.ExcelColumn].ToString();
break;
}
}
updateItem.Update();
}
//updateItem.Update();
if (item.File != null || _sharePoint.CurrentList.ForceCheckout)
{
item.File.CheckIn("Modified by SP2010 Excel List Updater", CheckinType.MajorCheckIn);
}
else
{
_sharePoint.Context.ExecuteQuery();
}
}// end DoMetadataUpdateEx()