I’m having trouble creating a new work item in Azure DevOps using the REST API. Specifically, I want to include the Microsoft.VSTS.Common.Priority and Microsoft.VSTS.Common.StackRank fields, but my current implementation doesn’t seem to be working correctly.
Here’s the method I’m using to create the work item:
public WorkItemDTO CreateWorkItem(WorkItemDTO workItem, string workItemType)
{
string tokenFormat = $"{string.Empty}:{GetTokenConfig()}";
string credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(tokenFormat));
using (var client = new HttpClient())
{
client.BaseAddress = new Uri($"{DEVOPS_ORG_URL}/{GetProjectNameConfig()}/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json-patch+json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials);
string uri = $"_apis/wit/workitems/${workItemType}?api-version=7.1-preview.3";
var patchDocument = new[]
{
new { op = "add", path = "/fields/System.Title", value = workItem.Title },
new { op = "add", path = "/fields/System.Description", value = workItem.Description },
new { op = "add", path = "/fields/Microsoft.VSTS.Common.Priority", value = workItem.Priority },
new { op = "add", path = "/fields/Microsoft.VSTS.Common.StackRank", value = workItem.BusinessValue }
};
var jsonContent = JsonConvert.SerializeObject(patchDocument);
var content = new StringContent(jsonContent, Encoding.UTF8, "application/json-patch+json");
HttpResponseMessage response = client.PostAsync(uri, content).Result;
if (response.IsSuccessStatusCode)
{
string responseBody = response.Content.ReadAsStringAsync().Result;
var createdWorkItemEntity = JsonConvert.DeserializeObject<WorkItemEntity>(responseBody);
var createdWorkItemDTO = _mapper.Map<WorkItemDTO>(createdWorkItemEntity);
return createdWorkItemDTO;
}
else
{
Console.WriteLine("Error creating work item. Status code: " + response.StatusCode);
string responseBody = response.Content.ReadAsStringAsync().Result;
Console.WriteLine("Response body: " + responseBody);
}
}
return null;
}
What I Tried:
I used a JSON patch document to include the Microsoft.VSTS.Common.Priority and Microsoft.VSTS.Common.StackRank fields.
I sent a POST request to the Azure DevOps REST API with the above JSON patch document.
What I Expected:
The new work item should be created with the Microsoft.VSTS.Common.Priority and Microsoft.VSTS.Common.StackRank fields set according to the values provided.
What Actually Happened:
The work item is created successfully, but the Microsoft.VSTS.Common.Priority and Microsoft.VSTS.Common.StackRank fields are not populated with the provided values.
The response from the API does not provide useful information about why these fields are not being set.
Questions:
Are the Microsoft.VSTS.Common.Priority and Microsoft.VSTS.Common.StackRank fields correctly specified in the patch document?
Could there be an issue with the API version 7.1-preview.3 or the field names?
Is there something specific I might be missing in the request format or API usage?
Neima Mohamed Abdoulkader is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
1
I can reproduce the similar issue when using the sample code.
The cause of the issue could be that the patchDocument
content has issue. If we use the same definition as yours, the Priority
and StackRank
field needs string type input.
To solve this issue, you can change to use the following format to define patchDocument
:
var patchDocument = new Microsoft.VisualStudio.Services.WebApi.Patch.Json.JsonPatchDocument();
patchDocument.Add(
new Microsoft.VisualStudio.Services.WebApi.Patch.Json.JsonPatchOperation()
{
Path = "/fields/System.Description",
Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Add,
Value = workItem.Description
});
patchDocument.Add(
new Microsoft.VisualStudio.Services.WebApi.Patch.Json.JsonPatchOperation()
{
Path = "/fields/System.Title",
Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Add,
Value = workItem.Title
});
patchDocument.Add(
new Microsoft.VisualStudio.Services.WebApi.Patch.Json.JsonPatchOperation()
{
Path = "/fields/Microsoft.VSTS.Common.Priority",
Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Add,
Value = workItem.Priority
});
patchDocument.Add(
new Microsoft.VisualStudio.Services.WebApi.Patch.Json.JsonPatchOperation()
{
Path = "/fields/Microsoft.VSTS.Common.StackRank",
Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Add,
Value = workItem.BusinessValue
});
Here is the full sample:
using Newtonsoft.Json;
using System.Net.Http.Headers;
using System.Text;
public WorkItemDTO CreateWorkItem(WorkItemDTO workItem, string workItemType)
{
string tokenFormat = $"{string.Empty}:{GetTokenConfig()}";
string credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(tokenFormat));
using (var client = new HttpClient())
{
client.BaseAddress = new Uri($"{DEVOPS_ORG_URL}/{GetProjectNameConfig()}/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json-patch+json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials);
string uri = $"_apis/wit/workitems/${workItemType}?api-version=7.1-preview.3";
var patchDocument = new Microsoft.VisualStudio.Services.WebApi.Patch.Json.JsonPatchDocument();
patchDocument.Add(
new Microsoft.VisualStudio.Services.WebApi.Patch.Json.JsonPatchOperation()
{
Path = "/fields/System.Description",
Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Add,
Value = workItem.Description
});
patchDocument.Add(
new Microsoft.VisualStudio.Services.WebApi.Patch.Json.JsonPatchOperation()
{
Path = "/fields/System.Title",
Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Add,
Value = workItem.Title
});
patchDocument.Add(
new Microsoft.VisualStudio.Services.WebApi.Patch.Json.JsonPatchOperation()
{
Path = "/fields/Microsoft.VSTS.Common.Priority",
Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Add,
Value = workItem.Priority
});
patchDocument.Add(
new Microsoft.VisualStudio.Services.WebApi.Patch.Json.JsonPatchOperation()
{
Path = "/fields/Microsoft.VSTS.Common.StackRank",
Operation = Microsoft.VisualStudio.Services.WebApi.Patch.Operation.Add,
Value = workItem.BusinessValue
});
var jsonContent = JsonConvert.SerializeObject(patchDocument);
var content = new StringContent(jsonContent, Encoding.UTF8, "application/json-patch+json");
HttpResponseMessage response = client.PostAsync(uri, content).Result;
if (response.IsSuccessStatusCode)
{
string responseBody = response.Content.ReadAsStringAsync().Result;
var createdWorkItemEntity = JsonConvert.DeserializeObject<WorkItemEntity>(responseBody);
var createdWorkItemDTO = _mapper.Map<WorkItemDTO>(createdWorkItemEntity);
return createdWorkItemDTO;
}
else
{
Console.WriteLine("Error creating work item. Status code: " + response.StatusCode);
string responseBody = response.Content.ReadAsStringAsync().Result;
Console.WriteLine("Response body: " + responseBody);
}
}
return null;
}
WorkItemDTO Class:
public class WorkItemDTO
{
public int Id { get; set; }
public int Rev { get; set; }
public string Type { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string State { get; set; }
public string Url { get; set; }
public int Priority { get; set; } // Add Priority property
public double BusinessValue { get; set; } // Add BusinessValue propert
}
Result:
1
public class WorkItemDTO
{
public int Id { get; set; }
public int Rev { get; set; }
public string Type { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string State { get; set; }
public string Url { get; set; }
public int Priority { get; set; } // Add Priority property
public double BusinessValue { get; set; } // Add BusinessValue propert
}
and this is my workitemEntity :
using Newtonsoft.Json;
namespace AzureDevOpsAPI.Models
{
// Cette classe représente une entité de WorkItem dans Azure DevOps
public class WorkItemEntity
{
[Key]
public int Id { get; set; } // Identifiant unique du WorkItem
public int Rev { get; set; } // Numéro de révision du WorkItem
[JsonProperty(PropertyName = "fields")]
public Fields Fields { get; set; } // Champs du WorkItem
public Links2 Links { get; set; } // Liens associés au WorkItem
public string Url { get; set; } // URL du WorkItem
public string SprintName { get; set; } // Nom du sprint associé au WorkItem
}
// Classe représentant les champs d'un WorkItem
public class Fields
{
public string SystemAreaPath { get; set; } // Chemin de la zone du système
public string SystemTeamProject { get; set; } // Nom du projet de l'équipe
public string SystemIterationPath { get; set; } // Chemin de l'itération
[JsonProperty("System.WorkItemType")]
public string SystemWorkItemType { get; set; } // Type de WorkItem
[JsonProperty("System.State")]
public string SystemState { get; set; } // État du WorkItem
public string SystemReason { get; set; } // Raison de l'état du WorkItem
public DateTime SystemCreatedDate { get; set; } // Date de création du WorkItem
public SystemCreatedBy SystemCreatedBy { get; set; } // Créateur du WorkItem
public DateTime SystemChangedDate { get; set; } // Date de modification du WorkItem
public SystemChangedBy SystemChangedBy { get; set; } // Personne ayant modifié le WorkItem
public int SystemCommentCount { get; set; } // Nombre de commentaires
[JsonProperty("System.Title")]
public string SystemTitle { get; set; } // Titre du WorkItem
public string SystemBoardColumn { get; set; } // Colonne du tableau Kanban
public bool SystemBoardColumnDone { get; set; } // Indicateur de fin de colonne Kanban
[JsonProperty("System.Description")]
public string SystemDescription { get; set; } // Description du WorkItem
public DateTime MicrosoftVSTSCommonStateChangeDate { get; set; } // Date de changement d'état
public int MicrosoftVSTSCommonPriority { get; set; } // Priorité du WorkItem
public float MicrosoftVSTSCommonStackRank { get; set; } // Rang de pile
public string Wef5B0F1FA329CE496382ED607D03A48B89KanbanColumn { get; set; } // Colonne Kanban personnalisée
public bool Wef5B0F1FA329CE496382ED607D03A48B89KanbanColumnDone { get; set; } // Indicateur de fin de colonne Kanban personnalisée
}
// Classe représentant les informations sur le créateur du WorkItem
public class SystemCreatedBy
{
public string DisplayName { get; set; } // Nom affiché du créateur
public string Url { get; set; } // URL du créateur
public Links Links { get; set; } // Liens associés au créateur
public string Id { get; set; } // Identifiant du créateur
public string UniqueName { get; set; } // Nom unique du créateur
public string ImageUrl { get; set; } // URL de l'image du créateur
public string Descriptor { get; set; } // Descripteur du créateur
}
// Classe représentant les liens associés à un utilisateur
public class Links
{
public Avatar Avatar { get; set; } // Avatar de l'utilisateur
}
// Classe représentant un avatar
public class Avatar
{
public string Href { get; set; } // URL de l'avatar
}
// Classe représentant les informations sur la personne ayant modifié le WorkItem
public class SystemChangedBy
{
public string DisplayName { get; set; } // Nom affiché de la personne ayant modifié
public string Url { get; set; } // URL de la personne ayant modifié
public Links1 Links { get; set; } // Liens associés à la personne ayant modifié
public string Id { get; set; } // Identifiant de la personne ayant modifié
public string UniqueName { get; set; } // Nom unique de la personne ayant modifié
public string ImageUrl { get; set; } // URL de l'image de la personne ayant modifié
public string Descriptor { get; set; } // Descripteur de la personne ayant modifié
}
// Classe représentant les liens associés à une modification
public class Links1
{
public Avatar1 Avatar { get; set; } // Avatar de la personne ayant modifié
}
// Classe représentant un avatar
public class Avatar1
{
public string Href { get; set; } // URL de l'avatar
}
// Classe représentant les liens associés au WorkItem
public class Links2
{
public Self Self { get; set; } // Lien vers le WorkItem lui-même
public WorkItemUpdates WorkItemUpdates { get; set; } // Lien vers les mises à jour du WorkItem
public WorkItemRevisions WorkItemRevisions { get; set; } // Lien vers les révisions du WorkItem
public WorkItemComments WorkItemComments { get; set; } // Lien vers les commentaires du WorkItem
public Html Html { get; set; } // Lien HTML du WorkItem
public WorkItemType WorkItemType { get; set; } // Lien vers le type de WorkItem
public Fields1 Fields { get; set; } // Lien vers les champs du WorkItem
}
// Classe représentant un lien vers soi-même
public class Self
{
public string Href { get; set; } // URL du lien
}
// Classe représentant un lien vers les mises à jour du WorkItem
public class WorkItemUpdates
{
public string Href { get; set; } // URL du lien
}
// Classe représentant un lien vers les révisions du WorkItem
public class WorkItemRevisions
{
public string Href { get; set; } // URL du lien
}
// Classe représentant un lien vers les commentaires du WorkItem
public class WorkItemComments
{
public string Href { get; set; } // URL du lien
}
// Classe représentant un lien HTML
public class Html
{
public string Href { get; set; } // URL du lien
}
// Classe représentant un lien vers le type de WorkItem
public class WorkItemType
{
public string Href { get; set; } // URL du lien
}
// Classe représentant un lien vers les champs du WorkItem
public class Fields1
{
public string Href { get; set; } // URL du lien
}
}
Neima Mohamed Abdoulkader is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.