0

I'm trying to automate creating git repositories for my team. I need to use the Web Api, NOT the .NET API. The call I'm trying to use is this one which responds, but returns the following error body within a HTTP/1.1 400 Bad Request:

{"$id":"1","innerException":null,"message":"Bad parameters. A repository with a team project and a name are required.","typeName":"System.ArgumentException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089","typeKey":"ArgumentException","errorCode":0,"eventId":0}

The error message is: Bad parameters. A repository with a team project and a name are required.

Here's my code:

    var projectName = "testing";
    var url = ConfigurationManager.AppSettings["TFS-Url"] + "/_apis/git/repositories/?api-version=1.0";
    var data = "{ \"name\": \"" + projectName + "\", \"project\": { \"id\": \"" + ConfigurationManager.AppSettings["TFS-Parent-Project-Guid"] + "\", \"name\": \"" + ConfigurationManager.AppSettings["TFS-Parent-Project-Name"] + "\" } }";

    var wc = new WebClient();
    wc.Credentials = new NetworkCredential("user", "pass");
    var res = wc.UploadString(url, data);

I have tried this without the "name" of the project - (like the example does), without the "id", with varying "id" guids gathered from the Get Repositories Api.

No matter what I try, the same error is returned. Any ideas?

TheSoftwareJedi
  • 34,421
  • 21
  • 109
  • 151
  • Have you tried using Wireshark or Fiddler to intercept the web request when creating a repo via the .Net API or Visual Studio Team Explorer or whatever, then matching that against what you're generating? That'd be my first step, can't really help any more than that though. – Callum Bradbury Apr 15 '15 at 15:47
  • I thought the same, but VS Team Explorer doesn't support creating repos, and I would prefer not to spend time diving into the .NET API unless I have to. Sounds like I might have to... – TheSoftwareJedi Apr 15 '15 at 15:53

1 Answers1

4

I know this is old, but hopefully someone else stumbles here for an answer...

The documentation on MS's website is incorrect. Id is a required property for the Project object when submitting the postdata via the WebApi for creating a new repository in TFS (tested on TFS 2015 Update 2, Update 3, and VSTS).

A code solution for this, should you not have a list of the GUIDs of your projects available is:

public static TfsProject GetTfsProjectGuid(string projectName, string collectionName)
{
    var tfsInstance = ConfigurationManager.AppSettings["TFSInstance"];
    using (var client = new WebClient())
    {
        client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
        client.UseDefaultCredentials = true;

        var tfsUri = new Uri(tfsInstance + collectionName + "/_apis/projects/" + projectName + "?api-version=1.0");
        var response = client.DownloadString(tfsUri);

        JavaScriptSerializer jss = new JavaScriptSerializer();
        return jss.Deserialize<TfsProject>(response.ToString());
    }
}

TfsProject looks like:

public class TfsProject
{
    public string id { get; set; }
    public string name { get; set; }
    public string description { get; set; }
    public string url { get; set; }
    public string state { get; set; }
    public int revision { get; set; }
}

For actually creating the repo, I'm using:

public static OperationResult CreateTfsGitRepository(string projectName, string repositoryName, string collectionName)
{
    var tfsInstance = ConfigurationManager.AppSettings["TFSInstance"];
    using (var client = new WebClient())
    {
        client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
        client.UseDefaultCredentials = true;

        var tfsNewRepository = new TfsRepository();
        tfsNewRepository.name = repositoryName;
        tfsNewRepository.project.id = TfsHelper.GetTfsProjectGuid(projectName, collectionName).id;
        var tfsUri = new Uri(tfsInstance + collectionName + "/_apis/git/repositories/?api-version=1.0");

        JavaScriptSerializer jss = new JavaScriptSerializer();
        var jsonValues = jss.Serialize(tfsNewRepository);
        try
        {
            var response = client.UploadString(tfsUri, "POST", jsonValues);
        }
        catch (WebException ex)
        {
            //Handle WebExceptions here.  409 is the error code for a repository with the same name already exists within the specified project
        }
        return new OperationResult { ReturnValue = 0, Message = "Repository created successfully." };
    }
}

OperationResult object is:

public class OperationResult
{
    public int ReturnValue { get; set; }
    public string Message { get; set; }
}

Thanks!

Brian
  • 91
  • 4