public static void SetValueFromPath(Type entityType, PathComponent[] pathComponents, object entity, object value, JsonPatchOperationType operationType) { try { PathComponent[] parent = pathComponents.Take(pathComponents.Length - 1).ToArray(); string parentPath = PathComponent.GetFullPath(parent); object previous = GetValueFromPath(entityType, parent, entity); if (previous == null) { throw new JsonPatchException(string.Format("Value at parent path \"{0}\" is null.", parentPath)); } var target = pathComponents.Last(); TypeSwitch.On(target) .Case((PropertyPathComponent component) => { switch (operationType) { case JsonPatchOperationType.add: case JsonPatchOperationType.replace: component.PropertyInfo.SetValue(previous, ConvertValue(value, component.ComponentType)); break; case JsonPatchOperationType.remove: component.PropertyInfo.SetValue(previous, null); break; default: throw new ArgumentOutOfRangeException("operationType"); } }) .Case((CollectionIndexPathComponent component) => { var list = previous as IList; if (list == null) { throw new JsonPatchException(string.Format("Value at parent path \"{0}\" is not a valid collection.", parentPath)); } switch (operationType) { case JsonPatchOperationType.add: list.Insert(component.CollectionIndex, ConvertValue(value, component.ComponentType)); break; case JsonPatchOperationType.remove: list.RemoveAt(component.CollectionIndex); break; case JsonPatchOperationType.replace: list[component.CollectionIndex] = ConvertValue(value, component.ComponentType); break; default: throw new ArgumentOutOfRangeException("operationType"); } }); } catch (Exception e) { throw new JsonPatchException(string.Format( "Failed to set value at path \"{0}\" while performing \"{1}\" operation: {2}", PathComponent.GetFullPath(pathComponents), operationType, e.Message), e); } }
public static object GetValueFromPath(Type entityType, PathComponent[] pathComponents, object entity) { try { if (entity == null) { throw new JsonPatchException("The root object is null."); } object previous = entity; for (int i = 0; i < pathComponents.Length; i++) { string parentPath = PathComponent.GetFullPath(pathComponents.Take(i)); var pathComponent = pathComponents[i]; TypeSwitch.On(pathComponent) .Case((PropertyPathComponent component) => { if (previous == null) { throw new JsonPatchException(string.Format( "Cannot get property \"{0}\" from null object at path \"{1}\".", component.Name, parentPath)); } previous = component.PropertyInfo.GetValue(previous); }) .Case((CollectionIndexPathComponent component) => { try { var list = (IList) previous; previous = list[component.CollectionIndex]; } catch (Exception e) { throw new JsonPatchException(string.Format( "Cannot access index {0} from collection at path \"{1}\".", component.CollectionIndex, parentPath), e); } }); } return previous; } catch (Exception e) { throw new JsonPatchException(string.Format( "Failed to get value from path \"{0}\": {1}", PathComponent.GetFullPath(pathComponents), e.Message), e); } }