public static void SetFileProperties(this File file, IDictionary<string, string> properties, bool checkoutIfRequired = true) { if (file == null) { throw new ArgumentNullException("file"); } if (properties == null) { throw new ArgumentNullException("properties"); } var changedProperties = new Dictionary<string, string>(); var changedPropertiesString = new StringBuilder(); var context = file.Context; if (properties != null && properties.Count > 0) { // Get a reference to the target list, if any // and load file item properties var parentList = file.ListItemAllFields.ParentList; context.Load(parentList, l => l.ForceCheckout); context.Load(file.ListItemAllFields); context.Load(file.ListItemAllFields.FieldValuesAsText); try { context.ExecuteQueryRetry(); } catch (ServerException ex) { // If this throws ServerException (does not belong to list), then shouldn't be trying to set properties) if (ex.Message != "The object specified does not belong to a list.") { throw; } } // Loop through and detect changes first, then, check out if required and apply foreach (var kvp in properties) { var propertyName = kvp.Key; var propertyValue = kvp.Value; var fieldValues = file.ListItemAllFields.FieldValues; var currentValue = string.Empty; if (file.ListItemAllFields.FieldValues.ContainsKey(propertyName)) { currentValue = file.ListItemAllFields.FieldValuesAsText[propertyName]; } //LoggingUtility.Internal.TraceVerbose("*** Comparing property '{0}' to current '{1}', new '{2}'", propertyName, currentValue, propertyValue); switch (propertyName.ToUpperInvariant()) { case "CONTENTTYPE": { if (!currentValue.Equals(propertyValue, StringComparison.InvariantCultureIgnoreCase) && parentList != null) { ContentType targetCT = parentList.GetContentTypeByName(propertyValue); context.ExecuteQueryRetry(); if (targetCT != null) { changedProperties["ContentTypeId"] = targetCT.StringId; changedPropertiesString.AppendFormat("{0}='{1}'; ", propertyName, propertyValue); } else { Log.Error(Constants.LOGGING_SOURCE, "Content Type {0} does not exist in target list!", propertyValue); } } break; } case "CONTENTTYPEID": { if (!currentValue.Equals(propertyValue, StringComparison.InvariantCultureIgnoreCase)) { changedProperties[propertyName] = propertyValue; changedPropertiesString.AppendFormat("{0}='{1}'; ", propertyName, propertyValue); } /* var currentBase = currentValue.Substring(0, currentValue.Length - 34); var sameValue = (currentBase == propertyValue); if (!sameValue && propertyValue.Length >= 32 + 6 && propertyValue.Substring(propertyValue.Length - 34, 2) == "00") { var propertyBase = propertyValue.Substring(0, propertyValue.Length - 34); sameValue = (currentBase == propertyBase); } if (!sameValue) { changedProperties[propertyName] = propertyValue; changedPropertiesString.AppendFormat("{0}='{1}'; ", propertyName, propertyValue); } */ break; } case "PUBLISHINGASSOCIATEDCONTENTTYPE": { var testValue = ";#" + currentValue.Replace(", ", ";#") + ";#"; if (testValue != propertyValue) { changedProperties[propertyName] = propertyValue; changedPropertiesString.AppendFormat("{0}='{1}'; ", propertyName, propertyValue); } break; } default: { if (currentValue != propertyValue) { //Console.WriteLine("Setting property '{0}' to '{1}'", propertyName, propertyValue); changedProperties[propertyName] = propertyValue; changedPropertiesString.AppendFormat("{0}='{1}'; ", propertyName, propertyValue); } break; } } } if (changedProperties.Count > 0) { Log.Info(Constants.LOGGING_SOURCE, CoreResources.FileFolderExtensions_UpdateFile0Properties1, file.Name, changedPropertiesString); var checkOutRequired = false; if (parentList != null) { checkOutRequired = parentList.ForceCheckout; } if (checkoutIfRequired && checkOutRequired && file.CheckOutType == CheckOutType.None) { Log.Debug(Constants.LOGGING_SOURCE, "Checking out file '{0}'", file.Name); file.CheckOut(); context.ExecuteQueryRetry(); } Log.Debug(Constants.LOGGING_SOURCE, "Set properties: {0}", file.Name); foreach (var kvp in changedProperties) { var propertyName = kvp.Key; var propertyValue = kvp.Value; Log.Debug(Constants.LOGGING_SOURCE, " {0}={1}", propertyName, propertyValue); file.ListItemAllFields[propertyName] = propertyValue; } file.ListItemAllFields.Update(); context.ExecuteQueryRetry(); } } }
/// <summary> /// Sets file properties using a dictionary. /// </summary> /// <param name="file">Target file object.</param> /// <param name="properties">Dictionary of properties to set.</param> /// <param name="checkoutIfRequired">Check out the file if necessary to set properties.</param> public static void SetFileProperties(this Microsoft.SharePoint.Client.File file, IDictionary<string, string> properties, bool checkoutIfRequired = true) { if (file == null) { throw new ArgumentNullException("file"); } if (properties == null) { throw new ArgumentNullException("properties"); } var changedProperties = new Dictionary<string, string>(); var changedPropertiesString = new StringBuilder(); var context = file.Context; if (properties != null && properties.Count > 0) { // If this throws ServerException (does not belong to list), then shouldn't be trying to set properties) context.Load(file.ListItemAllFields); context.Load(file.ListItemAllFields.FieldValuesAsText); context.ExecuteQueryRetry(); // Loop through and detect changes first, then, check out if required and apply foreach (var kvp in properties) { var propertyName = kvp.Key; var propertyValue = kvp.Value; var fieldValues = file.ListItemAllFields.FieldValues; var currentValue = string.Empty; if (file.ListItemAllFields.FieldValues.ContainsKey(propertyName)) { currentValue = file.ListItemAllFields.FieldValuesAsText[propertyName]; } //LoggingUtility.Internal.TraceVerbose("*** Comparing property '{0}' to current '{1}', new '{2}'", propertyName, currentValue, propertyValue); switch (propertyName.ToUpperInvariant()) { case "CONTENTTYPE": { // TODO: Add support for named ContentType (need to lookup ID and check if it needs changing) throw new NotSupportedException("ContentType property not yet supported; use ContentTypeId instead."); //break; } case "CONTENTTYPEID": { var currentBase = currentValue.Substring(0, currentValue.Length - 34); var sameValue = (currentBase == propertyValue); if (!sameValue && propertyValue.Length >= 32 + 6 && propertyValue.Substring(propertyValue.Length - 34, 2) == "00") { var propertyBase = propertyValue.Substring(0, propertyValue.Length - 34); sameValue = (currentBase == propertyBase); } if (!sameValue) { changedProperties[propertyName] = propertyValue; changedPropertiesString.AppendFormat("{0}='{1}'; ", propertyName, propertyValue); } break; } case "PUBLISHINGASSOCIATEDCONTENTTYPE": { var testValue = ";#" + currentValue.Replace(", ", ";#") + ";#"; if (testValue != propertyValue) { changedProperties[propertyName] = propertyValue; changedPropertiesString.AppendFormat("{0}='{1}'; ", propertyName, propertyValue); } break; } default: { if (currentValue != propertyValue) { //Console.WriteLine("Setting property '{0}' to '{1}'", propertyName, propertyValue); changedProperties[propertyName] = propertyValue; changedPropertiesString.AppendFormat("{0}='{1}'; ", propertyName, propertyValue); } break; } } } if (changedProperties.Count > 0) { Log.Info(Constants.LOGGING_SOURCE, CoreResources.FileFolderExtensions_UpdateFile0Properties1, file.Name, changedPropertiesString); var checkOutRequired = false; var parentList = file.ListItemAllFields.ParentList; context.Load(parentList, l => l.ForceCheckout); try { context.ExecuteQueryRetry(); checkOutRequired = parentList.ForceCheckout; } catch (ServerException ex) { if (ex.Message != "The object specified does not belong to a list.") { throw; } } if (checkOutRequired && file.CheckOutType == CheckOutType.None) { Log.Debug(Constants.LOGGING_SOURCE, "Checking out file '{0}'", file.Name); file.CheckOut(); context.ExecuteQueryRetry(); } Log.Debug(Constants.LOGGING_SOURCE, "Set properties: {0}", file.Name); foreach (var kvp in changedProperties) { var propertyName = kvp.Key; var propertyValue = kvp.Value; Log.Debug(Constants.LOGGING_SOURCE, " {0}={1}", propertyName, propertyValue); file.ListItemAllFields[propertyName] = propertyValue; } file.ListItemAllFields.Update(); context.ExecuteQueryRetry(); } } }