private void UpdateField(Web web, string fieldId, XElement templateFieldElement, PnPMonitoredScope scope, TokenParser parser, string originalFieldXml) { var existingField = web.Fields.GetById(Guid.Parse(fieldId)); web.Context.Load(existingField, f => f.SchemaXml); web.Context.ExecuteQueryRetry(); XElement existingFieldElement = XElement.Parse(existingField.SchemaXml); XNodeEqualityComparer equalityComparer = new XNodeEqualityComparer(); if (equalityComparer.GetHashCode(existingFieldElement) != equalityComparer.GetHashCode(templateFieldElement)) // Is field different in template? { if (existingFieldElement.Attribute("Type").Value == templateFieldElement.Attribute("Type").Value) // Is existing field of the same type? { var listIdentifier = templateFieldElement.Attribute("List") != null?templateFieldElement.Attribute("List").Value : null; if (listIdentifier != null) { // Temporary remove list attribute from list templateFieldElement.Attribute("List").Remove(); } if (IsFieldXmlValid(parser.ParseXmlString(originalFieldXml), parser, web.Context)) { foreach (var attribute in templateFieldElement.Attributes()) { if (existingFieldElement.Attribute(attribute.Name) != null) { existingFieldElement.Attribute(attribute.Name).Value = attribute.Value; } else { existingFieldElement.Add(attribute); } } foreach (var element in templateFieldElement.Elements()) { if (existingFieldElement.Element(element.Name) != null) { existingFieldElement.Element(element.Name).Remove(); } existingFieldElement.Add(element); } if (string.Equals(templateFieldElement.Attribute("Type").Value, "Calculated", StringComparison.OrdinalIgnoreCase)) { var fieldRefsElement = existingFieldElement.Descendants("FieldRefs").FirstOrDefault(); if (fieldRefsElement != null) { fieldRefsElement.Remove(); } } if (existingFieldElement.Attribute("Version") != null) { existingFieldElement.Attributes("Version").Remove(); } existingField.SchemaXml = parser.ParseXmlString(existingFieldElement.ToString(), "~sitecollection", "~site"); existingField.UpdateAndPushChanges(true); web.Context.Load(existingField, f => f.TypeAsString, f => f.DefaultValue); try { web.Context.ExecuteQueryRetry(); } catch (ServerException se) { if (se.ServerErrorTypeName == "Microsoft.SharePoint.Client.ClientServiceTimeoutException") { string fieldName = existingFieldElement.Attribute("Name") != null?existingFieldElement.Attribute("Name").Value : existingFieldElement.Attribute("StaticName").Value; WriteMessage(string.Format(CoreResources.Provisioning_ObjectHandlers_Fields_Updating_field__0__timeout, fieldName), ProvisioningMessageType.Warning); scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_Fields_Updating_field__0__timeout, fieldName); web.Context.Load(existingField, f => f.TypeAsString, f => f.DefaultValue); web.Context.ExecuteQueryRetry(); } else { throw; } } bool isDirty = false; #if !SP2013 if (originalFieldXml.ContainsResourceToken()) { var originalFieldElement = XElement.Parse(originalFieldXml); var nameAttributeValue = originalFieldElement.Attribute("DisplayName") != null?originalFieldElement.Attribute("DisplayName").Value : ""; if (nameAttributeValue.ContainsResourceToken()) { existingField.TitleResource.SetUserResourceValue(nameAttributeValue, parser); isDirty = true; } var descriptionAttributeValue = originalFieldElement.Attribute("Description") != null?originalFieldElement.Attribute("Description").Value : ""; if (descriptionAttributeValue.ContainsResourceToken()) { existingField.DescriptionResource.SetUserResourceValue(descriptionAttributeValue, parser); isDirty = true; } } #endif if (isDirty) { existingField.Update(); web.Context.ExecuteQueryRetry(); } if ((existingField.TypeAsString == "TaxonomyFieldType" || existingField.TypeAsString == "TaxonomyFieldTypeMulti")) { var taxField = web.Context.CastTo <TaxonomyField>(existingField); if (!string.IsNullOrEmpty(existingField.DefaultValue)) { ValidateTaxonomyFieldDefaultValue(taxField); } SetTaxonomyFieldOpenValue(taxField, originalFieldXml); } } else { // The field Xml was found invalid var tokenString = parser.GetLeftOverTokens(originalFieldXml).Aggregate(String.Empty, (acc, i) => acc + " " + i); scope.LogError("The field was found invalid: {0}", tokenString); throw new Exception($"The field was found invalid: {tokenString}"); } } else { var fieldName = existingFieldElement.Attribute("Name") != null?existingFieldElement.Attribute("Name").Value : existingFieldElement.Attribute("StaticName").Value; WriteMessage(string.Format(CoreResources.Provisioning_ObjectHandlers_Fields_Field__0____1___exists_but_is_of_different_type__Skipping_field_, fieldName, fieldId), ProvisioningMessageType.Warning); scope.LogWarning(CoreResources.Provisioning_ObjectHandlers_Fields_Field__0____1___exists_but_is_of_different_type__Skipping_field_, fieldName, fieldId); } } }