If you’re creating a TFS API program from scratch, the first thing that you’ll need is to reference the TFS API libraries. They are in extensions:
Don’t worry too much about which one’s you’ll need just yet, when you start to write some code, this will be more obvious. The next stage is to create a function that creates your bug; it might look like this:
private static ActionResult CreateNewBug(Project teamProject, string title, string description, string area, string iteration, string assignee, string reproductionSteps) { WorkItemType workItemType = teamProject.WorkItemTypes["Bug"]; // Create the work item. WorkItem newBug = new WorkItem(workItemType); newBug.Title = title; newBug.Description = description; newBug.AreaPath = area; newBug.IterationPath = iteration; newBug.Fields["Assigned To"].Value = assignee; newBug.Fields["Repro Steps"].Value = reproductionSteps; var validationResult = newBug.Validate(); if (validationResult.Count == 0) { // Save the new work item. newBug.Save(); return new ActionResult() { Success = true }; } else { // Establish why it can't be saved var result = new ActionResult() { Success = false, ErrorCodes = new List<string>() }; foreach (var res in validationResult) { Microsoft.TeamFoundation.WorkItemTracking.Client.Field field = res as Microsoft.TeamFoundation.WorkItemTracking.Client.Field; if (field == null) { result.ErrorCodes.Add(res.ToString()); } else { result.ErrorCodes.Add($"Error with: {field.Name}"); } } return result; } }
Obviously, we’re not writing a new front end for TFS here, but the basics are there. The first part of the function gets the relevant fields; once the .Validate() has been called, then we have a look at the result. If there are no errors then just save; otherwise, we try and work out what they were.
In the example above, I’m returning a class of the following type:
public class ActionResult { public bool Success { get; set; } public List<string> ErrorCodes { get; set; } }
But that’s only because this is in its own library. The method above also accepts a Project; assuming that you know what the project is called, you could use something like this to return the correct object:
public static Project GetTeamProject(string uri, string name) { TfsTeamProjectCollection tfs; tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(uri)); // https://mytfs.visualstudio.com/DefaultCollection tfs.Authenticate(); var workItemStore = new WorkItemStore(tfs); var project = (from Project pr in workItemStore.Projects where pr.Name == name select pr).FirstOrDefault(); if (project == null) throw new Exception($"Unable to find {name} in {uri}"); return project; }
And that’s it; here’s my calling code:
var result = TFSUtilLibrary.WorkItemHelper.CreateNewBug(TFSUri, "TFSSandbox", "Test new bug", "New bug description", @"TFSSandbox\Team 12", @"TFSSandbox\Iteration 1", "Paul Michaels", "Click the screen");
Here’s the bug to prove it works: