Search code examples
c#tfstfs-workitemtfs-sdk

Create task from template via API in Microsoft Team Foundation Server 2018


I'm creating an integration from our testing framework (Selenium) to Team Foundation Server (TFS) 2018 using C# (our tests are already written in it) - the integration will generate work items in TFS based on test results. I'd like to create the work item from a template, and I can't seem to find any documentation on doing so. I'm using the TFS client library from Microsoft found here.

I can pull a template from TFS:

var client = new HttpClient()
// Client auth stuff removed
var method = new HttpMethod("GET");
var httpRequestMessage = new HttpRequestMessage(method, "http://server:port/tfs/collection/team/project/_api/wit/templates/12345abc");
var httpResponseMessage = client.SendAsync(httpRequestMessage).Result;
WorkItemTemplate tfs_template = httpResponseMessage.Content.ReadAsAsync<WorkItemTemplate>().Result;

The API for creating new work items here looks fairly straightforward, but I can't find any way to connect the two actions, or a way to apply a template using this call. Is it possible to create a work item via API with a template, and if so, is there any documentation for it?


Solution

  • You can not create work item from work item template. You can use work item templates to see which fields contains some default values. This example for new work item from template with rest api:

            using Microsoft.TeamFoundation.Core.WebApi;
            using Microsoft.TeamFoundation.Core.WebApi.Types;
            using Microsoft.TeamFoundation.WorkItemTracking.WebApi;
            using Microsoft.VisualStudio.Services.Common;
            using Microsoft.VisualStudio.Services.WebApi;
            using Microsoft.VisualStudio.Services.WebApi.Patch;
            using Microsoft.VisualStudio.Services.WebApi.Patch.Json;
            using System;
            using System.Collections.Generic;
            using System.Linq;
            using System.Text;
            using System.Threading.Tasks;
    
            namespace ConsoleApp1
            {
                class Program
                {
                    static string ServiceURL = "https://your_name.visualstudio.com";
                    static string PAT = "your pat";
                    static void Main(string[] args)
                    {
                        string projectName = "your project";
                        string templateName = "Critical bug";
    
                        /*connect to service. I use VSTS. In your case: 
                        VssConnection connection = new VssConnection(new Uri(ServiceURL), new VssCredential());
                        https://learn.microsoft.com/ru-ru/azure/devops/integrate/get-started/client-libraries/samples?view=vsts
                        */
    
                        VssConnection connection = new VssConnection(new Uri(ServiceURL), new VssBasicCredential(string.Empty, PAT));
                        //get clients
                        var WitClient = connection.GetClient<WorkItemTrackingHttpClient>();
                        var ProjectClient = connection.GetClient<ProjectHttpClient>();
    
                        var project = ProjectClient.GetProject(projectName).Result;
    
                        //get context for default project team
                        TeamContext tmcntx = new TeamContext(project.Id, project.DefaultTeam.Id);
    
                        //get all template for team
                        var templates = WitClient.GetTemplatesAsync(tmcntx).Result;
    
                        //get tempate through its name
                        var id = (from tm in templates where tm.Name == templateName select tm.Id).FirstOrDefault();
    
                        if (id != null)
                        {
                            var template = WitClient.GetTemplateAsync(tmcntx, id).Result;
    
                            JsonPatchDocument patchDocument = new JsonPatchDocument();
    
                            foreach (var key in template.Fields.Keys) //set default fields from template
                                patchDocument.Add(new JsonPatchOperation()
                                {
    
                                    Operation = Operation.Add,
                                    Path = "/fields/" + key,
                                    Value = template.Fields[key]
    
                                });
    
                            //add any additional fields
                            patchDocument.Add(new JsonPatchOperation()
                            {
    
                                Operation = Operation.Add,
                                Path = "/fields/System.Title",
                                Value = "My critical bug"
    
                            });
    
                            var newWorkItem = WitClient.CreateWorkItemAsync(patchDocument, projectName, template.WorkItemTypeName).Result;
                        }            
    
                    }
                }
            }
    

    My template: enter image description here