使用REST API创建新的团队项目 [英] Creating a new Team Project using the REST api
问题描述
这整个星期我一直在反对.使用REST API创建新的团队项目.在我所看到的任何地方,响应都是相同的,并且总是涉及使用命令行和xml.
Ive been banging my head against this all week. Creating a new Team Project using the REST api. Everywhere i look, the response is the same, and it always involves using command line and xml.
但是为什么?
在Visual Studio在线页面上,可以找到以下内容:
On the visual studio online pages this can be found:
https://www.visualstudio.com/zh-CN/集成/api/tfs/项目
(专门查看标有创建团队项目"的部分)
(Specifically looking at the part labelled "Create a team project")
那么,如果不能使用它,为什么会存在呢?还是我想念什么?
So why does this exist if it cant be used? Or am i missing something?
如果有人知道使用此示例的任何示例,我将不胜感激.
If anyone knows any examples of using this i would greatly appreciate it.
我一直在使用Microsoft.TeamFoundation.WorkItemTracking.Client命名空间等...并且一直在为项目高兴地创建新的工作项
Ive been using the Microsoft.TeamFoundation.WorkItemTracking.Client namespaces etc... and have been happily creating new work items to projects
和Ive甚至还设法使用API来下拉项目列表.使用此示例中的代码(滚动到页面底部)
and Ive even managed to use the API to pull down lists of projects too. using code from this example (scroll to bottom of page)
https://www.visualstudio.com/zh-我们/集成/入门/休息/基础
但是我无法为我一生张贴一个新的团队项目.
but i cannot for the life of me post a new team project.
这时我愿意接受任何建议,我在这里创建了一个帐户,只是想问(我喜欢这个网站):(
At this point i am open to any suggestions, i created an account here just to ask (i love this site) :(
根据要求,提供一些代码:
As requested, some code:
static async Task<string> PostProjectAsync(HttpClient _client, string _apiUrl, string _apiVersion)
{
var responseBody = string.Empty;
HttpContent hc = new StringContent(@"
{
""name"": ""Testprojectfromconsole"",
""description"": ""Posted from console application using the tfs API""
}
");
//TODO: make a class that matches the json layout that the api is expecting
//then see if you have any better luck with that instead of this horrid horrid mess
ProjectPost newproj = new ProjectPost();
newproj.Name = @"Test Project -From console";
newproj.Description = @"Hopefully this has been posted from the console app, delete it later on if need be.";
newproj.Capabilities.VersionControl.SourceControlType = @"TFS"; //probably wrong
newproj.Capabilities.ProcessTemplate.TemplateTypeId = @"default"; //also probably wrong
string json = JsonConvert.SerializeObject(newproj);
try
{
using (HttpResponseMessage response = _client.PostAsync(_apiUrl + _apiVersion, hc).Result)
{
response.EnsureSuccessStatusCode();
responseBody = await response.Content.ReadAsStringAsync();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
return responseBody;
}
此刻,我正在将名为"hc"的HttpContent传递给postasync,但是如果我将其切换为json对象,则postasync会停止工作(因为它希望httpcontent不是json)
At the moment I'm passing a HttpContent called "hc" to the postasync, but if i switch it for the json object, the postasync stops working (because it wants httpcontent not a json)
在调用此方法之前,将客户端设置为
before this methodis called, the client is set up as so:
client.DefaultRequestHeaders.Accept.Add(
new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
//Set alternate credentials
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", ALTUSERNAME, ALTPASSWORD))));
Console.WriteLine("<--------------Getting projects from tfs!-------------->");
Console.WriteLine("<----------------Hold on to your butts!---------------->");
responseBody = await GetAsync(client, BASEURL + "projects", APIVERS);
Console.WriteLine(responseBody.ToString());
Console.WriteLine("<----------------Making a new project!----------------->");
Console.WriteLine("<----------------Hold on to your butts!---------------->");
responseBody = await PostProjectAsync(client, BASEURL + "projects", APIVERS);
Console.WriteLine(responseBody.ToString());
哦,URL是这样的:
static string PN1 = @"Test Project -From Web";
static string PN2 = @"Another Test Project -From Web";
static string COL = @"DefaultCollection";
static string BASEURL = "https://{0}.visualstudio.com/DefaultCollection/_apis/";
// Get the alternate credentials that you'll use to access the Visual Studio Online account.
static string ALTUSERNAME = "myusername";
static string ALTPASSWORD = "mypassword!";
//Your visual studio account name
static string ACCOUNT = "ourserver";
//Api version query parameter
static string APIVERS = "?api-version=1.0";
推荐答案
这是我使用的代码.这是为.net 3.5设计的,但是我找到了.net 4.5.1的解决方案:
Here is the code that I've used. This is made for .net 3.5 but I found solutions with .net 4.5.1:
private const string PROJECT_TEMPLATE_AGILE = "adcc42ab-9882-485e-a3ed-7678f01f66bc";
private const string PROJECT_TEMPLATE_SCRUM = "6b724908-ef14-45cf-84f8-768b5384da45";
private const string PROJECT_TEMPLATE_CMMI = "27450541-8e31-4150-9947-dc59f998fc01";
VsoTeamProject project = new VsoTeamProject(
newFolderName,
comment,
new Capabilities(new VersionControl("Tfvc"), new ProcessTemplate(projectTemplateId)));
CreateTeamProject(project, "POST", false); // this calls PostResponse method
这是主要方法:
private void PostResponse(VsoTeamProject project, string method, bool useProjectName)
{
string projectState = "wellFormed";
if(method.Equals("DELETE"))
{
projectState = "deleting";
}
var requestUriString = ConstructUrl(
useProjectName ? project.TeamProjectId : string.Empty,
string.Empty,
new Dictionary<string, object>());
var httpWebRequest = (HttpWebRequest)WebRequest.Create(requestUriString);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = method;
string autorization = TFSImplementor.LoginName + ":" + TFSImplementor.Password;
byte[] binaryAuthorization = Encoding.UTF8.GetBytes(autorization);
autorization = Convert.ToBase64String(binaryAuthorization);
autorization = "Basic " + autorization;
httpWebRequest.Headers.Add("AUTHORIZATION", autorization);
if(method.Equals("POST"))
{
using(var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = JsonConvert.SerializeObject(project);
streamWriter.Write(json);
}
}
try
{
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
if(httpResponse.StatusCode == HttpStatusCode.Accepted)
{
Task<WebResponse> responseTask = Task.Factory.FromAsync<WebResponse>(httpWebRequest.BeginGetResponse, httpWebRequest.EndGetResponse, null);
using(var responseStream = responseTask.Result.GetResponseStream())
{
var reader = new StreamReader(responseStream);
var t = reader.ReadToEnd();
ProjectStatus json = JsonConvert.DeserializeObject<ProjectStatus>(t);
if(json.status.Equals("queued"))
{
while(true)
{
if(CheckTeamProjectState(project.ProjectName, true, projectState))
{
break;
}
}
}
}
}
}
catch(WebException e)
{
using(WebResponse response = e.Response)
{
using(Stream data = response.GetResponseStream())
{
using(var reader = new StreamReader(data))
{
string text = reader.ReadToEnd();
Logger.Error(text);
Logger.Exception(e);
if(method.Equals("DELETE"))
{
throw new Exception("Failed to delete project, check log for more details");
}
throw new Exception("Failed to create project, check log for more details");
}
}
}
}
}
以下是您可以使用的类:
Here are the classes that you can use:
private class VsoTeamProject
{
#region Fields
private readonly string m_name;
private readonly string m_comment;
private readonly string m_teamProjectId;
private readonly Capabilities m_capabilities;
#endregion
#region Constructors
public VsoTeamProject(string teamProjectId, string name)
{
m_teamProjectId = teamProjectId;
m_name = name;
}
public VsoTeamProject(string projectName, string description, Capabilities capabilities)
{
m_name = projectName;
m_comment = description;
m_capabilities = capabilities;
}
#endregion
#region Properties
[JsonProperty("name")]
protected internal string ProjectName
{
get
{
return m_name;
}
}
[JsonProperty("description")]
protected internal string Description
{
get
{
return m_comment;
}
}
protected internal string TeamProjectId
{
get
{
return m_teamProjectId;
}
}
[JsonProperty("capabilities")]
protected internal Capabilities Capabilities
{
get
{
return m_capabilities;
}
}
#endregion
}
private class ProjectStatus
{
public string id { get; set; }
public string status { get; set; }
public string url { get; set; }
public string name { get; set; }
public string state { get; set; }
public string message { get; set; }
}
private class Capabilities
{
public Capabilities(VersionControl versionControl, ProcessTemplate template)
{
VersionControl = versionControl;
ProcessTemplate = template;
}
[JsonProperty("processTemplate")]
public ProcessTemplate ProcessTemplate { get; private set; }
[JsonProperty("versioncontrol")]
public VersionControl VersionControl { get; private set; }
}
private class VersionControl
{
public VersionControl(object type)
{
SourceControlType = type;
}
[JsonProperty("sourceControlType")]
public object SourceControlType { get; private set; }
}
private class ProcessTemplate
{
public ProcessTemplate(string templateTypeId)
{
TemplateTypeId = templateTypeId;
}
[JsonProperty("templateTypeId")]
public string TemplateTypeId { get; private set; }
}
我还有这个PostResponse方法,也可以从VSO中删除项目.它像一种魅力.
I've this PostResponse method also for deleting the projects from VSO. It works like a charm.
这篇关于使用REST API创建新的团队项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!