TFS REST API .NET Client, TFS2017, Personal Access Token: "You must pass a valid patch document in the body of the request."

Viewed 1421

I use Microsoft.VisualStudio.Services.Client for connecting to TFS/VSTS with different credentials in order to update work items.

In a case when I connect to TFS2017 on premisses and use Personal Access Tokens (PAT), the work item creatin update fails with:

You must pass a valid patch document in the body of the request.

All GET requests work fine though.

The same scenario works if I connect to VSTS (even with PAT) and also when I connect to TFS2017 with NTLM credentials.

Checking it with Fiddler, the problem seems to be, that for this scenario, TFS2017 sends an authentication challenge for every request (for VSTS it only sends it for the first and then just passes in the session id).

The .NET Client sends the proper patch document as the content of the first POST/PATCH request, but it does not include the content again when it responds to the authentication challenge. So the content of the second request is empty and this triggers the "You must pass a valid patch document in the body of the request." at the end.

I have tried it with different authentication ways, but it is all the same, GET requests work (so the auth works in general), but updates not:

  • new VssBasicCredential(string.Empty, pat)
  • new VssCredentials(new WindowsCredential(new NetworkCredential(string.Empty, pat)))

I think it works for VSTS, because there the authentication challenge only for the first (GET) request, and not for the POST/PATCH requests later.

Any hints about how to get this scenario working?

2 Answers

I do everything with Microsoft.TeamfoundationServer.Client+Microsoft.AspNet.WebApi.Client now. There are HTTPClients for all TFS/VSTS Services. I used to develop my own client because the library wasn't that big in april. I remember having kind of the same issues with authentication. I used to login with:

credentials = new VssCredentials(useDefaultCredentials: true);
connection = new VssConnection(new Uri(uriString), credentials);

I used to get the HttpMessageHandler from the connection and so on. The clue on getting the authentication right was loging in first via VS or browser.

The other way was to give the correct authentication into the HttpClient.

It worked with POST and GET.

My Setup ist a TFS2015 and VS2017. I hope this helps you somehow

For the record, if someone runs into the same problem: it seems that personal access tokens (PAT) can only be used the connection is secure (uses https). This is somewhat understandable, but not clear always from the error message.

Related