CDSWebApiService class library (C#)

Note

Unsure about entity vs. table? See Developers: Understand terminology in Microsoft Dataverse.

A .NET Framework sample class library that uses JSON objects and common HTTP messaging operations with the Microsoft Dataverse Web API. Use of these class methods result in less complicated application code, implementation of performance best practices, and improved error processing.

This class library demonstrates how to:

Using the provided Visual Studio project, you can build a class library and include this functionality in your own application code. You can find the CDSWebApiService class library source code and Visual Studio solution at PowerApps-Samples/cds/webapi/C#/CDSWebApiService.

Example

This example shows how to instantiate a CDSWebAPIService instance and create a contact row.

This example expects that the connection string is set in the App.config file as shown below.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0"
                      sku=".NETFramework,Version=v4.7.2" />
  </startup>
  <connectionStrings>
    <add name="Connect"
         connectionString="Url=https://yourorg.api.crm.dynamics.com;
         Authority=null;
         ClientId=51f81489-12ee-4a9e-aaae-a2591f45987d;
         RedirectUrl=app://58145B91-0C36-4500-8554-080854F2AC97;
         UserPrincipalName=you@yourorg.onmicrosoft.com;
         Password=y0urp455w0rd;
         CallerObjectId=null;
         Version=9.1;
         MaxRetries=3;
         TimeoutInSeconds=180;
         "/>
  </connectionStrings>
</configuration>

The code will access the connection string to instantiate the CDSWebApiService.

//Get configuration data from App.config connectionStrings
static readonly string connectionString = ConfigurationManager.ConnectionStrings["Connect"].ConnectionString;
static readonly ServiceConfig config = new ServiceConfig(connectionString);

    using (CDSWebApiService svc = new CDSWebApiService(config))
    {
        //Create a contact
        var contact1 = new JObject
            {
                { "firstname", "Rafel" },
                { "lastname", "Shillo" }
            };
        Uri contact1Uri = svc.PostCreate("contacts", contact1);
    }

Properties

This class exposes only the BaseAddress property. This is the configured BaseAddress used by the HttpClient. It can be useful to build complete URIs when needed since most cases will expect relative URIs.

Methods

This class provides the following public methods:

PostCreate

Creates a table row (entity record) synchronously and returns the URI.

Parameters

Name Type Description
entitySetName String The entity set name of the type of entity to create.
body JObject Contains the data for the entity to create

Return Value

The Uri of the created table row (entity record)

Remarks

This method is provided because creating entities is a common operation and the URI is returned in the OData-EntityId header. Having this specialized method allows for less code than having only the Post method, which returns only a JObject.

More information: Create a table row using the Web API.

PostCreateAsync

The asynchronous version of PostCreate.

Post

Sends a POST request synchronously and returns the response as a JObject.

Parameters

Name Type Description
path String The relative path to send the request. Frequently the name of an action or an entity set name.
body JObject The payload to POST
headers Dictionary<string, List<string>> (Optional) Any headers needed to apply special behaviors

Return Value

A JObject containing the response.

Remarks

This method can be used for any operation using the POST http method, but it only includes the response content. Use PostCreate to create table rows (entity records) and return only the URI of the created row.

More information:

PostAsync

The asynchronous version of Post.

Patch

Sends a PATCH request synchronously.

Parameters

Name Type Description
uri Uri The relative path to send the request. Frequently the Uri for a specific table row (entity record)
body JObject The payload to send
headers Dictionary<string, List<string>> (Optional) Any headers needed to apply special behaviors

Remarks

Patch is frequently used to Update or Upsert table rows.

More information:

PatchAsync

The asynchronous version of Patch.

Get

Sends a GET request synchronously and returns data

Parameters

Name Type Description
path String The relative path of the resource to return
headers Dictionary<string, List<string>> (Optional) Any headers needed to apply special behaviors

Return Value

A JToken representing the requested data.

Remarks

More information:

GetAsync

The asynchronous version of Get.

Delete

Sends a DELETE request synchronously.

Parameters

Name Type Description
uri Uri The relative path of the resource to delete
headers Dictionary<string, List<string>> (Optional) Any headers needed to apply special behaviors

Remarks

More information:

DeleteAsync

The asynchronous version of Delete.

Put

Sends a PUT request synchronously.

Parameters

Name Type Description
uri Uri The relative path to the resource to update.
property String The name of the column to update
value String The value to set

Remarks

Put is used to update specific table columns.

Note: The Http PUT method is also used to update table or column definitions (metadata). This method cannot be used for that purpose. It is specifically for business data.

More information:

PutAsync

The asynchronous version of Put.

Private SendAsync method

All of the methods above route their requests through the private SendAsync method. This is where the low level common logic occurs.

This method contains the logic to manage any Service Protection API 429 errors and re-try them for a number of times configurable in the service.

In order to do this, it sends a copy of the request rather than the actual request because the request will be disposed and cannot be sent again if an error is returned.

The copy of the request is available because of the custom HttpRequestMessage Clone method defined in the Extensions.cs file.

OAuthMessageHandler

When the internal HttpClient is initialized in the CDSWebApiService constructor, an instance of this class is set as an HttpMessageHandler. This class works with the ADAL libraries to ensure that the accessToken will be refreshed each time a request is sent. If the accessToken expires, the ADAL library methods will automatically refresh it.

More information: Example demonstrating a DelegatingHandler

ServiceConfig

The CDSWebApiService class should be initialized with a connection string via the ServiceConfig class.

The ServiceConfig constructor accepts a connection string, typically from the App.config configuration, and the data defined there is parsed into a ServiceConfig instance which the CDSWebApiService constructor requires.

Properties

The following are the properties of the ServiceConfig class.

Name Type Description
Authority String The authority to use to authorize user. Default is 'https://login.microsoftonline.com/common'
CallerObjectId Guid The Azure AD ObjectId for the user to impersonate other users.
ClientId String The id of the application registered with Azure AD
MaxRetries Byte The maximum number of attempts to retry a request blocked by service protection limits. Default is 3.
Password SecureString The password for the user principal
RedirectUrl String The Redirect Url of the application registered with Azure AD
TimeoutInSeconds ushort The amount of time to try completing a request before it will be cancelled. Default is 120 (2 minutes)
Url String The Url to the Dataverse environment, i.e "https://yourorg.api.crm.dynamics.com"
UserPrincipalName String The user principal name of the user. i.e. you@yourorg.onmicrosoft.com
Version String The version of the Web API to use. Default is '9.1'

Example connection string

Each of the samples that use CDSWebApiService include a reference to a common App.config and code to read a connection string value named 'Connect'. The following is an example of that App.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0"
                      sku=".NETFramework,Version=v4.7.2" />
  </startup>
  <connectionStrings>
    <add name="Connect"
         connectionString="Url=https://yourorg.api.crm.dynamics.com;
         Authority=null;
         ClientId=51f81489-12ee-4a9e-aaae-a2591f45987d;
         RedirectUrl=app://58145B91-0C36-4500-8554-080854F2AC97;
         UserPrincipalName=you@yourorg.onmicrosoft.com;
         Password=y0urp455w0rd;
         CallerObjectId=null;
         Version=9.1;
         MaxRetries=3;
         TimeoutInSeconds=180;
         "/>
  </connectionStrings>
</configuration>

The ClientId and RedirectUrl values are for sample applications. You can use these to run the samples, but you should register your own applications and enter the corresponding values for these properties.

More information: Walkthrough: Register an app with Azure Active Directory

ServiceException

This class simply extends Exception and provides additional properties from an error response.

Properties

Name Type Description
Message String The message returned by the platform
ErrorCode Int32 The error code returned by the platform
StatusCode Int32 The HttpResponseMessage.StatusCode
ReasonPhrase String The HttpResponseMessage.ReasonPhrase

Samples using this class

The following C# samples use this class: