Reputation: 49
I am trying to queue a build from my TFS servers using the TFS Rest API nuget package for c#. However, upon sending the request to the server with the JSON:
"definition":{ "id":63 }
I get a 400 response back with the error:
message=Value cannot be null. Parameter name: build.Definition
I think I am sending the JSON correctly, considering before I was getting errors saying it couldnt be deserialized, or that there wasnt a JSON in the first place.
Can someone help me figure out what is causing this error and how to fix it?
For reference and showing what I have already used as help:
Again Queueing a build in powershell
And several other articles (google "queue build tfs rest api c#")
//post request for queuing the build
var client = new RestClient(websiteName);
var request = new RestRequest("_apis/build/builds?ignoreWarnings=true&sourceBuildId=63&api-version=4.0", Method.POST, DataFormat.Json);
Dictionary<string, string> values = new Dictionary<string, string>();
values.Add("{\"definition\"", "{\"id\":63}}");
request.AddHeader("Authorization", "Basic " + Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", "", personalAccessToken))));
request.AddJsonBody(values);
IRestResponse response = client.Execute(request);
Upvotes: 0
Views: 312
Reputation: 41625
If you use the Rest API nuget packages, you can use build-in methods to queue a new build, this will much convenient than using HttpClient
or other class:
var url = new Uri("http://tfsServer:8080/tfs/MyCollection/");
var connection = new VssConnection(url, new VssCredentials());
var buildServer = connection.GetClient<BuildHttpClient>();
// Get the list of build definitions.
var definition = buildServer.GetDefinitionAsync("teamprojectname", 33).Result;
//It requires project's GUID, so we're compelled to get GUID by API.
var res = buildServer.QueueBuildAsync(new Build
{
Definition = new DefinitionReference
{
Id = definition.Id
},
Project = definition.Project
});
Console.WriteLine($"Queued build with id: {res.Id}");
If you still want to use the URL to trigger, here is also an example:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://tfsServer:8080/tfs/DefaultCollection/TeamProject/_apis/build/builds?api-version=4.0");
request.Credentials = CredentialCache.DefaultNetworkCredentials;
request.Method = "Post";
request.ContentType = "application/json";
Stream stream = request.GetRequestStream();
string json = "{\"definition\":{\"id\":63}}";
byte[] buffer = Encoding.UTF8.GetBytes(json);
stream.Write(buffer, 0, buffer.Length);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Console.Write(response.StatusCode);
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
Console.Read();
Upvotes: 0
Reputation: 59036
"definition":{ "id":63 }
isn't valid JSON.
{ "definition":{ "id":63 } }
is.
Don't construct JSON as a string, use ConvertTo-Json
on an associative array to turn an appropriately-shaped object into JSON, such as
$body = @{
definition = @{
id = $definitionId
}
} | ConvertTo-Json -Depth 100
Upvotes: 1