Skip to content
This repository has been archived by the owner on Oct 4, 2021. It is now read-only.

VSTS organization URL helper samples #162

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 42 additions & 30 deletions ClientLibrary/Quickstarts/netcore/ShowWorkItemConsole/Program.cs
Original file line number Diff line number Diff line change
@@ -1,51 +1,63 @@
using Microsoft.TeamFoundation.WorkItemTracking.WebApi;
using System;
using System.Threading.Tasks;
using Microsoft.TeamFoundation.WorkItemTracking.WebApi;
using Microsoft.TeamFoundation.WorkItemTracking.WebApi.Models;
using Microsoft.VisualStudio.Services.Common;
using Microsoft.VisualStudio.Services.WebApi;
using System;

namespace ConsoleApp
namespace ShowWorkItemConsole
{
/// <summary>
/// Simple console program that shows information about a VSTS work item.
///
/// Usage:
/// ShowWorkItemConsole [organizationName] [personalAccessToken] [workItemNumber]
/// </summary>
class Program
{
static void Main(string[] args)
{
if (args.Length == 3)
{
Uri accountUri = new Uri(args[0]); // Account URL, for example: https://fabrikam.visualstudio.com
String personalAccessToken = args[1]; // See https://www.visualstudio.com/docs/integrate/get-started/authentication/pats
int workItemId = int.Parse(args[2]); // ID of a work item, for example: 12
string organizationName = args[0]; // Organization (formerly called "account") name, for example: "fabrikam"
string accessToken = args[1]; // Personal access token. See https://docs.microsoft.com/vsts/integrate/get-started/authentication/pats?view=vsts
int workItemId = int.Parse(args[2]); // Work item ID, for example: 12

// Create a connection to the account
VssConnection connection = new VssConnection(accountUri, new VssBasicCredential(string.Empty, personalAccessToken));

// Get an instance of the work item tracking client
WorkItemTrackingHttpClient witClient = connection.GetClient<WorkItemTrackingHttpClient>();
try
{
WorkItem workitem = GetWorkItem(organizationName, accessToken, workItemId).GetAwaiter().GetResult();

try
// Output the work item's field values
foreach (var field in workitem.Fields)
{
// Get the specified work item
WorkItem workitem = witClient.GetWorkItemAsync(workItemId).Result;

// Output the work item's field values
foreach (var field in workitem.Fields)
{
Console.WriteLine(" {0}: {1}", field.Key, field.Value);
}
Console.WriteLine($" {field.Key}: {field.Value}");
}
catch (AggregateException aex)
}
catch (AggregateException aex)
{
VssServiceException vssex = aex.InnerException as VssServiceException;
if (vssex != null)
{
VssServiceException vssex = aex.InnerException as VssServiceException;
if (vssex != null)
{
Console.WriteLine(vssex.Message);
}
Console.WriteLine(vssex.Message);
}
}
else
catch (Exception ex)
{
Console.WriteLine("Usage: ConsoleApp {accountUri} {personalAccessToken} {workItemId}");
Console.WriteLine("Exception occurred: " + ex.Message);
}
}

static async Task<WorkItem> GetWorkItem(string organizationName, string accessToken, int workItemId)
{
// Get the connection URL for the specified VSTS organization name
Uri organizationUrl = await VssConnectionHelper.GetOrganizationUrlAsync(organizationName);

// Create a connection to the organization
VssConnection connection = new VssConnection(organizationUrl, new VssBasicCredential(string.Empty, accessToken));

// Get an instance of the work item tracking client
WorkItemTrackingHttpClient witClient = connection.GetClient<WorkItemTrackingHttpClient>();

// Make the call and return the work item
return await witClient.GetWorkItemAsync(workItemId);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ This sample shows how to use the Work Item Tracking client, but other clients (b

## How to run

1. If you do not already have a Visual Studio Team Services account, [create one](https://docs.microsoft.com/vsts/organizations/accounts/create-account-msa-or-work-student?view=vsts) (it's free)
1. If you do not already have a Visual Studio Team Services account, [create one](https://docs.microsoft.com/vsts/organizations/accounts/create-organization-msa-or-work-student?view=vsts) (it's free)

2. Create a work item in your account

3. Create a personal access token ([steps](https://docs.microsoft.com/vsts/organizations/accounts/use-personal-access-tokens-to-authenticate?view=vsts))

4. Install [.NET SDK (2.0 or later)](https://microsoft.com/net/core)

5. Build `dotnet build`
> Note: you may see warnings about certain dependencies not being fully compatible with the project. This is expected and is due to some dependencies not explicitly listing .NET Standard or .NET Core as a supported framework.

6. Run `dotnet run https://{account}.visualstudio.com {token} {workItemId}` (substituting these values for your account name, your personal access token, and a valid work item ID)
6. Run `dotnet run {organizationName} {token} {workItemId}` (substituting these values for your VSTS organization name, your personal access token, and a valid work item ID)
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.TeamFoundationServer.Client" Version="16.137.0-preview" />
<PackageReference Include="Microsoft.TeamFoundationServer.Client" Version="16.139.0-preview" />
</ItemGroup>

</Project>
11 changes: 11 additions & 0 deletions Helpers/Helpers.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.6" />
</ItemGroup>

</Project>
57 changes: 57 additions & 0 deletions Helpers/OrganizationUrlHelpers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;

namespace Samples.Helpers
{
/// <summary>
/// Helper methods for building URLs to VSTS organization ("account") resources using just a name or ID.
/// </summmary>
public static class OrganizationUrlHelpers
{
/// <summary>
/// Gets the connection URL for the specified VSTS organization name.
/// </summary>
public static async Task<Uri> GetUrl(string organizationName)
{
string requestUrl = $"{s_locationServiceUrl}/_apis/resourceAreas/{s_defaultResourceAreaId}/?accountName={organizationName}&api-version=5.0-preview.1";

HttpResponseMessage response = await s_client.GetAsync(requestUrl);

return await ExtractLocationUrl(response);
}

/// <summary>
/// Gets the connection URL for the specified VSTS organization ID.
/// </summary>
public static async Task<Uri> GetUrl(Guid organizationId)
{
string requestUrl = $"{s_locationServiceUrl}/_apis/resourceAreas/{s_defaultResourceAreaId}/?hostid={organizationId}&api-version=5.0-preview.1";

HttpResponseMessage response = await s_client.GetAsync(requestUrl);

return await ExtractLocationUrl(response);
}

private static async Task<Uri> ExtractLocationUrl(HttpResponseMessage response)
{
if (response.StatusCode == HttpStatusCode.OK)
{
var resourceArea = await response.Content.ReadAsAsync<JObject>();

if (resourceArea != null)
{
return new Uri(resourceArea["locationUrl"].ToString());
}
}

return null;
}

private static readonly HttpClient s_client = new HttpClient();
private static readonly string s_locationServiceUrl = "https://app.vssps.visualstudio.com";
private static readonly Guid s_defaultResourceAreaId = Guid.Parse("79134C72-4A58-4B42-976C-04E7115F32BF");
}
}
37 changes: 37 additions & 0 deletions Helpers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Helpers

This project include various useful "helper" samples.

## OrganizationUrlHelpers

Provides sample helper methods for properly constructing URLs to VSTS organizations (formerly "account") using an organization ID or name.

### Get the URL for a VSTS organization (by name)

```cs
public async Task DoSomething()
{
Uri orgUrl = Samples.Helpers.OrganizationUrlHelpers
.GetUrl("myOrgName"); // https://myorgname.visualstudio.com

HttpClient client = new HttpClient();

await client.GetAsync(orgUrl);
}
```

### Get the URL for a VSTS organization (by ID)

```cs
public async Task DoSomething()
{
Guid orgId = Guid.Parse("279ed1c4-2f72-4e61-8c95-4bafcc13fd02"); // ID for the "myOrgName" organzation

Uri orgUrl = Samples.Helpers.OrganizationUrlHelpers
.GetUrl(orgId); // https://myorgname.visualstudio.com

HttpClient client = new HttpClient();

await client.GetAsync(orgUrl);
}
```