Download a File using VSTS REST APIs

View API ArticlesAdding yet another post related to Visual Studio Team Services (VSTS) REST APIs, I thought I’d cover an example of how to download a file from a Git repo in VSTS using the REST APIs (I will cover TFVC-based repositories in another post). In the example below, I will be using C# to make the API calls. However, you can use whatever approach makes the most sense for you (e.g. JavaScript, PowerShell, etc.).

If you are new to calling the VSTS REST APIs or you are new to this series of articles then I would recommend on clicking the View API Articles link above to get started.

Rather than spend time on how to authenticate with the VSTS APIs or how to deserialize API results into POCOs, I will simply highlight the API necessary to download the file and show some example code for doing it. Again, refer to the previous articles for more information on authentication and deserialization.

To obtain a file stored within a Git repo in VSTS you make use of the items API. The format of this API looks like this:

https://{instance}/{project}defaultcollection/_apis/git/repositories/{repository}/items?api-version={version}&scopepath={filepath}[&includecontentmetadata={bool}&lastprocessedchange={bool}]

A real-world example of this API (with variable replacement) might look like this:

https://MyAccount.VisualStudio.com/defaultcollection/MyProject/_apis/git/repositories/MyRepo/items?api-version=1.0&scopepath=ReadMe.md

In the above example, I am attempting to download a file named ReadMe.md from a Git repo named MyRepo in the project named MyProject.

In C# this URL can be constructed like this (assume the variables are being passed in via a method call):

var url = $"{authentication.AccountUrl}/{project}/_apis/git/repositories/{repo}/items?api-version=1.0&scopePath={fileToDownload}";

With the properly formatted URL we can then make a call to the API using the WebRequest class. For example:

var request = (HttpWebRequest)WebRequest.Create(address); request.UserAgent = "VSTS-Get"; request.Headers.Set(HttpRequestHeader.Authorization, GetAuthenticationHeaderValue(
authentication).ToString()); request.ContentType = "application/json"; request.Method = httpMethod; response = (HttpWebResponse)request.GetResponse();

The GetAuthenticationHeaderValue is simply the Base64-encoded credentials (e.g. Alternate Credentials or a Personal Access Token) that will be used for authentication (refer to the aforementioned articles for more details). Once the call is made in the last line of the above example, we are left with an HttpWebResponse object that can be used to stream the contents of the requested file.

Using the HttpWebResponse object we can obtain a Stream object that we can then use to write out the API results to a local file. For example:

using (var responseStream = GetResponseStream(response))
{     var fileName = Path.Get Filename(fileToDownload ?? "");     using (var fileStream = File.Create(Path.Combine(destination, fileName)))     {         responseStream.CopyTo(fileStream);     }
}

In the above example, we create a new FileStream object that can be used to save the contents of the Stream object we obtained from HttpWebRequest. In simple terms, we call the items API, use the resulting Stream object to stream the contents of the requested file to a newly created FileStream object to store the contents of the file locally.

The nice thing about this particular API is that it’s very simple to implement. There is no need to deserialize the API call into an entity/model. You simply store off the results of the call as a local file.

Also, since this API can be utilized with streams, you make use of other types of streams, such as the MemoryStream, if you don’t want to actually store the file on secondary storage.

So, if you have a need to pull one or more files down from a Git repo but don’t want to actually make use of Git, you can create a simple C# (or PowerShell, VB.NET, etc.) program to do it for you.

In an up-coming post, I will show how to pull down entire folders. Enjoy!

Related Posts