Skip to content

Commit 849e6bc

Browse files
committed
Added Blazor sample page
1 parent d9c8adf commit 849e6bc

File tree

4 files changed

+131
-23
lines changed

4 files changed

+131
-23
lines changed

powerapps-docs/developer/data-platform/TOC.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,8 @@
438438
href: discovery-service.md
439439
- name: "Sample: Global Discovery Service"
440440
href: sample-global-discovery-service-csharp.md
441+
- name: "Sample: Blazor WebAssembly with Global Discovery"
442+
href: sample-blazor-web-assembly-global-discovery.md
441443
- name: Tutorials
442444
items:
443445
- name: "Tutorial: Register an app with Azure Active Directory"

powerapps-docs/developer/data-platform/discovery-service.md

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: "Discover user organizations (Microsoft Dataverse) | Microsoft Docs" # Intent and product brand in a unique string of 43-59 chars including spaces
33
description: "Your client application may connect to multiple Dataverse environments. Use the Global Discovery Service to find which environments the user of your application can access."
4-
ms.date: 07/01/2022
4+
ms.date: 07/18/2022
55
ms.reviewer: pehecke
66
ms.topic: article
77
author: ImadYanni # GitHub ID
@@ -122,12 +122,12 @@ The following table describes the properties of the `Instance` Entity from the $
122122
|`Id`|Guid|The OrganizationId for the environment.|
123123
|`IsUserSysAdmin`|Boolean|Whether the calling user has the system administrator role for the environment.|
124124
|`LastUpdated`|DateTimeOffset|When the environment was last updated. |
125-
|`OrganizationType`|Int32|The type of the organization. Values correspond to the OrganizationType Enum|
125+
|`OrganizationType`|Int32|The type of the organization. Values correspond to the <xref:Microsoft.Dynamics.CRM.OrganizationType?text=OrganizationType EnumType>|
126126
|`Purpose`|String|Information for the purpose provided when the environment was created.|
127127
|`Region`|String|A 2-3 letter code for region where the environment is located. |
128128
|`SchemaType`|String|For internal use only.|
129-
|`State`|Int32|Whether the organization is enabled (`0`) or eisabled (`1`).|
130-
|`StatusMessage`|Int32|TODO: This is an integer value. What does it mean?|
129+
|`State`|Int32|Whether the organization is `0`:enabled or `1`:disabled.|
130+
|`StatusMessage`|Int32|One of the following values: <br /> `0`:`InstanceLocked`<br /> `1`:`PendingServiceInstanceMove`<br /> `2`:`InstanceFailed`<br /> `3`:`Provisioning` <br /> `4`:`InActiveOrganizationStatus`<br /> `5`:`NewInstance`<br /> `6`:`InstancePickerReady` |
131131
|`TenantId`|Guid|The Id of the tenant associated to the instance|
132132
|`TrialExpirationDate`|DateTimeOffset|The date when the trial period for the instance expires.|
133133
|`UniqueName`|String|The Unique Name for the instance.|
@@ -163,7 +163,7 @@ odata-version: 4.0
163163
}
164164
```
165165

166-
Use the `FriendlyName` property for your application UI so the user will recognize the name of the environment. Use the `ApiUrl` to connect to the Dataverse Web API.
166+
Use the `FriendlyName` property for your application UI so the user will recognize the name of the environment. Use the `ApiUrl` to connect to Dataverse.
167167

168168
The rest of the properties are primarily for filtering.
169169

@@ -235,8 +235,6 @@ You can use the following string query functions:
235235

236236
For .NET applications you can use <xref:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient?text=Dataverse.Client.ServiceClient>.<xref:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.DiscoverOnlineOrganizationsAsync%2A?text=DiscoverOnlineOrganizationsAsync Method> to call the Global Discovery Services.
237237

238-
TODO: Ask Matt B to comment on the key benefits provided by this method.
239-
240238
```csharp
241239
// Set up user credentials
242240
var creds = new System.ServiceModel.Description.ClientCredentials();
@@ -256,7 +254,7 @@ DiscoverOrganizationsResult organizationsResult = await ServiceClient.DiscoverOn
256254
return organizationsResult;
257255
```
258256

259-
While the `DiscoverOnlineOrganizationsAsync` method uses the same OData endpoint and enables that it be passed in the `discoveryServiceUri` parameter, it does not return data in the shape of an *Instance*. Data is returned as an <xref:Microsoft.PowerPlatform.Dataverse.Client.Model.DiscoverOrganizationsResult?text=DiscoverOrganizationsResult Class> that includes a <xref:Microsoft.PowerPlatform.Dataverse.Client.Model.DiscoverOrganizationsResult.OrganizationDetailCollection?text=OrganizationDetailCollection Property> which contains a collection of <xref:Microsoft.Xrm.Sdk.Discovery.OrganizationDetail?text=OrganizationDetail Class> instances. This class contains the same information as the Instance types returned by the OData service.
257+
While the `DiscoverOnlineOrganizationsAsync` method uses the same OData endpoint and enables that it be passed in the `discoveryServiceUri` parameter, it does not return data in the shape of an *Instance*. Data is returned as an <xref:Microsoft.PowerPlatform.Dataverse.Client.Model.DiscoverOrganizationsResult?text=DiscoverOrganizationsResult Class> that includes a <xref:Microsoft.PowerPlatform.Dataverse.Client.Model.DiscoverOrganizationsResult.OrganizationDetailCollection?text=OrganizationDetailCollection Property> which contains a collection of <xref:Microsoft.Xrm.Sdk.Discovery.OrganizationDetail?text=OrganizationDetail Class> instances. This class contains the same information as the `Instance` types returned by the OData service.
260258

261259
> [!NOTE]
262260
> While the `DiscoverOnlineOrganizationsAsync.discoveryServiceUri` parameter accepts a URL to the Global Discovery Service, any `$select` or `$filter` query options used will be ignored. The `DiscoverOnlineOrganizationsAsync.discoveryServiceUri` parameter is optional and if not provided will default to the Commercial cloud.
@@ -286,14 +284,13 @@ For .NET Full Framework applications you can continue to use the <xref:Microsoft
286284
return organizations.ToList();
287285
```
288286

289-
Like the `ServiceClient.DiscoverOnlineOrganizationsAsync` method, the `CrmServiceClient.DiscoverGlobalOrganizations` method also does not return data as an *Instance*. It returns a
290-
291-
<xref:Microsoft.Xrm.Sdk.Discovery.OrganizationDetailCollection?text=OrganizationDetailCollection> which contains a collection of <xref:Microsoft.Xrm.Sdk.Discovery.OrganizationDetail?text=OrganizationDetail Class> instances that contains the same information as the Instance types returned by the OData service.
287+
Like the `ServiceClient.DiscoverOnlineOrganizationsAsync` method, the `CrmServiceClient.DiscoverGlobalOrganizations` method also does not return data as an *Instance*. It returns a <xref:Microsoft.Xrm.Sdk.Discovery.OrganizationDetailCollection?text=OrganizationDetailCollection> which contains a collection of <xref:Microsoft.Xrm.Sdk.Discovery.OrganizationDetail?text=OrganizationDetail Class> instances that contains the same information as the `Instance` types returned by the OData service.
292288

293289
### See Also
294290

295291
[Sample: Global Discovery Service Sample (C#)](sample-global-discovery-service-csharp.md)<br />
296-
[Sample: Access the Discovery service using CrmServiceClient](org-service/samples/access-discovery-service.md)
292+
[Sample: Access the Discovery service using CrmServiceClient](org-service/samples/access-discovery-service.md)<br />
293+
[Sample: Blazor WebAssembly with Global Discovery](sample-blazor-web-assembly-global-discovery.md)
297294

298295

299296
[!INCLUDE[footer-include](../../includes/footer-banner.md)]
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
---
2+
title: "Sample: Blazor WebAssembly with Global Discovery (C#) (Microsoft Dataverse) | Microsoft Docs" # Intent and product brand in a unique string of 43-59 chars including spaces
3+
description: "This sample a Blazor WebAssembly project that uses the Global Discovery Service and Dataverse Web API to access multiple environments available to the user." # 115-145 characters including spaces. This abstract displays in the search result.
4+
ms.date: 07/18/2022
5+
author: ImadYanni
6+
ms.author: iyanni
7+
ms.reviewer: jdaly
8+
search.audienceType:
9+
- developer
10+
search.app:
11+
- PowerApps
12+
- D365CE
13+
contributors:
14+
- JimDaly
15+
- phecke
16+
---
17+
# Sample: Blazor WebAssembly with Global Discovery
18+
19+
This sample shows how to use the Global Discovery service from a Blazor WebAssembly application.
20+
21+
You can download the sample from [https://github.com/microsoft/PowerApps-Samples/tree/master/cds/webapi/C#/BlazorCDS](https://github.com/microsoft/PowerApps-Samples/tree/master/cds/webapi/C%23/BlazorCDS)
22+
23+
This sample is a modification of the steps in the [Tutorial: Create an ASP.NET Core Blazor WebAssembly app using Microsoft Dataverse](walkthrough-blazor-webassembly-single-tenant.md)
24+
25+
## How to run this sample
26+
27+
1. Download or clone the [Samples](https://github.com/microsoft/PowerApps-Samples) repo so that you have a local copy.
28+
1. Follow the instructions in [Setup](#setup) to create an Azure Active Directory app registration and run the sample.
29+
30+
## What this sample does
31+
32+
This sample demonstrates how to provide a select (drop-down) control in a web application to allow users to switch environments that they have access to.
33+
34+
## How this sample works
35+
36+
The `Pages/EnvironmentChooser.razor `file provides the UI to allow users to select from available environments based on their credentials after they have logged in.
37+
38+
This page depends on a named definition of an HttpClient (`GDSClient`) in Program.cs that is configured to access the Global Discovery Service. Access to the Global Discovery Service is added to the available scopes when the user logs in. When the user selects a different environment, the `SelectedEnvUrl` in `Models/AppState.cs` changes.
39+
40+
Access to the account records is provided by `Pages/FetchAccounts.razor` with an access token that depends on the selected environment.
41+
42+
### Setup
43+
44+
To run this sample you must first configure an Azure Active Directory application on your tenant and update the `BlazorCDS\wwwroot\appsettings.json` file to replace the placeholder `ClientId` value with the application (client) Id. Use the following steps:
45+
46+
#### Create an app registration
47+
48+
1. Go to [Azure](https://portal.azure.com/).
49+
1. Select **Azure Active Directory**.
50+
1. Go To **App registrations**.
51+
1. Select **New Registration**.
52+
1. Enter the following:
53+
54+
|Field|Value|
55+
|---------|---------|
56+
|Name|Your choice. You might use: `BlazorGlobalDiscoverySample`|
57+
|Supported account types:|Accounts in this organization directory only (Single Tenant)|
58+
|Redirect URI (optional)|`https://localhost:44363/authentication/login-callback`|
59+
60+
1. Click **Register**.
61+
1. Copy the **Application (client) ID** value. You will need this when you [Update the project](#update-the-project).
62+
63+
#### Configure Authentication
64+
65+
1. Go to **Authentication**.
66+
1. Under **Implicit grant and hybrid flows**, select both of the following options:
67+
68+
- Access tokens (used for implicit flows)
69+
- ID tokens (used for implicit and hybrid flows)
70+
71+
1. Click **Save**.
72+
73+
#### Configure Permissions
74+
75+
1. Go to **API permissions**.
76+
1. Click **Add a permission**.
77+
1. In the **Request API permissions** fly-out, under the**Microsoft APIs** tab, select **Dynamics CRM**.
78+
1. Under **Select permissions**, select **user_impersonation**.
79+
1. Click **Add permissions**.
80+
1. Under **Configured permissions**, click **Grant admin consent** for {Your tenant name.}
81+
1. In the **Grant admin consent** confirmation dialog, click **Yes**.
82+
83+
#### Update the project
84+
85+
1. Open the BlazorCDS Visual Studio solution file (BlazorCDS.sln) with Visual Studio
86+
1. In **Solution Explorer**, expand `wwwroot` and open the `appsettings.json` file.
87+
1. Replace the placeholder `ClientId` value (`11111111-1111-1111-1111-111111111111`) with the application (client) ID value you copied in [Create an app registration](#create-an-app-registration).
88+
89+
#### Run the sample
90+
91+
In Visual Studio, click **IIS Express** to run the sample.
92+
93+
### Demonstrate
94+
95+
1. In the browser window that opens with the app, click **Log in**.
96+
1. Enter your credentials and you will see a select control with the label: **Choose an Environment**. The select control should list all the environments you have access to with the credentials you provided.
97+
1. Click **Fetch Accounts**. This should display a list of account records you have access to view in the selected environment.
98+
1. If you have more than one environment to choose from, select a different environment and the list of account records will be refreshed to represent the records available in that environment.
99+
100+
### Clean up
101+
102+
This sample makes no changes to data in your environment.
103+
104+
105+
[!INCLUDE [footer-banner](../../includes/footer-banner.md)]

powerapps-docs/developer/data-platform/sample-global-discovery-service-csharp.md

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: "Global Discovery Service Sample (C#) (Microsoft Dataverse) | Microsoft Docs" # Intent and product brand in a unique string of 43-59 chars including spaces
33
description: "This sample shows how to access the global Discovery Service using the OData V4 RESTful API and the Dataverse.Client.ServiceClient" # 115-145 characters including spaces. This abstract displays in the search result.
4-
ms.date: 07/01/2022
4+
ms.date: 07/18/2022
55
author: ImadYanni
66
ms.author: iyanni
77
ms.reviewer: jdaly
@@ -17,7 +17,10 @@ contributors:
1717

1818
# Sample: Global Discovery Service (C#)
1919

20-
This Visual Studio solution contains two projects that demonstrate how to use the Global Discovery Service.
20+
This Visual Studio solution contains two .NET 6.0 projects that demonstrate how to use the Global Discovery Service.
21+
22+
- `REST` project shows using the OData endpoint
23+
- `ServiceClient` project shows using <xref:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.DiscoverOnlineOrganizationsAsync%2A?text=Dataverse.Client.ServiceClient.DiscoverOnlineOrganizationsAsync Method>
2124

2225
## How to run this sample
2326

@@ -41,23 +44,23 @@ To run the sample:
4144

4245
Both the `REST` and `ServiceClient` samples do the same things:
4346

44-
1. Retrieve the list of environments available for your credentials
45-
1. List the environments so you can select one
46-
1. Execute a WhoAmI message to return the SystemUser.UserId value for your account in the selected environment
47+
1. Retrieve the list of environments available for your credentials.
48+
1. List the environments so you can select one.
49+
1. Execute a `WhoAmI` message to return the `SystemUser.UserId` value for your account in the selected environment.
4750

4851
## How this sample works
4952

5053
### REST
5154

52-
The REST project uses the MSAL libraries with an HttpClient to use the Global Discovery OData endpoint without the use of any additional assemblies.
55+
The `REST` project uses the MSAL libraries with an [HttpClient](/dotnet/api/system.net.http.httpclient) to use the Global Discovery OData endpoint without the use of any additional assemblies.
5356

5457
### ServiceClient
5558

56-
The ServiceClient project uses the <xref:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient?text=Dataverse.Client.ServiceClient>.<xref:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.DiscoverOnlineOrganizationsAsync%2A?text=DiscoverOnlineOrganizationsAsync Method> to use the Global Discovery OData endpoint.
59+
The `ServiceClient` project uses the <xref:Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.DiscoverOnlineOrganizationsAsync%2A?text=Dataverse.Client.ServiceClient.DiscoverOnlineOrganizationsAsync Method> to use the Global Discovery OData endpoint.
5760

5861
### Demonstrates
5962

60-
Both samples use the same Cloud enum defined in Cloud.cs to represent the different clouds that may be used with the Global Discovery Service.
63+
Both projects use the same `Cloud` enum defined in Cloud.cs to represent the different clouds that may be used with the Global Discovery Service.
6164

6265
```csharp
6366
using System.ComponentModel;
@@ -119,7 +122,7 @@ namespace PowerApps.Samples
119122
}
120123
```
121124

122-
The Program.cs file contains the following:
125+
The `REST` Program.cs file contains the following:
123126

124127
```csharp
125128
using Microsoft.Identity.Client;
@@ -369,7 +372,7 @@ namespace PowerApps.Samples
369372

370373
#### ServiceClient Project
371374

372-
The ServiceClient Project Program.cs file contains the following:
375+
The `ServiceClient` project Program.cs file contains the following:
373376

374377
```csharp
375378
using Microsoft.Crm.Sdk.Messages;
@@ -551,6 +554,7 @@ namespace PowerApps.Samples
551554

552555
## See Also
553556

554-
[Discover user organizations](discovery-service.md)
557+
[Discover user organizations](discovery-service.md)<br />
558+
[Blazor web assembly sample](https://github.com/microsoft/PowerApps-Samples/tree/master/cds/webapi/C%23/BlazorCDS)
555559

556560
[!INCLUDE [footer-banner](../../includes/footer-banner.md)]

0 commit comments

Comments
 (0)