Skip to content

Commit a2de6e2

Browse files
authored
Merge pull request #2723 from MicrosoftDocs/master
Publishing latest changes
2 parents 4522252 + 50835a2 commit a2de6e2

File tree

9 files changed

+1708
-104
lines changed

9 files changed

+1708
-104
lines changed

powerapps-docs/developer/common-data-service/api-limits.md

Lines changed: 278 additions & 102 deletions
Large diffs are not rendered by default.

powerapps-docs/developer/common-data-service/impersonate-another-user.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
title: "Impersonate another user (Common Data Service) | Microsoft Docs" # Intent and product brand in a unique string of 43-59 chars including spaces
33
description: "Use impersonation to execute business logic on behalf of another Common Data Service user to provide a desired feature or service using the appropriate role and object-based security of that impersonated user." # 115-145 characters including spaces. This abstract displays in the search result.
44
ms.custom: ""
5-
ms.date: 10/31/2018
5+
ms.date: 04/07/2020
66
ms.reviewer: "pehecke"
77
ms.service: powerapps
88
ms.topic: "article"
@@ -46,7 +46,7 @@ More information: [Build web applications using Server-to-Server (S2S) authentic
4646

4747
## Impersonate another user using the Web API
4848

49-
To impersonate a user, add a request header named `MSCRMCallerID` with a GUID value equal to the impersonated user’s `systemuserid` before sending the request to the web service.
49+
To impersonate a user, add a request header named `CallerObjectId` with a GUID value equal to the impersonated user's Azure Active Directory (AAD) object id before sending the request to the web service. The user's AAD object id is included in the [SystemUser.AzureActiveDirectoryObjectId](reference/entities/systemuser.md#BKMK_AzureActiveDirectoryObjectId).
5050

5151
More information: [Impersonate another user using the Web API](webapi/impersonate-another-user-web-api.md).
5252

@@ -70,3 +70,4 @@ More information: [Impersonate a user](impersonate-a-user.md).
7070
[Build web applications using Server-to-Server (S2S) authentication](build-web-applications-server-server-s2s-authentication.md)<br />
7171
[Impersonate another user using the Web API](webapi/impersonate-another-user-web-api.md)<br />
7272
[Write a plug-in](write-plug-in.md)
73+
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
---
2+
title: "Web API CDSWebApiService Async Parallel Operations Sample (C#) (Common Data Service)| Microsoft Docs"
3+
description: "This sample demonstrates using Task Parallel Library (TPL) dataflow components with asynchronous requests."
4+
ms.custom: ""
5+
ms.date: 04/20/2020
6+
ms.service: powerapps
7+
applies_to:
8+
- "Dynamics 365 (online)"
9+
author: "JimDaly"
10+
ms.author: "pehecke"
11+
ms.reviewer: "pehecke"
12+
search.audienceType:
13+
- developer
14+
search.app:
15+
- PowerApps
16+
- D365CE
17+
---
18+
# Web API CDSWebApiService Async Parallel Operations Sample (C#)
19+
20+
This sample demonstrates using Task Parallel Library (TPL) dataflow components [Dataflow (Task Parallel Library)](/dotnet/standard/parallel-programming/dataflow-task-parallel-library) with asynchronous requests.
21+
22+
TPL provides capabilities to add parallelism and concurrency to applications. These capabilities are an important part of maximizing throughput when performing operations that will add or update data within CDS.
23+
24+
This sample uses the CDSWebApiService class asynchronous methods within asynchronous operations. Because the CDSWebApiService class can manage Service Protection API limits, this code can be resilient to the transient 429 errors that clients should expect. It will retry a configurable number of times. More information: [Service Protection API Limits](../../api-limits.md)
25+
26+
This sample simply creates a configurable number of account records to create, which it will in turn delete. This sample uses dataflow components to process the records and transform the results of the create operation into the next phase that deletes these records. Because of the nature of this data flow, delete operations for previously created records will start before all the records to create are finished.
27+
28+
## Prerequisites
29+
30+
The following is required to build and run the CDSWebApiService C# samples :
31+
32+
- Microsoft Visual Studio 2019.
33+
- Access to Common Data Service with privileges to perform CRUD operations.
34+
35+
<a name="bkmk_runSample"></a>
36+
37+
## How to run this sample
38+
39+
1. Go to [Web API CDSWebApiService Sample](https://github.com/microsoft/PowerApps-Samples/tree/master/cds/webapi/C%23/CDSWebApiService), clone or download the samples repository, and extract its contents into a local folder.
40+
41+
1. Open the [CDSWebApiService.sln](https://github.com/microsoft/PowerApps-Samples/blob/master/cds/webapi/C%23/CDSWebApiService/CDSWebApiService.sln).
42+
43+
1. Select the **AsyncParallelOperations** project and open the App.config. This is a common [App.config](https://github.com/microsoft/PowerApps-Samples/blob/master/cds/webapi/C%23/CDSWebApiService/App.config) file used by all the samples in this solution. Once you edit this, you can run any of the samples in this solution.
44+
45+
1. You must edit the `Url`, `UserPrincipalName`, and `Password` values to set the CDS instance and credentials you want to connect to.
46+
47+
```xml
48+
<add name="Connect"
49+
connectionString="Url=https://yourorg.api.crm.dynamics.com;
50+
Authority=null;
51+
ClientId=51f81489-12ee-4a9e-aaae-a2591f45987d;
52+
RedirectUrl=app://58145B91-0C36-4500-8554-080854F2AC97;
53+
54+
Password=y0urp455w0rd;
55+
CallerObjectId=null;
56+
Version=9.1;
57+
MaxRetries=3;
58+
TimeoutInSeconds=180;
59+
"/>
60+
```
61+
62+
1. Make sure that the **AsyncParallelOperations** project is set as the startup project. The name of the project should be bold to indicate it is the startup project. If the name is not bold, right-click it in the solution explorer and select **Set as Startup Project**.
63+
64+
1. Press F5 to run the program in debug mode.
65+
66+
## Code listing
67+
68+
This sample depends on the assembly included in the CDSWebAPIService project. For information on the methods this class provides see: [Web API CDSWebApiService class Sample (C#)](cdswebapiservice.md).
69+
70+
The following is the code from the Program.cs file:
71+
72+
```csharp
73+
using Newtonsoft.Json.Linq;
74+
using System;
75+
using System.Collections.Generic;
76+
using System.Configuration;
77+
using System.Threading.Tasks;
78+
using System.Threading.Tasks.Dataflow;
79+
80+
namespace PowerApps.Samples
81+
{
82+
internal class Program
83+
{
84+
//Get configuration data from App.config connectionStrings
85+
private static readonly string connectionString = ConfigurationManager.ConnectionStrings["Connect"].ConnectionString;
86+
87+
private static readonly ServiceConfig serviceConfig = new ServiceConfig(connectionString);
88+
89+
//Controls the max degree of parallelism
90+
private static readonly int maxDegreeOfParallelism = 10;
91+
92+
//How many records to create with this sample.
93+
private static readonly int numberOfRecords = 100;
94+
95+
private static async Task Main()
96+
{
97+
#region Optimize Connection
98+
99+
//Change max connections from .NET to a remote service default: 2
100+
System.Net.ServicePointManager.DefaultConnectionLimit = 65000;
101+
//Bump up the min threads reserved for this app to ramp connections faster - minWorkerThreads defaults to 4, minIOCP defaults to 4
102+
System.Threading.ThreadPool.SetMinThreads(100, 100);
103+
//Turn off the Expect 100 to continue message - 'true' will cause the caller to wait until it round-trip confirms a connection to the server
104+
System.Net.ServicePointManager.Expect100Continue = false;
105+
//Can decrease overall transmission overhead but can cause delay in data packet arrival
106+
System.Net.ServicePointManager.UseNagleAlgorithm = false;
107+
108+
#endregion Optimize Connection
109+
110+
var executionDataflowBlockOptions = new ExecutionDataflowBlockOptions
111+
{
112+
MaxDegreeOfParallelism = maxDegreeOfParallelism
113+
};
114+
115+
var count = 0;
116+
double secondsToComplete;
117+
118+
//Will be populated with account records to import
119+
List<JObject> accountsToImport = new List<JObject>();
120+
121+
Console.WriteLine($"Preparing to create {numberOfRecords} acccount records using Web API.");
122+
123+
//Add account records to the list to import
124+
while (count < numberOfRecords)
125+
{
126+
var account = new JObject
127+
{
128+
["name"] = $"Account {count}"
129+
};
130+
accountsToImport.Add(account);
131+
count++;
132+
}
133+
134+
using (var svc = new CDSWebApiService(serviceConfig))
135+
{
136+
secondsToComplete = await ProcessData(svc, accountsToImport, executionDataflowBlockOptions);
137+
}
138+
139+
Console.WriteLine($"Created and deleted {accountsToImport.Count} accounts in {Math.Round(secondsToComplete)} seconds.");
140+
141+
Console.WriteLine("Sample completed. Press any key to exit.");
142+
Console.ReadLine();
143+
}
144+
145+
private static async Task<double> ProcessData(CDSWebApiService svc, List<JObject> accountsToImport,
146+
ExecutionDataflowBlockOptions executionDataflowBlockOptions)
147+
{
148+
var createAccounts = new TransformBlock<JObject, Uri>(
149+
async a =>
150+
{
151+
return await svc.PostCreateAsync("accounts", a);
152+
},
153+
executionDataflowBlockOptions
154+
);
155+
156+
var deleteAccounts = new ActionBlock<Uri>(
157+
async u =>
158+
{
159+
await svc.DeleteAsync(u);
160+
},
161+
executionDataflowBlockOptions
162+
);
163+
164+
createAccounts.LinkTo(deleteAccounts, new DataflowLinkOptions { PropagateCompletion = true });
165+
166+
var start = DateTime.Now;
167+
168+
accountsToImport.ForEach(a => createAccounts.SendAsync(a));
169+
createAccounts.Complete();
170+
await deleteAccounts.Completion;
171+
172+
//Calculate the duration to complete
173+
return (DateTime.Now - start).TotalSeconds;
174+
}
175+
}
176+
}
177+
```
178+
179+
### See also
180+
181+
[Use the Common Data Service Web API](../overview.md)<br />
182+
[Web API CDSWebApiService class Sample (C#)](cdswebapiservice.md)<br />
183+
[Web API CDSWebApiService Basic Operations Sample (C#)](cdswebapiservice-basic-operations.md)<br />
184+
[Web API CDSWebApiService Parallel Operations Sample (C#)](cdswebapiservice-parallel-operations.md)<br />
185+
[Create an entity using the Web API](../create-entity-web-api.md)<br />
186+
[Update and delete entities using the Web API](../update-delete-entities-using-web-api.md)

0 commit comments

Comments
 (0)