Dears
Please help me with VS add-in Tfs connection question.
I've wrote VS 2017 plugin that uses TfsTeamProjectCollection class to connect to the tfs server. Tfs server is hosted in the https://dev.azure.com
However on certain computers it fails to connect to the Tfs server.
For example, I've tried to reproduce this and cleared all caches like described here. After clearing/connecting several cycles I've got the following:
VS Team Explorer is connected to the Tfs. I can checkout/checkin files, load history etc.
My add-in fails to connect with 401 non authorized error.
unity test started by VS is able to connect to the same Tfs using the same code
I've created sample console application that uses exactly the same class and method from add-in to connect and it works too.
Here is the source code I'm using to connect:
public override TfsTeamProjectCollection CreateCollection(WorkspaceInfo wi)
{
var s = (overrideConfig ?? Config);
var u = wi.ServerUri;
var vssCred = new VssClientCredentials(); // GetCredentials(s.Vsts);
Logger.Debug("getting collection for url:{0}", u);
TfsTeamProjectCollection tpc = null;
try
{
tpc = new TfsTeamProjectCollection(u, vssCred);
Logger.Debug("authenticating");
tpc.Authenticate(); // 401 non authorized exception here
}
I've tried to add vssCred.Storage = new VssClientCredentialStorage(); before Autheticate() but no luck
Then I've checked network packets using Fiddler application.
It shows the same request packet is sent using unit test, console application and add-in.
But console application and unit test produces initial request
POST
https://dev.azure.com/quipu-cwnet/Services/v3.0/LocationService.asmx
HTTP/1.1
and response is
HTTP/1.1 401 Unauthorized
X-TFS-FedAuthRedirect:
https://app.vssps.visualstudio.com/_signin?realm=dev.azure.com&reply_to=https%3A%2F%2Fdev.azure.com%2F...
Then console and unit test sends packet to the redirect url and asks for user credentials.
When add-in tries to connect to the Tfs server fiddler shows only first POST request and 401 response (with the same X-TFS-FedAuthRedirect header. But there is no redirection. From user side it looks like application freezes for some period after 401 response is obtained and then fails with 401 error.
Both Unit test and add-in assemblies has the same references to the 15.0.0 assemblies like Microsoft.TeamFoundation.VersionControl.Client and related.
I've tried VssConnection but the same
VssConnection connection = new VssConnection(u, vssCred);
connection.ConnectAsync().SyncResult();
var prj = connection.GetClient<ProjectHttpClient>();
var prjCollection = prj.GetProjects().Result; // 401 error here when is executed as VS add-in
foreach (var pc in prjCollection)
Logger.Debug("\tVssConnection project {0} {1}", pc.Id, pc.Name);
I'm using the same user to start VS (and add-in) and console. No elevated permissions.
Is there anything I can do with TfsConnection when used as VS add-in ?
the answer is to execute Authenticate() in the separate thread (non GUI) :crazy
var authTask = Task.Run(() => tpc.Authenticate());
authTask.Wait();
Please note that I'm using VS 2017 15.9.11 and Microsoft.TeamFoundationServer.ExtendedClient.15.112.1
upd1: I've upgraded Microsoft.TeamFoundationServer.ExtendedClient to 15.113.1
it works on my machine but still fails on my colleague machine.
Tfs credentials are working like a charm on both machines:
var tfsClientCredentials = TfsClientCredentials.LoadCachedCredentials(wi.ServerUri, false, false);
var res = new TfsTeamProjectCollection(wi.ServerUri, tfsClientCredentials);
res.EnsureAuthenticated();
despite the fact it is marked as obsolete.
Related
I am trying to programmatically add the mention of users that are members of groups in TFS in the discussion area of work items. We were using the 1.0 version with TFS 2017 update 2 with success:
#{id.DisplayName}
However upgrading to TFS 2017 update 3 fails to send emails on the notifications. We also tried all of the "user ids" we could find on the TeamFoundationIdentitiy object for the solutions found here:
VSTS - uploading via an excel macro and getting #mentions to work
So how can we get emails for #mentions to work again in TFS 2017.3?
Update: 9/11/2018
Verified service account fails to send emails while my account running the same code will send emails for mentions:
using (var connection = new VssConnection(collectionUri, cred))
using (var client = connection.GetClient<WorkItemTrackingHttpClient>())
{
var wi = new JsonPatchDocument
{
new JsonPatchOperation()
{
Operation = Operation.Add,
Path = "/fields/System.History",
Value = $"#{id.DisplayName} <br/>"
}
};
using (var response = client.UpdateWorkItemAsync(wi, workItemId, suppressNotifications: false))
{
response.Wait();
}
}
We solved by dropping use of the WorkItemHttpClient and going back to loading the SOAP WorkItemStore as the user that submitted the changes instead of the service account. It would be nice if we could use impersonation of a user with TFS's WebApi
I have a TFS2018 setup on a server and I am trying to figure out what is the path to the api. Should the path look look like this? Do I have to enable the API on the server?
https://myserver/tfs/DefaultCollection/MyProject/_apis
If I run this in code like this
var cred = new VssCredentials(
new WindowsCredential(new NetworkCredential("username", "Pass")));
var buildClient = new BuildHttpClient(new Uri("https://myserver/tfs/DefaultCollection/MyProject/_apis", UriKind.Absolute), cred);
await buildClient.CreateDefinitionAsync(buildDef);
I get the following error
Web method running:
[https://myserver/tfs/DefaultCollection/MyProject/_apis]
(OPTIONS)_apis[]
It depends on how the server was setup. If it's a fresh install, the /tfs/ is no longer used. If it's an upgrade the /tfs/ is retained to not break existing clients. And I suspect you can leave off the /_api/ part as well, as that should be automatically added.
The best way to get to the BuildCLient is to use the TFS Server or Collection object and request the server:
var collection = new TfsTeamProjectCollection(tfsCollectionUri, credential);
var buildClient = collection.GetClient<BuildHttpClient>();
I'm having a problem calling the API's method CompleteSale via eBay_Service .NET SDK (v967) since 2 weeks (02/10).
When the ERP tries to sends some updated information about one order, it receives this Exception:
the underlying connection was closed an unexpected error occurred on a send
so I haven't got a response from the API.
There are more than one strange things:
there are some batch in background, using the same .dll, and they
work fine;
after rebooting the server the first call to "CompleteSale" works fine;
after registering again the .dll via the "regsrv" command, it worked
fine for one day;
all operators that uses the ERP are connected to the server via
remote desktop and all of they notice the problem. Instead, if i
connect from my company's office, all works fine;
I've tried to increase the timeout to 360 sec (from 60 sec) and nothing changed.
The ERP is developed in progress (OpenGL) , so I can't fix with setting "KeepAlive" to "false", setting the certificate explicitly (Tsl1.1 | Tsl1.2) or making other interventions on .net side. I was wrong, it can be done from the source code of the SDK.
i've checked the Security Protocols on the api's servers discovering that the "SSL3" is not longer supported whereas the default value for the ServicePointManager.SecurityProtocol in .NET 2.0 is SSL3.
I've solved the problem by adding this hotfix at the "eBayXmlAPIInterfaceService" class in the SDK's source code:
//768 = Tsl1.1, 3070 = Tsl1.2
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072 |
(SecurityProtocolType)768;
HttpWebRequest http = (HttpWebRequest) WebRequest.Create(this.Url);
http.Method = "POST";
http.ContentType = "text/xml";
http.ContentLength = data.Length;
http.KeepAlive = false;
Probably Microsoft as released an hotfix to correct this problem but the server wesn't updated since 2015.
Moreover i've replicated the .net code in the ABL application in a program that we use to do get/post requestes:
DEF VAR w-tsl10 AS System.Net.SecurityProtocolType
w-tsl10 = CAST(System.Enum:ToObject(PROGRESS.Util.TypeHelper:GetType("System.Net.SecurityProtocolType":U), 192), System.Net.SecurityProtocolType).
ystem.Net.ServicePointManager:SecurityProtocol = w-tsl10.
link to the security protocol verifier: https://www.ssllabs.com/ssltest/index.html
I was working with betfair api and got this issue. After some research I found this
System.Net.ServicePointManager.Expect100Continue = true;
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
I am writing an MVC application which needs to request owner names for ip addresses from ARIN.net. Here is the snippet of program code that I have written to do this:
.
.
.
string requestUrl = "http://whois.arin.net/rest/ip/17.151.229.4";
WebResponse response = null;
WebRequest request = WebRequest.Create(requestUrl);
request.Proxy.Credentials = CredentialCache.DefaultCredentials;
response = request.GetResponse();
StreamReader sr = new StreamReader(response.GetResponseStream());
XElement responseElmn = XElement.Parse(sr.ReadToEnd());
.
.
.
This snippet of code is successfully able to send a request to http://whois.arin.net/rest/ip/17.151.229.4 and receive the appropriate response when it is run from a console application on my machine. However, when I attempt to put this snippet of code in my MVC application, I get an exception stating
A connection attempt failed because the connected party did not
properly respond after a period of time, or established connection
failed because connected host has failed to respond .
My local machine, where these applications run, is inside the network of a very large corporation and therefore this snippet must send its request to ARIN through a proxy server when it is run by the previously mentioned applications. I believe that I'm probably receiving this discrepancy in results due to the console application running under a different user than the MVC application. I'm running both applications in debug mode in Visual Studio 2013. The MVC application is hosted by IIS Express when it is run in debug mode.
My questions are:
How can I find out what user the console application and the MVC application are run under?
How can I configure IIS Express to run the MVC application under a different user?
I have been unable to find answers to the questions in my research, any help is appreciated.
I discovered the cause of the problem. The MVC application didn't have a proxy server assigned to the proxy object member of the WebRequest instance by default, while the one in the console application did.
I therefore had to assign the proxy server to the proxy object instance of the WebRequest instance in my code before attempting to retrieve a response:
string requestUrl = "http://whois.arin.net/rest/ip/17.151.229.4";
WebResponse response = null;
WebRequest request = WebRequest.Create(requestUrl);
Uri newUri = new Uri("http://proxy.bigcorp.com:8080");
WebProxy myProxy = new WebProxy(newUri);
request.Proxy = myProxy;
request.Proxy.Credentials = CredentialCache.DefaultCredentials;
response = request.GetResponse();
StreamReader sr = new StreamReader(response.GetResponseStream());
XElement responseElmn = XElement.Parse(sr.ReadToEnd());
Thank you Brendan Green for your help!
So, I have a TFS server at http://mytfsserver:8080. I'm connected to it fine from visual studio doing all the usual TFSy things without any issue at all.
I'm trying to connect from code though - I do the following:
tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("http://mytfsserver:8080"));
tfs.EnsureAuthenticated();
But I get a TeamFoundationServiceUnavailableException.
I'm not connecting to my server in any funny ways, so what is different about what I'm doing to what VS does when it connects?
You just need to add the collection name at the end of the Uri
var tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(
new Uri("http://TFS:8080/TFS/DefaultCollection"));
Try adding /tfs to your server URI.
var tfsServerUri = new Uri("http://mytfsserver:8080/tfs");
var tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(tfsServerUri);
tfs.EnsureAuthenticated();