Example #1
0
        /// <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);
        }
Example #2
0
        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;
        }
Example #3
0
        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);
        }
Example #4
0
        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;
        }
Example #5
0
        /// <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);
        }
Example #6
0
        /// <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);
        }