public static WorkItem UpdateWorkItemFields(int WIId, Dictionary <string, object> Fields) { try { JsonPatchDocument patchDocument = new JsonPatchDocument(); foreach (var key in Fields.Keys) { JsonPatchOperation Jsonpatch = new JsonPatchOperation() { Operation = Operation.Replace, Path = "/fields/" + key, Value = Fields[key] }; if (!patchDocument.Contains(Jsonpatch)) { patchDocument.Add(Jsonpatch); } } if (patchDocument.Count != 0) { return(WitClient.UpdateWorkItemAsync(patchDocument, WIId).Result); } else { return(null); } } catch (Exception E) { throw (E); } }
/// <summary> /// Validates the path for the operation. /// </summary> protected static void ValidatePath(JsonPatchOperation operation) { // Path cannot be null, but it can be empty. if (operation.Path == null) { throw new VssPropertyValidationException("Path", PatchResources.PathCannotBeNull()); } // If it is not empty and does not start with /, this is an error per RFC. if (!operation.Path.StartsWith(PathSeparator) && !string.IsNullOrEmpty(operation.Path)) { throw new VssPropertyValidationException("Path", PatchResources.PathInvalidStartValue()); } // Ending in / is not valid.. if (operation.Path.EndsWith(PathSeparator)) { throw new VssPropertyValidationException("Path", PatchResources.PathInvalidEndValue()); } // Only add operations allow insert. if (operation.Operation != Operation.Add) { if (operation.Path.EndsWith(EndOfIndex)) { throw new VssPropertyValidationException("Path", PatchResources.InsertNotSupported(operation.Operation)); } } }
private WitBatchRequest GenerateWitBatchRequestFromWorkItem(WorkItem sourceWorkItem) { Dictionary <string, string> headers = new Dictionary <string, string>(); headers.Add("Content-Type", "application/json-patch+json"); JsonPatchDocument jsonPatchDocument = CreateJsonPatchDocumentFromWorkItemFields(sourceWorkItem); JsonPatchOperation insertIdAddOperation = GetInsertBatchIdAddOperation(); jsonPatchDocument.Add(insertIdAddOperation); // add hyperlink to source WorkItem string sourceWorkItemApiEndpoint = ClientHelpers.GetWorkItemApiEndpoint(this.migrationContext.Config.SourceConnection.Account, sourceWorkItem.Id.Value); JsonPatchOperation addHyperlinkAddOperation = MigrationHelpers.GetHyperlinkAddOperation(sourceWorkItemApiEndpoint, sourceWorkItem.Rev.ToString()); jsonPatchDocument.Add(addHyperlinkAddOperation); string json = JsonConvert.SerializeObject(jsonPatchDocument); string workItemType = jsonPatchDocument.Find(a => a.Path.Contains(FieldNames.WorkItemType)).Value as string; var witBatchRequest = new WitBatchRequest(); witBatchRequest.Method = "PATCH"; witBatchRequest.Headers = headers; witBatchRequest.Uri = $"/{this.migrationContext.Config.TargetConnection.Project}/_apis/wit/workItems/${workItemType}?{this.QueryString}"; witBatchRequest.Body = json; return(witBatchRequest); }
public static PatchOperation <TModel> CreateFromJson(JsonPatchOperation operation) { if (operation != null) { switch (operation.Operation) { case Operation.Add: return(AddPatchOperation <TModel> .CreateFromJson(operation)); case Operation.Replace: return(ReplacePatchOperation <TModel> .CreateFromJson(operation)); case Operation.Test: return(TestPatchOperation <TModel> .CreateFromJson(operation)); case Operation.Remove: return(RemovePatchOperation <TModel> .CreateFromJson(operation)); default: throw new PatchOperationFailedException(PatchResources.MoveCopyNotImplemented()); } } throw new VssPropertyValidationException("Operation", PatchResources.InvalidOperation()); }
private void WorkItemTypeChange(MigrationTools._EngineV1.DataContracts.WorkItemData targetWorkItem, bool skipToFinalRevisedWorkItemType, string finalDestType, MigrationTools._EngineV1.DataContracts.RevisionItem revision, MigrationTools._EngineV1.DataContracts.WorkItemData currentRevisionWorkItem, string destType) { //If the work item already exists and its type has changed, update its type. Done this way because there doesn't appear to be a way to do this through the store. if (!skipToFinalRevisedWorkItemType && targetWorkItem.Type != finalDestType) { Debug.WriteLine($"Work Item type change! '{targetWorkItem.Title}': From {targetWorkItem.Type} to {destType}"); var typePatch = new JsonPatchOperation() { Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Add, Path = "/fields/System.WorkItemType", Value = destType }; var datePatch = new JsonPatchOperation() { Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Add, Path = "/fields/System.ChangedDate", Value = currentRevisionWorkItem.ToWorkItem().Revisions[revision.Index].Fields["System.ChangedDate"].Value }; var patchDoc = new JsonPatchDocument { typePatch, datePatch }; _witClient.UpdateWorkItemAsync(patchDoc, int.Parse(targetWorkItem.Id), bypassRules: true).Wait(); } }
public override void WriteJson(JsonWriter writer, JsonPatchOperation value, JsonSerializer serializer) { JToken t = JToken.FromObject(value); if (t.Type != JTokenType.Object) { t.WriteTo(writer); } else { writer.WriteStartObject(); writer.WritePropertyName("op"); writer.WriteValue(value.Operation.ToString().ToLower()); writer.WritePropertyName("path"); writer.WriteValue(value.Path); if (!string.IsNullOrEmpty(value.From)) { writer.WritePropertyName("from"); writer.WriteValue(value.From); } writer.WritePropertyName("value"); t = JToken.FromObject(value.Value); t.WriteTo(writer); writer.WriteEndObject(); } }
private JsonPatchOperation GetAddHyperlinkWithCommentOperation(IList <WorkItem> targetWorkItems, WorkItemMigrationState state, int sourceId, int targetId, WorkItem sourceWorkItem, ISet <string> enabledPhaseStatuses) { IList <WorkItemRelation> targetRelations = targetWorkItems.First(a => a.Id == targetId).Relations; foreach (WorkItemRelation targetRelation in targetRelations) { if (RelationHelpers.IsRelationHyperlinkToSourceWorkItem(context, targetRelation, sourceId)) { string hyperlink = context.WorkItemIdsUris[sourceId]; // only store the enabled phase statuses RevAndPhaseStatus newRevAndPhaseStatus = new RevAndPhaseStatus(); newRevAndPhaseStatus.Rev = sourceWorkItem.Rev.Value; newRevAndPhaseStatus.PhaseStatus = enabledPhaseStatuses; state.RevAndPhaseStatus = newRevAndPhaseStatus; // get the key even if its letter case is different but it matches otherwise string idKeyFromFields = targetRelation.Attributes.GetKeyIgnoringCase(Constants.RelationAttributeId); object attributeId = targetRelation.Attributes[idKeyFromFields]; JsonPatchOperation addHyperlinkWithCommentOperation = MigrationHelpers.GetHyperlinkAddOperation(hyperlink, newRevAndPhaseStatus.GetCommentRepresentation(), attributeId); return(addHyperlinkWithCommentOperation); } } throw new Exception($"Could not find hyperlink to source work item on target work item with id: {targetId}. Expected source work item id: {sourceId}"); }
private WitBatchRequest GenerateWitBatchRequestFromWorkItem(WorkItem sourceWorkItem, int targetId) { Dictionary <string, string> headers = new Dictionary <string, string>(); headers.Add("Content-Type", "application/json-patch+json"); JsonPatchDocument jsonPatchDocument = CreateJsonPatchDocumentFromWorkItemFields(sourceWorkItem); string hyperlink = this.migrationContext.WorkItemIdsUris[sourceWorkItem.Id.Value]; object attributeId = migrationContext.TargetIdToSourceHyperlinkAttributeId[targetId]; JsonPatchOperation addHyperlinkWithCommentOperation = MigrationHelpers.GetHyperlinkAddOperation(hyperlink, sourceWorkItem.Rev.ToString(), attributeId); jsonPatchDocument.Add(addHyperlinkWithCommentOperation); string json = JsonConvert.SerializeObject(jsonPatchDocument); var witBatchRequest = new WitBatchRequest(); witBatchRequest.Method = "PATCH"; witBatchRequest.Headers = headers; witBatchRequest.Uri = $"/_apis/wit/workItems/{targetId}?{this.QueryString}"; witBatchRequest.Body = json; return(witBatchRequest); }
public async Task <IEnumerable <JsonPatchOperation> > Process(IMigrationContext migrationContext, IBatchMigrationContext batchContext, WorkItem sourceWorkItem, WorkItem targetWorkItem) { IList <JsonPatchOperation> jsonPatchOperations = new List <JsonPatchOperation>(); if (sourceWorkItem.Relations == null) { return(jsonPatchOperations); } IList <WorkItemRelation> sourceWorkItemLinkRelations = GetWorkItemLinkRelations(migrationContext, sourceWorkItem.Relations); if (sourceWorkItemLinkRelations.Any()) { foreach (WorkItemRelation sourceWorkItemLinkRelation in sourceWorkItemLinkRelations) { int linkedSourceId = ClientHelpers.GetWorkItemIdFromApiEndpoint(sourceWorkItemLinkRelation.Url); int targetWorkItemId = targetWorkItem.Id.Value; int linkedTargetId; if (!migrationContext.SourceToTargetIds.TryGetValue(linkedSourceId, out linkedTargetId)) { continue; } string comment = MigrationHelpers.GetCommentFromAttributes(sourceWorkItemLinkRelation); WorkItemLink newWorkItemLink = new WorkItemLink(linkedTargetId, sourceWorkItemLinkRelation.Rel, false, false, comment, 0); JsonPatchOperation workItemLinkAddOperation = MigrationHelpers.GetWorkItemLinkAddOperation(migrationContext, newWorkItemLink); jsonPatchOperations.Add(workItemLinkAddOperation); } } return(jsonPatchOperations); }
private static void _CheckProperty(this object obj, JsonPatchOperation operation, string propertyName, List <string> errors) { if (obj != null) { return; } errors.Add($"Operation '{operation}' requires a {propertyName}."); }
/// <summary> /// Removes the specified path. /// </summary> /// <param name="patchDoc">The patch document.</param> /// <param name="path">The path.</param> public static void Remove(this JsonPatchDocument patchDoc, string path) { var patch = new JsonPatchOperation { Operation = Operation.Remove, Path = JsonHelpers.SanitizePath(path) }; patchDoc.Add(patch); }
public async Task <IEnumerable <JsonPatchOperation> > Process(IMigrationContext migrationContext, IBatchMigrationContext batchContext, WorkItem sourceWorkItem, WorkItem targetWorkItem) { IList <JsonPatchOperation> jsonPatchOperations = new List <JsonPatchOperation>(); JsonPatchOperation addPostMoveTagOperation = AddPostMoveTag(migrationContext, sourceWorkItem); jsonPatchOperations.Add(addPostMoveTagOperation); return(jsonPatchOperations); }
/// <param name="data">JSON-formatted data</param> public JsonPatch BuildJsonPatch(JsonPatchOperation operation, string data, string path) { var jsonPatch = new JsonPatch(operation, path) { Data = data }; return(jsonPatch); }
public static JsonPatchOperation GetRelationRemoveOperation(int existingRelationIndex) { JsonPatchOperation jsonPatchOperation = new JsonPatchOperation(); jsonPatchOperation.Operation = Operation.Remove; jsonPatchOperation.Path = $"/{Constants.Relations}/{existingRelationIndex}"; return(jsonPatchOperation); }
internal JsonPatchDocument CreatePatchDocument() { var result = new JsonPatchDocument(); var keys = _fieldValues.Keys.ToList(); if (_initialFieldValues != null) { keys = keys.Union(_initialFieldValues.Keys).Distinct().OrderBy(_ => _).ToList(); } keys.Remove(SystemField.WorkItemType); keys.Remove(SystemField.Project); foreach (var key in keys) { object initialValue = null; _initialFieldValues?.TryGetValue(key, out initialValue); var hasNewValue = _fieldValues.TryGetValue(key, out var value); if (initialValue == null && value != null) { var operation = new JsonPatchOperation { Operation = Operation.Add, Path = $"/fields/{key}", Value = EncodeValueForJSonDocument(value) }; result.Add(operation); } else if (hasNewValue) { if (value == null) { var operation = new JsonPatchOperation { Operation = Operation.Remove, Path = $"/fields/{key}" }; result.Add(operation); } else { var operation = new JsonPatchOperation { Operation = Operation.Replace, Path = $"/fields/{key}", Value = EncodeValueForJSonDocument(value) }; result.Add(operation); } } } return(result); }
/// <summary> /// Better use JsonPatchManager for convenience. /// </summary> internal JsonPatch(JsonPatchOperation operation, string path) { this.Operation = operation; this.Path = path; _setMethod = SetMethod.None; if (operation == JsonPatchOperation.Remove) { this.Data = "null"; } }
public static JsonPatchOperation GetRelationAddOperation(WorkItemRelation relation) { JsonPatchOperation jsonPatchOperation = new JsonPatchOperation(); jsonPatchOperation.Operation = Operation.Add; jsonPatchOperation.Path = $"/{Constants.Relations}/-"; jsonPatchOperation.Value = relation; return(jsonPatchOperation); }
/// <summary> /// Replaces the specified path. /// </summary> /// <param name="patchDoc">The patch document.</param> /// <param name="path">The path.</param> /// <param name="value">The value.</param> public static void Replace(this JsonPatchDocument patchDoc, string path, object value) { var patch = new JsonPatchOperation { Operation = Operation.Replace, Path = JsonHelpers.SanitizePath(path), Value = value }; patchDoc.Add(patch); }
/// <summary> /// Adds the specified path. /// </summary> /// <param name="patchDoc">The patch document.</param> /// <param name="path">The path.</param> /// <param name="value">The value.</param> /// <returns>A JsonPatchDocument.</returns> public static JsonPatchDocument Add(this JsonPatchDocument patchDoc, string path, object value) { var patch = new JsonPatchOperation { Operation = Operation.Add, Path = JsonHelpers.SanitizePath(path), Value = value }; patchDoc.Add(patch); return(patchDoc); }
public static JsonPatchOperation AddLink(this JsonPatchDocument source, WorkItemRelation relation) { var op = new JsonPatchOperation() { Operation = Operation.Add, Path = "/relations/-", Value = relation }; source.Add(op); return(op); }
public static JsonPatchOperation UpdateField(this JsonPatchDocument source, string fieldName, object newValue) { var op = new JsonPatchOperation() { Operation = Operation.Replace, Path = ToFieldPath(fieldName), Value = newValue }; source.Add(op); return(op); }
/// <summary> /// Validates and returns the type for the operation. /// </summary> /// <param name="operation"></param> /// <returns></returns> protected static Type ValidateAndGetType(JsonPatchOperation operation) { var type = GetType(typeof(TModel), operation.Path); if (type == null) { throw new VssPropertyValidationException("Path", PatchResources.UnableToEvaluatePath(operation.Path)); } return(type); }
public async Task <IEnumerable <JsonPatchOperation> > Process(IMigrationContext migrationContext, IBatchMigrationContext batchContext, WorkItem sourceWorkItem, WorkItem targetWorkItem) { IList <JsonPatchOperation> jsonPatchOperations = new List <JsonPatchOperation>(); AttachmentReference aRef = await UploadAttachmentsToTarget(migrationContext, sourceWorkItem); JsonPatchOperation revisionHistoryAttachmentAddOperation = MigrationHelpers.GetRevisionHistoryAttachmentAddOperation(aRef, sourceWorkItem.Id.Value); jsonPatchOperations.Add(revisionHistoryAttachmentAddOperation); return(jsonPatchOperations); // We could just return one item, but we make an IList to be consistent }
public static new PatchOperation <TModel> CreateFromJson(JsonPatchOperation operation) { ValidatePath(operation); ValidateType(operation); if (operation.Value != null) { throw new VssPropertyValidationException("Value", PatchResources.ValueNotNull()); } return(new RemovePatchOperation <TModel>(operation.Path)); }
public async Task <IEnumerable <JsonPatchOperation> > Process(IMigrationContext migrationContext, IBatchMigrationContext batchContext, WorkItem sourceWorkItem, WorkItem targetWorkItem) { var jsonPatchOperations = new List <JsonPatchOperation>(); var attachments = await UploadAttachmentsToTarget(migrationContext, sourceWorkItem); foreach (var attachment in attachments) { JsonPatchOperation revisionHistoryAttachmentAddOperation = MigrationHelpers.GetRevisionHistoryAttachmentAddOperation(attachment, sourceWorkItem.Id.Value); jsonPatchOperations.Add(revisionHistoryAttachmentAddOperation); } return(jsonPatchOperations); }
private JsonPatchOperation CreateTags(string path, List <string> tags) { var cleanList = tags.Where(x => x.Length > 0); var mytags = new JsonPatchOperation { Operation = Operation.Add, Path = path, Value = string.Join(",", cleanList), }; return(mytags); }
public static new PatchOperation <TModel> CreateFromJson(JsonPatchOperation operation) { ValidatePath(operation); var value = ValidateAndGetValue(operation); if (value == null) { throw new VssPropertyValidationException("Value", PatchResources.ValueCannotBeNull()); } return(new AddPatchOperation <TModel>(operation.Path, value)); }
public static JsonPatchOperation GetJsonPatchOperationReplaceForField(KeyValuePair <string, object> field) { string key = field.Key; object value = field.Value; JsonPatchOperation jsonPatchOperationAdd = new JsonPatchOperation() { Operation = Operation.Replace, Path = $"/{Constants.Fields}/{key}", Value = value }; return(jsonPatchOperationAdd); }
public void Remove_Success(object input, string path, string expectedJson) { var patchOperations = new JsonPatchOperation[] { new JsonPatchRemoveOperation { Path = path } }; var output = Patch(input, patchOperations); output.ShouldBeJson(expectedJson); }
public void Test_Success(object input, string path, object value, string expectedJson) { var patchOperations = new JsonPatchOperation[] { new JsonPatchTestOperation { Path = path, Value = value } }; var output = Patch(input, patchOperations); output.ShouldBeJson(expectedJson); }