/// <summary> /// Check if all tokens where replaced. If the field is a taxonomy field then we will check for the values of the referenced termstore and termset. /// </summary> /// <param name="fieldXml">The xml to parse</param> /// <param name="parser"></param> /// <param name="context"></param> /// <returns></returns> protected static bool IsFieldXmlValid(string fieldXml, TokenParser parser, ClientRuntimeContext context) { var isValid = true; var leftOverTokens = parser.GetLeftOverTokens(fieldXml); if (!leftOverTokens.Any()) { var fieldElement = XElement.Parse(fieldXml); if (fieldElement.Attribute("Type").Value == "TaxonomyFieldType") { var termStoreIdElement = fieldElement.XPathSelectElement("//ArrayOfProperty/Property[Name='SspId']/Value"); if (termStoreIdElement != null) { var termStoreId = Guid.Parse(termStoreIdElement.Value); TaxonomySession taxSession = TaxonomySession.GetTaxonomySession(context); try { taxSession.EnsureProperty(t => t.TermStores); var store = taxSession.TermStores.GetById(termStoreId); context.Load(store); context.ExecuteQueryRetry(); if (store.ServerObjectIsNull.HasValue && !store.ServerObjectIsNull.Value) { var termSetIdElement = fieldElement.XPathSelectElement("//ArrayOfProperty/Property[Name='TermSetId']/Value"); if (termSetIdElement != null) { var termSetId = Guid.Parse(termSetIdElement.Value); try { var termSet = store.GetTermSet(termSetId); context.Load(termSet); context.ExecuteQueryRetry(); isValid = termSet.ServerObjectIsNull.HasValue && !termSet.ServerObjectIsNull.Value; } catch (Exception) { isValid = false; } } } } catch (Exception) { isValid = false; } } else { isValid = false; } } } else { //Some tokens where not replaced isValid = false; } return(isValid); }
private void CreateField(Web web, XElement templateFieldElement, TokenParser parser, string originalFieldXml) { var listIdentifier = templateFieldElement.Attribute("List") != null ? templateFieldElement.Attribute("List").Value : null; if (listIdentifier != null) { // Temporary remove list attribute from list templateFieldElement.Attribute("List").Remove(); } var fieldXml = parser.ParseString(templateFieldElement.ToString(), "~sitecollection", "~site"); if (IsFieldXmlValid(fieldXml, parser, web.Context)) { var field = web.Fields.AddFieldAsXml(fieldXml, false, AddFieldOptions.AddFieldInternalNameHint); web.Context.Load(field, f => f.TypeAsString, f => f.DefaultValue, f => f.InternalName, f => f.Title); web.Context.ExecuteQueryRetry(); // Add newly created field to token set, this allows to create a field + use it in a formula in the same provisioning template parser.AddToken(new FieldTitleToken(web, field.InternalName, field.Title)); var 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()) { field.TitleResource.SetUserResourceValue(nameAttributeValue, parser); isDirty = true; } var descriptionAttributeValue = originalFieldElement.Attribute("Description") != null ? originalFieldElement.Attribute("Description").Value : ""; if (descriptionAttributeValue.ContainsResourceToken()) { field.DescriptionResource.SetUserResourceValue(descriptionAttributeValue, parser); isDirty = true; } } #endif if (isDirty) { field.Update(); web.Context.ExecuteQueryRetry(); } if ((field.TypeAsString == "TaxonomyFieldType" || field.TypeAsString == "TaxonomyFieldTypeMulti") && !string.IsNullOrEmpty(field.DefaultValue)) { var taxField = web.Context.CastTo <TaxonomyField>(field); ValidateTaxonomyFieldDefaultValue(taxField); } } else { // The field Xml was found invalid var tokenString = parser.GetLeftOverTokens(fieldXml).Aggregate(string.Empty, (acc, i) => acc + " " + i); // scope.LogError("The field was found invalid: {0}", tokenString); Debug.WriteLine("The field was found invalid: {0}", tokenString); throw new Exception(string.Format("The field was found invalid: {0}", tokenString)); } }
private void UpdateField(Web web, string fieldId, XElement templateFieldElement, TokenParser parser, string originalFieldXml) { var existingField = web.Fields.GetById(Guid.Parse(fieldId)); web.Context.Load(existingField, f => f.SchemaXml); web.Context.ExecuteQueryRetry(); var existingFieldElement = XElement.Parse(existingField.SchemaXml); var 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? { if (IsFieldXmlValid(parser.ParseString(originalFieldXml), parser, web.Context)) { var listIdentifier = templateFieldElement.Attribute("List") != null ? templateFieldElement.Attribute("List").Value : null; if (listIdentifier != null) { // Temporary remove list attribute from list templateFieldElement.Attribute("List").Remove(); } 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 (existingFieldElement.Attribute("Version") != null) { existingFieldElement.Attributes("Version").Remove(); } existingField.SchemaXml = parser.ParseString(existingFieldElement.ToString(), "~sitecollection", "~site"); existingField.UpdateAndPushChanges(true); web.Context.Load(existingField, f => f.TypeAsString, f => f.DefaultValue); web.Context.ExecuteQueryRetry(); var 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") && !string.IsNullOrEmpty(existingField.DefaultValue)) { var taxField = web.Context.CastTo <TaxonomyField>(existingField); ValidateTaxonomyFieldDefaultValue(taxField); } } 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); Debug.Fail("The field was found invalid: {0}", tokenString); throw new Exception(string.Format("The field was found invalid: {0}", tokenString)); } } else { var fieldName = existingFieldElement.Attribute("Name") != null ? existingFieldElement.Attribute("Name").Value : existingFieldElement.Attribute("StaticName").Value; //WriteWarning(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); Debug.WriteLine("Adding field {0} {1} exists but is of different type and skipping the field", fieldName, fieldId); } } }