Coder Social home page Coder Social logo

microsoft / azure-devops-dotnet-samples Goto Github PK

View Code? Open in Web Editor NEW
512.0 71.0 507.0 1.4 MB

.NET/C# samples for integrating with Azure DevOps Services and Azure DevOps Server

Home Page: https://docs.microsoft.com/azure/devops/integrate

License: MIT License

C# 100.00%
microsoft samples visual-studio-team-services azure-devops dotnet csharp

azure-devops-dotnet-samples's Introduction

.NET samples for Azure DevOps

Build Status

This repository contains C# samples that show how to integrate with Azure DevOps Services and Azure using our public client libraries, service hooks, and more.

Explore the samples

Take a minute to explore the repo. It contains short as well as longer examples that demonstrate how to integrate with Azure DevOps Services and Azure DevOps Server.

In the ClientLibrary folder, you'll find the following:

  • Samples: short reusable code blocks demonstrating how to call specific APIs.
  • Quickstarts: self-contained programs demonstrating a specific scenario, typically by calling multiple APIs.

About the official client libraries

For .NET developers, the primary (and highly recommended) way to integrate with Azure DevOps Services and Azure DevOps Server is via our public .NET client libraries available on Nuget. Microsoft.TeamFoundationServer.Client is the most popular Nuget package and contains clients for interacting with work item tracking, Git, version control, build, release management and other services.

See the Azure DevOps client library documentation for more details.

Sample console program

Simple console program that connects to Azure DevOps using a personal access token and displays the field values of a work item.

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;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length == 3)
            {
                Uri orgUrl = new Uri(args[0]);         // Organization URL, for example: https://dev.azure.com/fabrikam               
                String personalAccessToken = args[1];  // See https://docs.microsoft.com/azure/devops/integrate/get-started/authentication/pats
                int workItemId = int.Parse(args[2]);   // ID of a work item, for example: 12

                // Create a connection
                VssConnection connection = new VssConnection(orgUrl, new VssBasicCredential(string.Empty, personalAccessToken));

                // Show details a work item
                ShowWorkItemDetails(connection, workItemId).Wait();
            }
            else
            {
                Console.WriteLine("Usage: ConsoleApp {orgUrl} {personalAccessToken} {workItemId}");
            }

        }

        static private async Task ShowWorkItemDetails(VssConnection connection, int workItemId)
        {
            // Get an instance of the work item tracking client
            WorkItemTrackingHttpClient witClient = connection.GetClient<WorkItemTrackingHttpClient>();

            try
            {
                // Get the specified work item
                WorkItem workitem = await witClient.GetWorkItemAsync(workItemId);

                // Output the work item's field values
                foreach (var field in workitem.Fields)
                {
                    Console.WriteLine("  {0}: {1}", field.Key, field.Value);
                }
            }
            catch (AggregateException aex)
            {
                VssServiceException vssex = aex.InnerException as VssServiceException;
                if (vssex != null)
                {
                    Console.WriteLine(vssex.Message);
                }
            }
        }
    }
}

Request other samples

Not finding a sample that demonstrates something you are trying to do? Let us know by opening an issue.

azure-devops-dotnet-samples's People

Contributors

abdulsametileri avatar adriennetacke avatar bansalaseem avatar chandan-anjani avatar danhellem avatar dorchuck avatar giridharannarayanan avatar hostr avatar mmanela avatar msftgits avatar nenoloje avatar niadak avatar nschonni avatar olicea avatar pranavgk avatar shadyysf avatar shayki5 avatar shpraka avatar viradhamms avatar vithati avatar vtbassmatt avatar willsmythe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

azure-devops-dotnet-samples's Issues

How can i get attachment id from WorkItemRelation?

I want to download an attachment on a workitem and I can see that there is a sample for download attachment, but I don't know how to get the attachment GUID from the workitem

var workItem = witClient.GetWorkItemAsync(Convert.ToInt32(id), expand: WorkItemExpand.Relations).Result;
`

                    foreach (var relation in workItem.Relations)
                    {
                        if (relation.Rel == "Hyperlink")
                        {
                            // dont know how to get GUID for attachment
                        }
                    }`

Several WIT samples assume existence of certain work items

Several of the WIT sample methods assume certain work items exist in the target account. This causes 12 separate exceptions during execution of the "wit" area.

If the samples need work items with certain properties to exist, they should arrange for those items to exist.

CommentsSample.GetSingleWorkItemComment (assumes "23")
RecycleBinSample.GetDeletedWorkItem (assumes there's a page of results)
RecycleBinSample.GetMultipledDeletedWorkItems (72, 73, 81)
RecycleBinSample.RestoreWorkItem (page)
RecycleBinSample.RestoreMultipleWorkItems (72, 73, 81)
RecycleBinSample.PermenentlyDeleteMultipleWorkItems (72, 73, 81)
WorkItemsSample.GetWorkItemsWithSpecificFields (assumes a key that's missing)
WorkItemsSample.GetWorkItemsWithLinksAndAttachments (50)
WorkItemsSample.MoveToAnotherProject (page)
WorkItemsSample.UpdateLinkComment (assumes a revision number)
WorkItemsSample.UpdateWorkItemAddHyperLink (id = -1?)
WorkItemsSample.UpdateWorkItemAddCommitLink (assumes revision number)

How to get Release Definition Environment's varables?

var connection = new VssConnection(new Uri(VstsCollectioUrl), new VssClientCredentials());
var releaseClient = connection.GetClient<ReleaseHttpClient>();
var defs = releaseClient.GetReleaseDefinitionsAsync("ProjectName", expand: ReleaseDefinitionExpands.Environments).Result;

I can get release release definitions with their environments expanded, but those environments don't have their variables expanded.

One would hope this would work:

var connection = new VssConnection(new Uri(VstsCollectioUrl), new VssClientCredentials());
var releaseClient = connection.GetClient<ReleaseHttpClient>();
var myEnv = releaseClient.GetDefinitionEnvironmentsAsync("MyProject").Result;

However, it throws an exception because the task group ID was not found (an optional param). I am having trouble locating this ID in TFS, and I cannot find any documentation on the GetDefinitionEnvironmentsAsync method.

Could you add examples of how to logout?

This documentation page on VisualStudio.com describes how to create a Visual Studio sign-in prompt with:

VssConnection connection = new VssConnection(new Uri(collectionUri), new VssClientCredentials());

but I cannot find a sensible way to logout. Could you add an example?

Get Merge Candidates

Is there any way to get a list of changesets when given a source and destination branch? I thought there used to be a call GetMergeCandidates.

When creating an area with child nodes, the child nodes are not created

I followed the example for CreateArea and ran it against my VSTS instance. It creates the parent node, but none of the children.

POST https://MYACCOUNT.visualstudio.com/{guid}/_apis/wit/classificationNodes/Areas​

{"id":0,"identifier":"00000000-0000-0000-0000-000000000000","name":"Third Party Inventory","structureType":"area","children":[{"id":0,"identifier":"00000000-0000-0000-0000-000000000000","name":"Company Profile","structureType":"area","children":null,"attributes":null,"url":null},{"id":0,"identifier":"00000000-0000-0000-0000-000000000000","name":"Business Relationship","structureType":"area","children":null,"attributes":null,"url":null}],"attributes":null,"url":null}

I see the JSON request looks correct, but the response does not include any child nodes (see below) nor does the VSTS web app display any children for the new area node. It's interesting that the REST API docs don't show the ability to add children.

Response:

{"id":1,"identifier":"<guid>","name":"Third Party Inventory","structureType":"area","hasChildren":false,"_links":{"self":{"href":"https://MYACCOUNT.visualstudio.com/{guid}/_apis/wit/classificationNodes/Areas/Third%20Party%20Inventory"},"parent":{"href":"https://MYACCOUNT.visualstudio.com/{guid}/_apis/wit/classificationNodes/Areas"}},"url":"https://MYACCOUNT.visualstudio.com/{guid}/_apis/wit/classificationNodes/Areas/Third%20Party%20Inventory"}

What is the correct way to create sub-areas via the API?

VssRequestTimerTrace P/Invokes into ADVAPI32.DLL

Not sure if this is the best place to report an issue in the base VSTS .NET libraries, but here goes!

We're starting to use the .NET VSTS API at Xamarin for cross-CI integration on macOS and immediately ran into an issue where anything using Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase (e.g. everything) results in an exception when run on macOS (Mono):

[ERROR] FATAL UNHANDLED EXCEPTION: System.DllNotFoundException: ADVAPI32.DLL
  at (wrapper managed-to-native) Microsoft.VisualStudio.Services.WebApi.VssRequestTimerTrace:EventActivityIdControl (int,System.Guid&)
  at Microsoft.VisualStudio.Services.WebApi.VssRequestTimerTrace.TraceRequest (System.Net.Http.HttpRequestMessage message) [0x00028] in <2918af0a6c8945db9347a85022c96b21>:0
  at Microsoft.VisualStudio.Services.WebApi.HttpMessageExtensions.Trace (System.Net.Http.HttpRequestMessage request) [0x0003b] in <2918af0a6c8945db9347a85022c96b21>:0
  at Microsoft.VisualStudio.Services.WebApi.VssHttpClientBase+<SendAsync>d__46.MoveNext () [0x000dd] in <2918af0a6c8945db9347a85022c96b21>:0

It would be great if this call could be avoided on non-Windows systems as it is not necessary to the functionality of the .NET VSTS API at all.

The call is made at the end of VssRequestTimerTrace.TraceRequest (HttpRequestMessage). It'd be great to just guard it with a check against Environment.OSVersion.Platform or similar (e.g. on macOS this will be PlatformID.Unix on Mono and possibly PlatformID.MacOSX on another runtime (.NET Core?)).

I'd probably also guard the call itself as well by catching DllNotFoundException, however an explicit platform check will be much faster than performing the P/Invoke and catching the failure (Mono will attempt to resolve many different patterns of native library names before giving up).

Workaround

As a workaround, I mocked a libADVAPI32.DLL.dylib to ensure the P/Invoke succeeds:

ADVAPI32.c:

unsigned int
EventActivityIdControl (int ControlCode, void *ActivityId)
{
	return 0;
}

Compile:

clang -o libADVAPI32.DLL.dylib ADVAPI32.c -dynamiclib -arch x86_64 -arch i386

Run my test tool:

Build:
  id: 847943
  url: https://abc.visualstudio.com/guid/_apis/build/Builds/847943
  status: NotStarted
  status: InProgress....................................................................................................................................................
  status: Completed
  result: Succeeded
  duration: 00:12:32.0572594

In other words, if we can just avoid this P/Invoke on non-Windows systems, the libraries work (for at least our current use case: build queueing and monitoring) just fine!

Net Core samples?

have any Net Core sample to show?

I try to run in Net Core 2.0 but is not working.

QueriesSample.DeleteQueryOrFolderByPath() should delete a previously created sample query

This sample method is currently deleting a hard-coded query My Queries/Sample, but should instead be deleting a sample query created earlier.

One idea is to reorder the methods you already have ...

  1. Create a sample query (store ID in $sampleQueryId)
  2. Delete the sample query by ID (using $sampleQueryId)
  3. Undelete this query
  4. Delete the same query again by path (likely means setting a $sampleQueryPath context variable in step 1)

JsonSerializationException on converting value when using in WebApi project

I get a

Newtonsoft.Json.JsonSerializationException: Error converting value "Microsoft.IdentityModel.Claims.ClaimsIdentity;{identity}" to type 'Microsoft.VisualStudio.Services.Identity.IdentityDescriptor'. Path 'authenticatedUser.descriptor', line 1, position 188. ---> System.ArgumentException: Could not cast or convert from System.String to Microsoft.VisualStudio.Services.Identity.IdentityDescriptor.

when i'm trying to create a work item in my web api project.

var hostUri = new Uri("TfsAccountUrl");
var connection = new VssConnection(hostUri, new VssBasicCredential(string.Empty, "PAT"));
var workItemClient = await connection.GetClientAsync<WorkItemTrackingHttpClient>();

When i'm using the exact same code in a console application it works fine. I can only guess that this has something to do with my JsonSerializer Settings which are currently so in the web api project:

var jSettings = new JsonSerializerSettings();
var jsonFormatter = httpConfiguration.Formatters.JsonFormatter;
jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
jSettings.Formatting = Formatting.Indented;
jSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
jsonFormatter.Indent = configHelper.Configuration.JsonSerializer.Indent;
jsonFormatter.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc
JsonConvert.DefaultSettings = () => jSettings;

When will the Release APIs be supported in the .NET client library

It appears they are in preview, but having those preview APIs in the .NET client library would be helpful. Any timeline for this?

Specifically, I'm looking for two things that will be set off from a 3rd party service:

  1. Start a Release deployment
  2. Approve/deny a Release deployment

Add group to default team

Is it possible to add group to default team of a project?

I see an API to create project but no API exists to associate project to a team. Or even add members to team. The team API doesn't seem to allow to add members to team.

ProfileHttpClient returns wrong account if signed into both Microsoft Account and Office 365

I couldn't find any other places to file this so if this is not in the right place, let me know and I'll file it elsewhere. This is what appears to be either a bug in the .NET client (version 15.112.1) or in VSTS OAuth itself.

Steps to reproduce:

  1. In your browser, be signed in to both a Microsoft account that has access to one or more VSTS accounts, and also be signed in with a work Office 365 account (perhaps this would happen with Azure AD as well?) that does not have access to any VSTS accounts. In my case, these are two different email addresses.
  2. Initiate the OAuth redirect. On the approval page, asking if you approve giving access to the scopes for this application, notice that it shows your Microsoft account email. Click to approve the request.
  3. After being redirected, the code below executes.
  4. The profile variable contains your Office 365 account information, not your Microsoft account, and any subsequent calls fail (i.e. AccountHttpClient.GetAccountsByMemberAsync returns no results) because your Office 365 account does not have access to any VSTS accounts.

Code:

var vsoBaseUri = new Uri("https://app.vssps.visualstudio.com/");
var credential = new VssOAuthAccessTokenCredential(accessToken);

var profileClient = new ProfileHttpClient(vsoBaseUri, credential);
var profile = await profileClient.GetProfileAsync(new ProfileQueryContext(AttributesScope.Core));

The code above works correctly if you are only signed in with your Microsoft account (and signed out of your Office 365 account).

How to get full work item from a relation?

Using this sample code as a base, how do I get the full contents of each of those related work items?

The only obvious solution to me is to chop the work item ID off the end of the URL, convert it to an integer, and then call workItemTrackingClient.GetWorkItemAsync(id), but I feel like there should be a solution that doesn't involve making assumptions on the format of the URL that comes back.

Sample for retrieving related work items

Existing samples show many example of working with work items. However, the libraries don't support a way to retrieve linked work items, i.e. Parent, Child, Related, etc.

WorkItem.Relations gives us a list of WorkItemRelation. A work item relation gives us only the relation type, and the title for the relation. No id is given for the work item. The closest we have is the Url to work item.

An sample showing how to retrieve a related work item would be most beneficial.

Work item linking samples throws errors

WorkItemsSample.CreateAndLinkToWorkItem throws an exception that "linking to a work item requires the full URL".

WorkItemsSample.LinkToOtherWorkItem throws an exception that "a work item cannot be linked to itself".

That means neither of these samples is actually successful at showing how the APIs work.

Using API to checkin\checkout files to TFVC repos

Hi,
I need to automate some activities by using vsts apis. Basically I need to get files, alter them, and checkin.
First part of the task is covered by TfvcHttpClient that allow me to access to the whole TFVC repository.

There is lot of stuff for git repos, but I cannot move to git.

There is some resources I missed or can you address me to a solution?

Example about approve PR

Hi,
After create a PR, how can I approve the PR and set PR autocompleted?
Is there any smaple code?

TfvcHttpClient: Must specify a text encoding, even if uploading a binary file?

// Notice that ContentType is being set to Base64Encoded.

static async Task<TfvcChangesetRef> AddFile(TfvcHttpClient client, string path, byte[] contentBytes)
{
    var item = new TfvcItem { Path = path };
    var content = new ItemContent { Content = Convert.ToBase64String(contentBytes), ContentType = ItemContentType.Base64Encoded };
    var change = new TfvcChange { ChangeType = VersionControlChangeType.Add, Item = item, NewContent = content };
    var changeset = new TfvcChangeset { Changes = new[] { change } };
    return await client.CreateChangesetAsync(changeset);
}

The sample above results in ArgumentException below, stating that I must either specify an encoding value, or provide base64 encoded content (which I already did).

ArgumentException: An explicit encoding value must be provided when supplying raw text content. Specify a valid text encoding value or provide base64 encoded content.
Parameter name: pathActions.action.encoding

Specifying an encoding in content metadata works around this issue, but this inappropriate unless adding a text file and the encoding is properly detected.

// Must specify a text encoding, even if uploading a binary file?

static async Task<TfvcChangesetRef> AddFile(TfvcHttpClient client, string path, byte[] contentBytes)
{
    var contentMetadata = new FileContentMetadata { Encoding = Encoding.UTF8.CodePage };
    var item = new TfvcItem { Path = path, ContentMetadata = contentMetadata };
    var content = new ItemContent { Content = Convert.ToBase64String(contentBytes), ContentType = ItemContentType.Base64Encoded };
    var change = new TfvcChange { ChangeType = VersionControlChangeType.Add, Item = item, NewContent = content };
    var changeset = new TfvcChangeset { Changes = new[] { change } };
    return await client.CreateChangesetAsync(changeset);
}

Is this expected behavior? What is the purpose/impact of specifying a text encoding when uploading a binary file?

Attachment uploaded using API is unauthorized to read for other users

Repro steps:

  1. Use the API and the code here to upload an attachment and get the attachemntReference.Url and try to get to the url using another user in the team project.

  2. The file should be available but it throws the following back;
    Note: (I have tried PAT & DefaultCredentials in my file uplaod)
    {"$id":"1","innerException":null,"message":"VS402330: Unauthorized Read access to the attachment under the areas ","typeName":"Microsoft.TeamFoundation.WorkItemTracking.Server.WorkItemUnauthorizedAttachmentException, Microsoft.TeamFoundation.WorkItemTracking.Server","typeKey":"WorkItemUnauthorizedAttachmentException","errorCode":0,"eventId":3200}

  3. Also tried the same using the REST calls and still the same behavior.
    Note: The other users I am using are created in the Azure AD on the default domain - ie - [email protected]

CreateChangeset. Maximum request size exceeded.

When i try to check-in several files via API i am getting a following error:
"The maximum request size of 26214400 bytes was exceeded"

I am using a Microsoft.TeamFoundationServer.Client library to make the requests. Here is the URL of the requests taken from Fiddler:
"/tfs/DefaultCollection/_apis/tfvc/changesets"

I guess this limit is specified in some web.config of TFS, but i could not find it. How can i increase the limit?

cannot specify a branch gitClient.GetItemsAsync

I am trying to retrieve items from a specific Branch on a git repo using GetItemsAsync

It looks like I should be able to specify the branch through the GitVersionDescriptor, and by setting the version type to Branch. However, when I do so, I don't retrieve items from the branch I am attempting to get from.

my C# code is like:

GitVersionDescriptor versionDesc = new GitBaseVersionDescriptor()
{ 
   VersionType = GitVersionType.Branch,
   Version = "myBranchNameHere"
}
var task = gitClient.GetItemsAsync(repositoryId: <myrepoid>,
 recursionLevel: VersionControlRecursionType.Full, 
scopePath: "/",
 versionDescriptor: versionDesc);

that all works and I get my Items, however, the Items I get do not match the Branch, the instead come back from the repo's master branch.

Jeff

Getting test results using VSTS rest API

I am using Nodejs for consuming rest API of VSTS
Getting Builds and work items is working fine.

But I am confused about the endpoint which will return me the test results of particular build.
Kindly help me with this.

Tag samples incorrectly checking for null

The samples for "get tag" and the sample for "update tag" show checking for null, but a get call will fail with a TagNotFoundException (and not return null). The update call can likely fails with this exception, but possibly others. There's no case where these APIs return null.

So instead of:

WebApiTagDefinition tag = taggingClient.GetTagAsync(projectId, tagName).Result;
if (tag == null)
{
    ...
}

Do:

try
{
    WebApiTagDefinition tag = taggingClient.GetTagAsync(projectId, tagName).Result;
    ...
}
catch (TagNotFoundException notFoundException)
{
    ...
}

The remote name could not be resolved: 'XXXX.visualstudio.com' Issue with WorkItemTrackingHttpClient

Hi,
I developed one windows service which used your sample code (work item track ) with my personal token, but i got exception which show "the remote name could not be resolved", but it works well durning my debug process this exception only happened when i deploy it on windows service, could you please help me figure out this issue ?

exception happened for below codes :
WorkItemQueryResult workItemQueryResult = workItemTrackingHttpClient.QueryByWiqlAsync(wiql).Result;

stack trace,
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task1.GetResultCore(Boolean waitCompletionNotification) at System.Threading.Tasks.Task1.get_Result()
at TFSataCollectorServices.GetWorkItemService.LoadWorkItems(Int32 numberOfDays, String projectName) in C:\Tom\source_projects\TFSDataCollectorService\TFSDataCollectorServiceV1\TFSataCollectorServices\GetWorkItemService.cs:line 80
at TFSataCollectorServices.GetWorkItemService.SaveAllWorkItems() in C:\Tom\source_projects\TFSDataCollectorService\TFSDataCollectorServiceV1\TFSataCollectorServices\GetWorkItemService.cs:line 133
at TFSDataCollectorServiceV1.TFSWorkItemService.OnTimedEvent(Object source, ElapsedEventArgs e) in C:\Tom\source_projects\TFSDataCollectorService\TFSDataCollectorServiceV1\TFSDataCollectorServiceV1\TFSWorkItemService.cs:line 40
at System.Timers.Timer.MyTimerCallback(Object state)

Need SDK sample for managing Capacity

Is there any facility in the SDK for managing User Capacity in a given Iteration? If so, I'm not finding it.

An SDK sample would be very helpful here.

Add example showing how to consume a notification published from service hooks

Provide a sample that shows how to use the public client library contracts to receive an incoming web hook and process it.

Basic steps for creating this sample

  1. Add the following public NuGet packages to your web project (get the latest pre-release)
    1. Microsoft.TeamFoundationServer.Client (provides the contract for WorkItemUpdate and the WIT client for making REST calls)
    2. Microsoft.VisualStudio.Services.ServiceHooks.WebApi (provides the WebHookEvent contract)
  2. Implement your controller function to accept a single WebHookEvent parameter (see below)
  3. Optional: if you plan to use our client library to make calls back to VSTS (highly recommended), create a VssConnection to your account in your app’s startup and reuse this connection object in your controller. VssConnection manages the pool of client instances and reuses them when it can.

Example controller

using Microsoft.TeamFoundation.WorkItemTracking.WebApi;
using Microsoft.TeamFoundation.WorkItemTracking.WebApi.Models;
using Microsoft.VisualStudio.Services.Common;
using Microsoft.VisualStudio.Services.ServiceHooks.WebApi;
using Microsoft.VisualStudio.Services.WebApi;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;

namespace ServiceHooksReceiverExample.Controllers
{
    public class EventsController : ApiController
    {
        // POST api/events
        public HttpResponseMessage Post(WebHookEvent webHookEvent)
        {
            WorkItemUpdate workItemUpdate = null;

            // Check if the incoming event is a work item updated event
            if (String.Equals(webHookEvent.EventType, "workitem.updated"))
            {
                JObject resource = webHookEvent.Resource as JObject;
                
                if (resource != null)
                {
                    // The resource for this type of event is a "WorkItemUpate" ... you can safely deserialize "resource" into a new instance of this type
                    workItemUpdate = resource.ToObject<WorkItemUpdate>();

                    // Get the already-created VssConnection (which points to your collection/account)
                    VssConnection connection =  HttpContext.Current.Application["vstsConnection"] as VssConnection;

                    // Get a WIT client
                    WorkItemTrackingHttpClient witClient = connection.GetClient<WorkItemTrackingHttpClient>();

                    // Make a call using the WIT client (in this example, just get the full representation of the updated work item)
                    WorkItem workitem = witClient.GetWorkItemAsync(workItemUpdate.WorkItemId).Result;
                }
            }
            
            if (workItemUpdate != null)
            {
                return Request.CreateResponse(HttpStatusCode.Accepted, workItemUpdate);
            }
            else
            {
                return Request.CreateResponse(HttpStatusCode.BadRequest);
            }
        }
    }
   
}

Example of how to establish the VssConnection in your app’s startup (Global.asax.cs)

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            GlobalConfiguration.Configure(WebApiConfig.Register);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            // Construct a new VssConnection object
            Uri collectionUrl = new Uri("https:/{your account name here}.visualstudio.com");
            VssCredentials creds = new VssBasicCredential(string.Empty, "{your PAT here; really you should pull this value from config}");
            VssConnection connection = new VssConnection(collectionUrl, creds);

            // Set this connection in application state so it can be reused throughout the lifecycle of the app
            Context.Application["vstsConnection"] = connection;
        }

WorkItemTrackingHttpClient.CreateAttachmentAsync(...).Result hangs

when attempting to use the code from the samples specifically this
AttachmentReference attachment = workItemTrackingClient.CreateAttachmentAsync(@filePath).Result;

The task never finishes, I can verify through fiddler that the request is goes out, and the response back is send similar to
{"id":"2253e426-3d97-4834-9206-d35ea0a2373f","url":"https://xxxxxxx.visualstudio.com/DefaultCollection/_apis/wit/attachments/2253e426-3d97-4834-9206-d35ea0a2373f?fileName=C:%5Ctemp%5CModels%5CArtifact.cs"}

This response and the URL it provides are valid and contain the correct file.

Create Bug Sample missing in project and the sample not work

I find the create bug sample by searching directly in the git repo, but nothing when I clone it to local. Turns out the file is not include in project Microsoft.TeamServices.Samples.Client.

Besides, the sample does not work. I captured the request, performed it in fiddler. Got bad request response claiming that: Rule Error for field Issue Type. Though the error message is clear, there is nothing related in the code sample.

Finally, I got it work by adding the object in request body:

{
    "op": "add",
    "path": "/fields/Microsoft.DevDiv.IssueType",
    "value": "Code Defect"
}

Hope it could get fixed. Thank you.

Is this sample compatible for VSO?

Hi,

Is this sample also compatible for VSO? In the config file I need to enter some "applicationid" which is needed for the authentication. I dont no where to get it from my VSO environment.

Not Found exception

I receive a 'Not Found' exception at this point.

https://github.com/Microsoft/vsts-dotnet-samples/blob/d4958e2eff2f61c1719465dd8045b7474217f012/ClientLibrary/Snippets/Microsoft.TeamServices.Samples.Client/WorkItemTracking/Sample.cs#L370

I'm thinking it's because I end up with 389 ids being passed to the query. I assume this is way too many since a query returning a smaller result set works fine. My issue is that I have no idea what the upper limit is and whether the query is truely 'Not Found' or whether it's a data issue.

Request sample clone with VssConnection

Can you give me an example how to clone a repository with VssClientCredentials?
I'v already found how to download a zip file of a repository, but cannot find the clone option.

Permissions

I'd be interested how to list all the ACLs on objects (projects, git repos, release configurations etc)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.