我有一个Visual Studio扩展,我们在内部用于项目,它需要做的一件事就是将门票发布到VSTS。以前我们使用的是现场TFS,并且建立与邮政票证的连接非常简单:
var vssCreds = new VssCredentials(true);
projectCollection = new TfsTeamProjectCollection(url, vssCreds);
workItems = projectCollection.GetService<WorkItemStore>();
project = workItems.Projects["My Project"];
defaultType = project.WorkItemTypes["Bug"];
//...
var newItem = new WorkItem(defaultType)
{
Title = title
};
newItem.Fields["Assigned To"].Value = assignTo;
newItem.Fields["Repro Steps"].Value = repoSteps;
var validationResult = newItem.Validate();
newItem.Save();
这很好用。但升级到VSTS之后,我很难获得凭据部分的工作。我更改了这一行:
projectCollection = new TfsTeamProjectCollection(url, vssCreds);
对此:
projectCollection = new TfsTeamProjectCollection(url, new VssClientCredentials());
这对我来说很好。但是,当我与团队中的其他人分享时,它首先没有工作,然后开始工作一段时间。我猜测与VSTS交互导致他们的凭据被加载,以便它可以工作。但我至少有一个人似乎完全无法使其发挥作用。
那么使用VSTS凭证(应该已经存在于VS中)的正确方法是什么?
我看到VssClientCredentials
(https://msdn.microsoft.com/en-us/library/dn228355(v=vs.120).aspx)的重载:
public VssClientCredentials(
IVssCredentialPrompt credentialPrompt
)
我怀疑这可能有用,但我似乎无法找出某个地方是否内置了IVssCredentialPrompt
,或者如果没有,如何实现它。
答案 0 :(得分:1)
从中删除相关密钥
Computer\HKEY_CURRENT_USER\Software\Microsoft\VSCommon\14.0\ClientServices\TokenStorage\VisualStudio\VssApp
,然后再次进行身份验证。
您还可以使用以下代码指定其他Kind(默认为vssApp)和Namespace(默认为VisualStudio):
var c = new VssClientCredentials();
c.Storage = new VssClientCredentialStorage(storageKind: "VssApp2", storageNamespace: "VisualStudio");
projectCollection = new TfsTeamProjectCollection(url, c);
答案 1 :(得分:0)
由于完全不清楚的原因以及对这个完全不同的问题的回答:https://stackoverflow.com/a/40256731/1250301
似乎产生一个新线程会导致在需要时出现登录提示并修复所有问题。所以,如果我这样做:
Task.Run(() =>
{
var url = new Uri(_tfsUrl);
var cred = new VssClientCredentials();
projectCollection = new TfsTeamProjectCollection(url, cred);
workItems = projectCollection.GetService<WorkItemStore>();
}).Wait();
project = workItems.Projects["Job Posting Data"];
defaultType = project.WorkItemTypes["Bug"];
taskType = project.WorkItemTypes["Task"];
然后它有效。我不知道它为什么有用,或者为什么这是必要的(起初我认为这可能是不在UI线程中的问题所以我试过Application.Current.Dispatcher.Invoke
没有用)但似乎已经解决了这个问题。