Skip to content

Commit 91721ff

Browse files
authored
Merge pull request #5 from Microsoft/users/jmarks/Fixes
Add consistency to samples
2 parents 33ca7fb + d910009 commit 91721ff

File tree

13 files changed

+217
-197
lines changed

13 files changed

+217
-197
lines changed
Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,29 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Linq;
4-
using System.Text;
5-
using System.Threading.Tasks;
6-
using Microsoft.TeamFoundation.WorkItemTracking.WebApi;
1+
using Microsoft.TeamFoundation.WorkItemTracking.WebApi;
72
using Microsoft.TeamFoundation.WorkItemTracking.WebApi.Models;
83
using Microsoft.VisualStudio.Services.Client;
94
using Microsoft.VisualStudio.Services.Common;
105
using Microsoft.VisualStudio.Services.WebApi;
6+
using System;
7+
using System.Linq;
118

129
namespace ClientLibraryConsoleAppSample
1310
{
1411
class Program
1512
{
13+
//============= Config [Edit these with your settings] =====================
14+
internal const string vstsCollectionUrl = "https://myaccount.visualstudio.com"; //change to the URL of your VSTS account; NOTE: This must use HTTPS
15+
// internal const string vstsCollectioUrl = "http://myserver:8080/tfs/DefaultCollection" alternate URL for a TFS collection
16+
//==========================================================================
17+
1618
//Console application to execute a user defined work item query
1719
static void Main(string[] args)
1820
{
19-
//=========== Config [edit these] ===================
20-
string collectionUri = "https://fabrikam-fiber-inc.visualstudio.com";
21-
Wiql query = new Wiql() { Query = "Select [State], [Title] from WorkItems where [Work Item Type] = 'Bug' And [Tags] Contains 'findMe'" };
22-
//===================================================
23-
24-
//Prompt user for credential for collection specified above
25-
VssCredentials cred = new VssClientCredentials(false);
26-
cred.PromptType = CredentialPromptType.PromptIfNeeded;
27-
VssConnection connection = new VssConnection(new Uri(collectionUri), cred);
21+
//Prompt user for credential
22+
VssConnection connection = new VssConnection(new Uri(vstsCollectionUrl), new VssClientCredentials());
2823

2924
//create http client and query for resutls
3025
WorkItemTrackingHttpClient witClient = connection.GetClient<WorkItemTrackingHttpClient>();
26+
Wiql query = new Wiql() { Query = "SELECT [Id], [Title], [State] FROM workitems WHERE [Work Item Type] = 'Bug' AND [Assigned To] = @Me" };
3127
WorkItemQueryResult queryResults = witClient.QueryByWiqlAsync(query).Result;
3228

3329
//Display reults in console
@@ -42,13 +38,6 @@ static void Main(string[] args)
4238
Console.WriteLine(item.Id);
4339
}
4440
}
45-
46-
//prevetns console from closing
47-
while (true)
48-
{
49-
50-
}
51-
5241
}
5342
}
5443
}

ClientLibraryConsoleAppSample/README.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ git clone https://github.com/Microsoft/vsts-auth-samples.git
1717

1818
1. Navigate to the sample in cloned repo `vsts-auth-samples/ClientLibraryConsoleAppSample/`
1919
2. Use [Nuget package restore](https://docs.microsoft.com/en-us/nuget/consume-packages/package-restore) to ensure you have all dependencies installed
20-
3. Open the solution file `ClientLibraryConsoleAppSample.sln` in [Visual Studio IDE 2017](https://www.visualstudio.com/downloads/)
21-
4. Open CS file `Program.cs` and there will be 2 input fields:
22-
* `collectionUri` - Mutable value. This is the url to your VSTS/TFS account.
23-
* `query` - Mutable value. This is the WIQL query you want to execute. Replace this with any query you want to execute.
20+
3. Open the solution file `ClientLibraryConsoleAppSample.csproj` in [Visual Studio 2017](https://www.visualstudio.com/downloads/)
21+
4. Open CS file `Program.cs` and there is a section with input values to change at the top of the class:
22+
* `vstsCollectionUrl` - Mutable value. This is the url to your VSTS/TFS collection, e.g. http://myaccount.visualstudio.com for VSTS or http://myserver:8080/tfs/DefaultCollection for TFS.
2423
5. Build and run solution. After running you should see a list of the IDs all work items which match your query restrictions.

DeviceProfileSample/App.config

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<configuration>
3+
<startup>
4+
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
5+
</startup>
6+
</configuration>
Lines changed: 67 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,73 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
2-
3-
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
4-
<OutputType>exe</OutputType>
5-
</PropertyGroup>
6-
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
74
<PropertyGroup>
8-
<Description>DirSearcherClient Console Application</Description>
9-
<Authors>Vittorio</Authors>
10-
<TargetFramework>netcoreapp1.0</TargetFramework>
5+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
6+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
7+
<ProjectGuid>{4B81F1A9-4A60-4793-ABEE-85546AAA480E}</ProjectGuid>
8+
<OutputType>Exe</OutputType>
9+
<AppDesignerFolder>Properties</AppDesignerFolder>
10+
<RootNamespace>DeviceProfileSample</RootNamespace>
1111
<AssemblyName>DeviceProfileSample</AssemblyName>
12-
<PackageId>DirSearcherClient</PackageId>
13-
<GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
14-
<GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>
15-
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
16-
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
17-
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
18-
<GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
19-
<ApplicationIcon />
20-
<OutputTypeEx>exe</OutputTypeEx>
21-
<StartupObject />
12+
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
13+
<FileAlignment>512</FileAlignment>
14+
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
15+
</PropertyGroup>
16+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
17+
<PlatformTarget>AnyCPU</PlatformTarget>
18+
<DebugSymbols>true</DebugSymbols>
19+
<DebugType>full</DebugType>
20+
<Optimize>false</Optimize>
21+
<OutputPath>bin\Debug\</OutputPath>
22+
<DefineConstants>DEBUG;TRACE</DefineConstants>
23+
<ErrorReport>prompt</ErrorReport>
24+
<WarningLevel>4</WarningLevel>
25+
</PropertyGroup>
26+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
27+
<PlatformTarget>AnyCPU</PlatformTarget>
28+
<DebugType>pdbonly</DebugType>
29+
<Optimize>true</Optimize>
30+
<OutputPath>bin\Release\</OutputPath>
31+
<DefineConstants>TRACE</DefineConstants>
32+
<ErrorReport>prompt</ErrorReport>
33+
<WarningLevel>4</WarningLevel>
2234
</PropertyGroup>
23-
2435
<ItemGroup>
25-
<PackageReference Include="Microsoft.IdentityModel.Clients.ActiveDirectory" Version="3.13.8" />
26-
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
36+
<Reference Include="Microsoft.IdentityModel.Clients.ActiveDirectory, Version=3.14.1.10, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
37+
<HintPath>packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.14.1\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll</HintPath>
38+
<Private>True</Private>
39+
</Reference>
40+
<Reference Include="Microsoft.IdentityModel.Clients.ActiveDirectory.Platform, Version=3.14.1.10, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
41+
<HintPath>packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.14.1\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll</HintPath>
42+
<Private>True</Private>
43+
</Reference>
44+
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
45+
<HintPath>packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
46+
<Private>True</Private>
47+
</Reference>
48+
<Reference Include="System" />
49+
<Reference Include="System.Core" />
50+
<Reference Include="System.Xml.Linq" />
51+
<Reference Include="System.Data.DataSetExtensions" />
52+
<Reference Include="Microsoft.CSharp" />
53+
<Reference Include="System.Data" />
54+
<Reference Include="System.Net.Http" />
55+
<Reference Include="System.Xml" />
2756
</ItemGroup>
28-
29-
<ItemGroup Condition=" '$(TargetFramework)' == 'dnxcore50' ">
30-
<PackageReference Include="Microsoft.CSharp" Version="4.0.1" />
31-
<PackageReference Include="System.Collections" Version="4.0.11" />
32-
<PackageReference Include="System.Console" Version="4.0.0" />
33-
<PackageReference Include="System.Linq" Version="4.1.0" />
34-
<PackageReference Include="System.Threading" Version="4.0.11" />
35-
<PackageReference Include="System.Net.Http" Version="4.1.1" />
57+
<ItemGroup>
58+
<Compile Include="Program.cs" />
59+
<Compile Include="Properties\AssemblyInfo.cs" />
60+
</ItemGroup>
61+
<ItemGroup>
62+
<None Include="App.config" />
63+
<None Include="packages.config" />
3664
</ItemGroup>
37-
38-
</Project>
65+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
66+
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
67+
Other similar extension points exist, see Microsoft.Common.targets.
68+
<Target Name="BeforeBuild">
69+
</Target>
70+
<Target Name="AfterBuild">
71+
</Target>
72+
-->
73+
</Project>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio 14
4+
VisualStudioVersion = 14.0.25420.1
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DeviceProfileSample", "DeviceProfileSample.csproj", "{4B81F1A9-4A60-4793-ABEE-85546AAA480E}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{4B81F1A9-4A60-4793-ABEE-85546AAA480E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{4B81F1A9-4A60-4793-ABEE-85546AAA480E}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{4B81F1A9-4A60-4793-ABEE-85546AAA480E}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{4B81F1A9-4A60-4793-ABEE-85546AAA480E}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
EndGlobal

DeviceProfileSample/Program.cs

Lines changed: 50 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -13,106 +13,83 @@ namespace DeviceProfileSample
1313
{
1414
public class Program
1515
{
16-
public const string resource_vsts = "499b84ac-1321-427f-aa17-267ca6975798";
17-
public const string clientId_vs = "872cd9fa-d31f-45e0-9eab-6e460a02d1f1";
18-
public static void Main(string[] args)
19-
{
20-
//============= Config [Edit these with your settings] =====================
21-
var vstsAccountUri = "https://mseng.VisualStudio.com";
22-
var restEndpoint = "_apis/projects?api-version=2.0";
23-
//==========================================================================
16+
//============= Config [Edit these with your settings] =====================
17+
internal const string vstsCollectionUrl = "https://myaccount.visualstudio.com"; //change to the URL of your VSTS account; NOTE: This must use HTTPS
18+
//==========================================================================
2419

25-
UserData(vstsAccountUri,restEndpoint);
20+
internal const string VSTSResourceId = "499b84ac-1321-427f-aa17-267ca6975798"; //Static value to target VSTS. Do not change
21+
internal const string clientId = "872cd9fa-d31f-45e0-9eab-6e460a02d1f1"; //VS ClientId. Please use this instead of your app's clientId
2622

27-
//prevents console from closing immediately at the end of output
28-
Console.ReadLine();
29-
}
30-
31-
static void UserData(string vstsAccountUri, string restEndpoint)
23+
public static void Main(string[] args)
3224
{
33-
//get auth token
34-
AuthenticationResult result = GetToken(null);
35-
var authHeader = new AuthenticationHeaderValue("Bearer", result.AccessToken);
36-
37-
//call VSTS REST API
38-
using (var client = new HttpClient())
25+
AuthenticationContext ctx = GetAuthenticationContext(null);
26+
AuthenticationResult result = null;
27+
try
3928
{
40-
client.BaseAddress = new Uri(vstsAccountUri);
41-
client.DefaultRequestHeaders.Accept.Clear();
42-
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
43-
client.DefaultRequestHeaders.Add("User-Agent", "VstsRestApiSamples");
44-
client.DefaultRequestHeaders.Add("X-TFS-FedAuthRedirect", "Suppress");
45-
client.DefaultRequestHeaders.Authorization = authHeader;
46-
47-
//connect to REST endpoint
48-
HttpResponseMessage response = client.GetAsync(restEndpoint).Result;
29+
DeviceCodeResult codeResult = ctx.AcquireDeviceCodeAsync(VSTSResourceId, clientId).Result;
30+
Console.WriteLine("You need to sign in.");
31+
Console.WriteLine("Message: " + codeResult.Message + "\n");
32+
result = ctx.AcquireTokenByDeviceCodeAsync(codeResult).Result;
4933

50-
if (response.IsSuccessStatusCode)
51-
{
52-
Console.WriteLine("\tSuccessful REST call\n");
53-
Console.WriteLine(response.Content.ReadAsStringAsync().Result);
54-
}
55-
else
56-
{
57-
Console.WriteLine("{0}:{1}", response.StatusCode, response.ReasonPhrase);
58-
}
34+
var bearerAuthHeader = new AuthenticationHeaderValue("Bearer", result.AccessToken);
35+
ListProjects(bearerAuthHeader);
36+
}
37+
catch (Exception ex)
38+
{
39+
Console.ForegroundColor = ConsoleColor.Red;
40+
Console.WriteLine("Something went wrong.");
41+
Console.WriteLine("Message: " + ex.Message + "\n");
5942
}
6043
}
6144

62-
static AuthenticationResult GetToken(string tenant)
45+
private static AuthenticationContext GetAuthenticationContext(string tenant)
6346
{
6447
AuthenticationContext ctx = null;
6548
if (tenant != null)
6649
ctx = new AuthenticationContext("https://login.microsoftonline.com/" + tenant);
6750
else
6851
{
69-
ctx = new AuthenticationContext("https://login.microsoftonline.com/common");
52+
ctx = new AuthenticationContext("https://login.windows.net/common");
7053
if (ctx.TokenCache.Count > 0)
7154
{
7255
string homeTenant = ctx.TokenCache.ReadItems().First().TenantId;
7356
ctx = new AuthenticationContext("https://login.microsoftonline.com/" + homeTenant);
7457
}
7558
}
76-
AuthenticationResult result = null;
77-
try
78-
{
79-
result = ctx.AcquireTokenSilentAsync(resource_vsts, clientId_vs).Result;
80-
}
81-
catch (Exception exc)
59+
60+
return ctx;
61+
}
62+
63+
private static void ListProjects(AuthenticationHeaderValue authHeader)
64+
{
65+
// use the httpclient
66+
using (var client = new HttpClient())
8267
{
83-
var adalEx = exc.InnerException as AdalException;
84-
if ((adalEx != null) && (adalEx.ErrorCode == "failed_to_acquire_token_silently"))
68+
client.BaseAddress = new Uri(vstsCollectionUrl);
69+
client.DefaultRequestHeaders.Accept.Clear();
70+
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
71+
client.DefaultRequestHeaders.Add("User-Agent", "VstsRestApiSamples");
72+
client.DefaultRequestHeaders.Add("X-TFS-FedAuthRedirect", "Suppress");
73+
client.DefaultRequestHeaders.Authorization = authHeader;
74+
75+
// connect to the REST endpoint
76+
HttpResponseMessage response = client.GetAsync("_apis/projects?stateFilter=All&api-version=2.2").Result;
77+
78+
// check to see if we have a succesfull respond
79+
if (response.IsSuccessStatusCode)
80+
{
81+
Console.WriteLine("\tSuccesful REST call");
82+
Console.WriteLine(response.Content.ReadAsStringAsync().Result);
83+
}
84+
else if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
8585
{
86-
result = GetTokenViaCode(ctx);
86+
throw new UnauthorizedAccessException();
8787
}
8888
else
8989
{
90-
Console.ForegroundColor = ConsoleColor.Red;
91-
Console.WriteLine("Something went wrong.");
92-
Console.WriteLine("Message: " + exc.InnerException.Message + "\n");
90+
Console.WriteLine("{0}:{1}", response.StatusCode, response.ReasonPhrase);
9391
}
9492
}
95-
return result;
96-
}
97-
98-
static AuthenticationResult GetTokenViaCode(AuthenticationContext ctx)
99-
{
100-
AuthenticationResult result = null;
101-
try
102-
{
103-
DeviceCodeResult codeResult = ctx.AcquireDeviceCodeAsync(resource_vsts, clientId_vs).Result;
104-
Console.ResetColor();
105-
Console.WriteLine("You need to sign in.");
106-
Console.WriteLine("Message: " + codeResult.Message + "\n");
107-
result = ctx.AcquireTokenByDeviceCodeAsync(codeResult).Result;
108-
}
109-
catch (Exception exc)
110-
{
111-
Console.ForegroundColor = ConsoleColor.Red;
112-
Console.WriteLine("Something went wrong.");
113-
Console.WriteLine("Message: " + exc.Message + "\n");
114-
}
115-
return result;
11693
}
11794
}
11895
}

0 commit comments

Comments
 (0)