1

I need to get (not download) the content from 10.000~ manifest files within a project in Azure DevOps, but I don't manage to achieve this. I have found several ways to retrieve the content from one file at a time, but in this context, it is neither an efficient nor sustainable solution. I have managed to retrieve all files of a particular file type by checking if the file path ends with the name of the file, then using the TfvcHttpClientBase.GetItemsBatch method. However, this method does not return the item's content.

Program.cs

using Microsoft.TeamFoundation.SourceControl.WebApi;

AzureRest azureRest = new AzureRest();
var tfvcItems = azureRest.GetTfvcItems();
List<TfvcItemDescriptor> itemDescriptorsList = new List<TfvcItemDescriptor>();
foreach(var item in tfvcItems)
{
//Example manifest file .NET
    if (item.Path.EndsWith("packages.config"))
    {
            var itemDescriptor = new TfvcItemDescriptor()
            {
                Path = item.Path,
                RecursionLevel = VersionControlRecursionType.None,
                Version = "",
                VersionOption = TfvcVersionOption.None,
                VersionType = TfvcVersionType.Latest
            };
            itemDescriptorsList.Add(itemDescriptor);
    }
}
TfvcItemDescriptor[] itemDescriptorsArray = itemDescriptorsList.ToArray();
var itemBatch = azureRest.GetTfvcItemsBatch(itemDescriptorsArray);
foreach(var itemList in itemBatch)
{
    foreach(var itemListList in itemList)
    {
        Console.WriteLine("Content: " + itemListList.Content); //empty/null
        Console.WriteLine("ContentMetadata: " + itemListList.ContentMetadata); //not empty/null
    }
}

AzureRest.cs

using Microsoft.TeamFoundation.SourceControl.WebApi;
using Microsoft.VisualStudio.Services.Common;
using Microsoft.VisualStudio.Services.WebApi;
public class AzureRest
    {
        const string ORG_URL = "https://org/url/url";
        const string PROJECT = "Project";
        const string PAT = "PersonalAccessToken";

        private string GetTokenConfig()
        {
            return PAT;
        }

        private string GetProjectNameConfig()
        {
            return PROJECT;
        }

        private VssConnection Authenticate()
        {
            string token = GetTokenConfig();
            string projectName = GetProjectNameConfig();
            var credentials = new VssBasicCredential(string.Empty, token);
            var connection = new VssConnection(new Uri(ORG_URL), credentials);
            return connection;
        }
        public List<TfvcItem> GetTfvcItems()
        {
            var connection = Authenticate();
            using (TfvcHttpClient tfvcClient = connection.GetClient<TfvcHttpClient>())
            {
                var tfvcItems = tfvcClient.GetItemsAsync(scopePath: "/Path", recursionLevel: VersionControlRecursionType.Full, true).Result;
                return tfvcItems;
            }
        }
        public List<List<TfvcItem>> GetTfvcItemsBatch(TfvcItemDescriptor[] itemDescriptors)
        {
            TfvcItemRequestData requestData = new TfvcItemRequestData()
            {
                IncludeContentMetadata = true,
                IncludeLinks = true,
                ItemDescriptors = itemDescriptors
            };
            var connection = Authenticate();
            using (TfvcHttpClient tfvcClient = connection.GetClient<TfvcHttpClient>())
            {
                var tfvcItems = tfvcClient.GetItemsBatchAsync(requestData).Result;
                return tfvcItems;
            }
        }
    }
}
agoSwitch
  • 21
  • 2

1 Answers1

1

For reference:
I have tested the codes you shared and when debugging at "itemDescriptorsList" and have found that there is no content specified in it, so that's why you cannot get the txt content. enter image description here You should first check and add the content property into the "itemDescriptorsList".

RoyWang-MSFT
  • 245
  • 1
  • 3
  • 1
    Thanks for debugging my code. According to the Microsoft documentation, the class TfvcItemDescriptor nor the TfvcItemRequestData class contains a content property. However, TfvcItemDesciptor attributes DataContractAttribute. Is it possible to use this attribute to get the text content? Can you clarify your solution? – agoSwitch Nov 17 '22 at 19:29
  • Thanks to that screenshot I understood what is the correct syntax for ScopePath in the newest SDK i'm using with TfvcHttpClient.GetItemsAsync.. some things are lacking even basic details. It'd be really useful if there was a documented approach to download files using the SDK, the sample I found was logging to console instead of showing how to actually download) – iBobb Jul 15 '23 at 20:20