/// <summary> /// Updates the given SPListItem with the value passed. /// This method does not call Update or SystemUpdate. /// </summary> /// <param name="item">The SharePoint list item to update.</param> /// <param name="fieldValueInfo">The value information to be updated in the SPListItem.</param> public void WriteValueToListItem(SPListItem item, FieldValueInfo fieldValueInfo) { if (item == null) { throw new ArgumentNullException("item"); } if (fieldValueInfo == null || fieldValueInfo.FieldInfo == null) { throw new ArgumentNullException("fieldValueInfo"); } IBaseValueWriter valueWriter = this.GetWriter(fieldValueInfo); valueWriter.WriteValueToListItem(item, fieldValueInfo); }
private SPField InnerEnsureField(SPFieldCollection fieldCollection, BaseFieldInfo fieldInfo) { SPField field = null; if (fieldInfo.GetType().Name.StartsWith("MinimalFieldInfo", StringComparison.OrdinalIgnoreCase)) { // Ensuring a MinimalFieldInfo from its SchemaXML is impossible since the MinimalFieldInfo object // doesn't hold enough information to completely describe the field metadata. // Instead, we have to re-use the site column and apply it to the list. var existingSiteColumn = fieldCollection.Web.Site.RootWeb.Fields.TryGetFieldByStaticName(fieldInfo.InternalName); if (existingSiteColumn == null) { throw new NotSupportedException( string.Format( CultureInfo.InvariantCulture, "Failed to ensure MinimalFieldInfo for field {0} because the pre-requisite Site Column doesn't exist.", fieldInfo.InternalName)); } SPList parentList = null; if (!TryGetListFromFieldCollection(fieldCollection, out parentList)) { throw new NotSupportedException( string.Format( CultureInfo.InvariantCulture, "Failed to ensure MinimalFieldInfo for field {0}. A MinimalFieldInfo can only be used to ensure a Field on a List's SPFieldCollection, not to re-define an OOTB site column definition.", fieldInfo.InternalName)); } fieldCollection.Add(existingSiteColumn); field = fieldCollection[existingSiteColumn.Id]; } else { // We have a fully-functional/fully-detailed IFieldInfo which should support a conversion to SchemaXML: go ahead and try to add the field. XElement xmlSchemaForField = this.fieldSchemaHelper.SchemaForField(fieldInfo); field = this.fieldSchemaHelper.EnsureFieldFromSchema(fieldCollection, xmlSchemaForField); } // In some cases, the returned field will not match the one we meant to create or ensure. For example, // we may have defined a fieldInfo with an InternalName that clashes with an already existing field. // In such a case, EnsureFieldFromSchema will return us the conflicting/already existing field (not // the one we mean to ensure). if (field.Id == fieldInfo.Id && field.InternalName == fieldInfo.InternalName) { try { var refetchedField = fieldCollection[field.Id]; } catch (ArgumentException) { // in a sneaky edge case, we're dealing with a sub-web's fieldCollection, // and we actually ensured the column on the root web (instead of on the sub-web). fieldCollection = fieldCollection.Web.Site.RootWeb.Fields; } // Set the field visibility this.UpdateFieldVisibility(field, fieldInfo); // Set miscellaneous properties this.UpdateFieldTypeSpecificProperties(fieldCollection, field, fieldInfo); // Tiny bit of ugly reflection here: we assume that all implementations of IFieldInfo will // derive from FieldInfo<T>, which in turn lets us assume a DefaultValue property will always // be there for us to create our FieldValueInfo (which simply needs an untyped object as value). FieldValueInfo defaultValueFieldInfo = new FieldValueInfo(fieldInfo, fieldInfo.GetType().GetProperty("DefaultValue").GetValue(fieldInfo)); this.fieldValueWriter.WriteValueToFieldDefault(fieldCollection, defaultValueFieldInfo); if (!string.IsNullOrEmpty(fieldInfo.DefaultFormula)) { if (!string.IsNullOrEmpty(field.DefaultValue)) { // A default value was already specified, so setting a Formula makes no sense. throw new InvalidOperationException("Failed to ensure field " + fieldInfo.InternalName + " in its entirety because both DefaultFormula and DefaultValue properties were specified. Please only set Formula OR DefaultValue, not both. Also don't forget to clean up the partially created field " + fieldInfo.InternalName + "."); } // Setting the DefaultFormula through the SchemaXML doesn't work, // so let's force it here. field.DefaultFormula = fieldInfo.DefaultFormula; } field.Update(); } return field; }
private SPField InnerEnsureField(SPFieldCollection fieldCollection, BaseFieldInfo fieldInfo) { SPField field = null; if (fieldInfo.GetType().Name.StartsWith("MinimalFieldInfo", StringComparison.OrdinalIgnoreCase)) { // Ensuring a MinimalFieldInfo from its SchemaXML is impossible since the MinimalFieldInfo object // doesn't hold enough information to completely describe the field metadata. // Instead, we have to re-use the site column and apply it to the list. var existingSiteColumn = fieldCollection.Web.Site.RootWeb.Fields.TryGetFieldByStaticName(fieldInfo.InternalName); if (existingSiteColumn == null) { throw new NotSupportedException( string.Format( CultureInfo.InvariantCulture, "Failed to ensure MinimalFieldInfo for field {0} because the pre-requisite Site Column doesn't exist.", fieldInfo.InternalName)); } SPList parentList = null; if (!TryGetListFromFieldCollection(fieldCollection, out parentList)) { throw new NotSupportedException( string.Format( CultureInfo.InvariantCulture, "Failed to ensure MinimalFieldInfo for field {0}. A MinimalFieldInfo can only be used to ensure a Field on a List's SPFieldCollection, not to re-define an OOTB site column definition.", fieldInfo.InternalName)); } fieldCollection.Add(existingSiteColumn); field = fieldCollection[existingSiteColumn.Id]; } else { // We have a fully-functional/fully-detailed IFieldInfo which should support a conversion to SchemaXML: go ahead and try to add the field. XElement xmlSchemaForField = this.fieldSchemaHelper.SchemaForField(fieldInfo); field = this.fieldSchemaHelper.EnsureFieldFromSchema(fieldCollection, xmlSchemaForField); } // In some cases, the returned field will not match the one we meant to create or ensure. For example, // we may have defined a fieldInfo with an InternalName that clashes with an already existing field. // In such a case, EnsureFieldFromSchema will return us the conflicting/already existing field (not // the one we mean to ensure). if (field.Id == fieldInfo.Id && field.InternalName == fieldInfo.InternalName) { try { var refetchedField = fieldCollection[field.Id]; } catch (ArgumentException) { // in a sneaky edge case, we're dealing with a sub-web's fieldCollection, // and we actually ensured the column on the root web (instead of on the sub-web). fieldCollection = fieldCollection.Web.Site.RootWeb.Fields; } // Set the field visibility this.UpdateFieldVisibility(field, fieldInfo); // Set miscellaneous properties this.UpdateFieldTypeSpecificProperties(fieldCollection, field, fieldInfo); // Tiny bit of ugly reflection here: we assume that all implementations of IFieldInfo will // derive from FieldInfo<T>, which in turn lets us assume a DefaultValue property will always // be there for us to create our FieldValueInfo (which simply needs an untyped object as value). FieldValueInfo defaultValueFieldInfo = new FieldValueInfo(fieldInfo, fieldInfo.GetType().GetProperty("DefaultValue").GetValue(fieldInfo)); this.fieldValueWriter.WriteValueToFieldDefault(fieldCollection, defaultValueFieldInfo); if (!string.IsNullOrEmpty(fieldInfo.DefaultFormula)) { if (!string.IsNullOrEmpty(field.DefaultValue)) { // A default value was already specified, so setting a Formula makes no sense. throw new InvalidOperationException("Failed to ensure field " + fieldInfo.InternalName + " in its entirety because both DefaultFormula and DefaultValue properties were specified. Please only set Formula OR DefaultValue, not both. Also don't forget to clean up the partially created field " + fieldInfo.InternalName + "."); } // Setting the DefaultFormula through the SchemaXML doesn't work, // so let's force it here. field.DefaultFormula = fieldInfo.DefaultFormula; } // Set the JavaScript custom rendering file URL if (!string.IsNullOrEmpty(fieldInfo.JsLink)) { field.JSLink = fieldInfo.JsLink; } field.Update(fieldInfo.AreChangesPushedToList); } return(field); }
private IBaseValueWriter GetWriter(FieldValueInfo fieldValueInfo) { var associatedValueType = fieldValueInfo.FieldInfo.AssociatedValueType; IBaseValueWriter valueWriter = null; if (this.writers.ContainsKey(associatedValueType)) { valueWriter = this.writers[associatedValueType]; } else { throw new ArgumentException(string.Format( CultureInfo.InvariantCulture, "Failed to find a value writer for your FieldInfo's AssociatedValueType (field={0}, valueType={1})", fieldValueInfo.FieldInfo.InternalName, associatedValueType.ToString())); } return valueWriter; }
/// <summary> /// Updates the specified SPFolder with new default field value /// </summary> /// <param name="folder">The SharePoint folder for which we want to update the metadata defaults.</param> /// <param name="defaultFieldValueInfo">The default value to be applied to items created within that folder.</param> public void WriteValuesToFolderDefault(SPFolder folder, FieldValueInfo defaultFieldValueInfo) { if (folder == null) { throw new ArgumentNullException("folder"); } if (defaultFieldValueInfo == null || defaultFieldValueInfo.FieldInfo == null) { throw new ArgumentNullException("defaultFieldValueInfo"); } IBaseValueWriter valueWriter = this.GetWriter(defaultFieldValueInfo); valueWriter.WriteValueToFolderDefault(folder, defaultFieldValueInfo); }
/// <summary> /// Updates the specified SPField definition with new DefaultValue /// </summary> /// <param name="parentFieldCollection">The SharePoint field collection containing the field to update.</param> /// <param name="defaultFieldValueInfo">The default value to be applied as the SPField' new default.</param> public void WriteValueToFieldDefault(SPFieldCollection parentFieldCollection, FieldValueInfo defaultFieldValueInfo) { if (parentFieldCollection == null) { throw new ArgumentNullException("parentFieldCollection"); } if (defaultFieldValueInfo == null || defaultFieldValueInfo.FieldInfo == null) { throw new ArgumentNullException("defaultFieldValueInfo"); } IBaseValueWriter valueWriter = this.GetWriter(defaultFieldValueInfo); valueWriter.WriteValueToFieldDefault(parentFieldCollection, defaultFieldValueInfo); }