/// <summary> /// Copy a property from another JObject, to a property path on this one, overwriting an existing property or creating a new one /// </summary> /// <param name="toObject">Object receiving property update</param> /// <param name="toPath">Path of property to update/add</param> /// <param name="fromObject">Object supplying property</param> /// <param name="fromPath">Path of property to supply</param> public static void CopyPropertyFrom(this JObject toObject, string toPath, JObject fromObject, string fromPath) { JProperty toProperty = toObject.PropertyByPath(toPath); JProperty fromProperty = fromObject.PropertyByPath(fromPath); if (fromProperty != null) { if (toProperty == null) { toObject.AddAtPath(toPath, fromProperty); } else { toProperty.Value = fromProperty.Value; } } }
public IActionResult Rename(string dataType, string path, bool pathInSummary, string newPath, bool newPathInSummary, bool?isDelete) { Type contentType = ContentTypeHierarchy.GetContentType(dataType); if (contentType == null) { return(Content("No such type, remember to add 'Content' where necessary")); } int propMissing = 0; int updated = 0; // create a new ContentRepository so we can bypass any block to writing caused by existing data problems // on the global data api var repo = new ContentRepository(new CoreDataSourceFactory(LyniconSystem.Instance)); repo.BypassChangeProblems = true; foreach (ContentItem ci in repo.Get <ContentItem>(contentType, new Type[] { contentType }, iq => iq)) { JObject jObjFrom; if (pathInSummary) { jObjFrom = JObject.Parse(ci.Summary ?? "{}"); } else { jObjFrom = JObject.Parse(ci.Content ?? "{}"); } JObject jObjTo = null; bool doDelete = isDelete ?? false; bool wasComputed = false; if (!doDelete) { if (newPathInSummary) { jObjTo = JObject.Parse(ci.Summary ?? "{}"); } else { jObjTo = JObject.Parse(ci.Content ?? "{}"); } jObjTo.CopyPropertyFrom(newPath, jObjFrom, path); JProperty prop = jObjTo.PropertyByPath(path); // try to deserialize in case its a computed property if (!pathInSummary && newPathInSummary && prop == null) { object content = jObjFrom.ToObject(contentType); object val = ReflectionX.GetPropertyValueByPath(content, path); if (val != null) { string pName = newPath.Contains(".") ? newPath.LastAfter(".") : newPath; jObjTo.AddAtPath(newPath, new JProperty(pName, val)); wasComputed = true; } } if (pathInSummary == newPathInSummary) { if (prop != null) { prop.Remove(); updated++; } else { propMissing++; } } } if (pathInSummary != newPathInSummary || doDelete) // we need to update both summary and content { // remove the old path JProperty prop = jObjFrom.PropertyByPath(path); if (prop != null) { prop.Remove(); updated++; if (pathInSummary) { ci.Summary = jObjFrom.ToString(); } else { ci.Content = jObjFrom.ToString(); } } else if (wasComputed) { updated++; } else { propMissing++; } } if (!doDelete) { if (newPathInSummary) { ci.Summary = jObjTo.ToString(); } else { ci.Content = jObjTo.ToString(); } } repo.Set(new List <object> { ci }, new Dictionary <string, object>()); } return(Content(string.Format("{0} updated {1} had property missing", updated, propMissing))); }