# .NET

> Call ReportingCloud from C# with the TXTextControl.ReportingCloud NuGet package: target frameworks, API keys, MergeDocument and the endpoints of its methods.

- **Product:** ReportingCloud
- **Section:** Documentation
- **Kind:** Topic
- **Path:** ReportingCloud > SDKs > .NET
- **3804 words**
- **Web URL:** https://docs.textcontrol.com/reporting-cloud/sdks/dotnet/
- **LLMs URL:** https://docs.textcontrol.com/reporting-cloud/sdks/dotnet/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/reporting-cloud/sdks/dotnet/llms-full.txt

---

`TXTextControl.ReportingCloud` is the NuGet package that calls the ReportingCloud Web API from C#. Its `ReportingCloud` class has a method for each endpoint, those of the two tracked-changes endpoints in its property `Processing.Review`: you pass .NET objects and byte arrays, and the class sends the JSON request, checks the answer and returns the documents as byte arrays. Below are the package's target frameworks, how the class authenticates, a merge example and every method with the endpoint it calls.

For a first application built step by step, follow [ASP.NET Core](https://docs.textcontrol.com/reporting-cloud/getting-started/dotnet/aspnet-core/llms-full.txt) or [.NET Framework](https://docs.textcontrol.com/reporting-cloud/getting-started/dotnet/dotnet-framework/llms-full.txt) in Getting Started.

### Package and Requirements

| Package | Version | Released | Target frameworks | Dependencies |
|---|---|---|---|---|
| [TXTextControl.ReportingCloud](https://www.nuget.org/packages/TXTextControl.ReportingCloud/) | 1.205.500 | September 2, 2019 | .NET Framework 4.5, .NET Standard 1.3, .NET Core 1.1 | `Newtonsoft.Json` 10.0.3 or later, and per target framework `Microsoft.AspNet.WebApi` 5.2.6, `NETStandard.Library` 1.6.1 or `Microsoft.NETCore.App` 1.1.2 |

The package holds one assembly, *ReportingCloudWrapper.dll*, for each target framework, and its classes are in the namespace `TXTextControl.ReportingCloud`. A project for .NET 8 or .NET 10 gets the .NET Core 1.1 build: a .NET 10 console application compiles and runs with it. Restoring the package in a .NET 10 project reports warning NU1903, a dependency with a known vulnerability, for `Newtonsoft.Json` 10.0.3, `Microsoft.NETCore.App` 1.1.2 and `Microsoft.NETCore.Jit` 1.1.2. [Installing an SDK](https://docs.textcontrol.com/reporting-cloud/installation/sdks/#net) explains what you can do about them, shows the other ways to install the package and checks the installation with a first call.

Install the package with the .NET CLI in the folder of your project:

```bash
dotnet add package TXTextControl.ReportingCloud
```

The package `TXTextControl.ReportingCloud.Core` was a separate build for .NET Core until the multi-target package replaced it, as the blog article [ReportingCloud: One Multi-Target Wrapper for .NET, .NET Core and .NET Standard](https://www.textcontrol.com/blog/2018/12/03/reportingcloud-one-multitarget-dotnet-wrapper/) announced. Its last version, 1.200.500 of November 30, 2018, describes itself as deprecated: don't use it in new projects.

### Authentication

Every method runs on an instance of `ReportingCloud`. Its constructor takes the credentials that the class sends with each request:

| Constructor | Authorization header of every request |
|---|---|
| `ReportingCloud(string apikey)` | `ReportingCloud-APIKey` followed by the key |
| `ReportingCloud(string apikey, Uri webApiBaseUrl)` | The same, sent to another base URL |
| `ReportingCloud(string username, string password)` | `Basic` followed by the Base64-encoded user name and password |
| `ReportingCloud(string username, string password, Uri webApiBaseUrl)` | The same, sent to another base URL |

Without `webApiBaseUrl`, the requests go to `https://api.reporting.cloud`. The properties `APIKey`, `Username`, `Password` and `WebApiBaseUrl` change the values later. When `APIKey` holds a key, the class sends it and ignores the user name and password. Use an API key: [API Keys](https://docs.textcontrol.com/reporting-cloud/installation/api-keys/llms-full.txt) shows how to create one, and [Authentication](https://docs.textcontrol.com/reporting-cloud/document-processing/authentication/llms-full.txt) explains both methods.

### Merge a Template

The following console application merges *sample\_invoice.tx*, the demo template in the template storage of every trial account, with one invoice record and saves the result as *invoice.pdf*. Create it with `dotnet new console`, add the package, set the environment variable `REPORTINGCLOUD_API_KEY` to your API key and replace the contents of *Program.cs* with this code:

```csharp
using TXTextControl.ReportingCloud;

// Send the API key with every request
ReportingCloud reportingCloud = new ReportingCloud(
    Environment.GetEnvironmentVariable("REPORTINGCLOUD_API_KEY"));

// One record with the fields and the item block of sample_invoice.tx
var invoice = new
{
    invoice_no = "778723",
    billto_name = "Joey Montana",
    billto_companyname = "Montana, LLC",
    item = new[]
    {
        new { qty = "1", item_no = "1", item_description = "Item description 1", item_total = "2130.40" },
        new { qty = "1", item_no = "2", item_description = "Item description 2", item_total = "5543" }
    },
    total = "8210.538"
};

MergeBody mergeBody = new MergeBody
{
    MergeData = new[] { invoice },
    MergeSettings = new MergeSettings { DocumentTitle = "Invoice 778723" }
};

try
{
    // Merge the stored template and return the documents as byte arrays
    List<byte[]> documents = reportingCloud.MergeDocument(
        mergeBody, "sample_invoice.tx", ReturnFormat.PDF);

    File.WriteAllBytes("invoice.pdf", documents[0]);
    Console.WriteLine("invoice.pdf has been written.");
}
catch (ArgumentException exception)
{
    // The message is the response body of the failed request
    Console.WriteLine(exception.Message);
}
```

The code works as follows:

- `MergeBody` is the request body. `MergeData` holds the records, any object that serializes to a JSON array; `Template` can hold a template as a byte array instead of a template name; `MergeSettings` sets merge options and document properties.
- `MergeDocument` sends the request to [POST /v1/document/merge](https://docs.textcontrol.com/reporting-cloud/reference/web-api/document/merge/post/llms-full.txt). Its parameters after the body are `templateName` (`null` by default), `returnFormat` (`ReturnFormat.PDF`), `append` (`true`), which combines several records into one document, and `test` (`false`).
- The method returns a `List<byte[]>` with one entry for each created document. `ReturnFormat` has the values `PDF`, `PDFA`, `DOC`, `DOCX`, `RTF`, `TX`, `HTML` and `TXT`.

[Merge Settings](https://docs.textcontrol.com/reporting-cloud/mail-merge/settings/llms-full.txt) describes every option of `MergeSettings`.

#### How Merge Data Is Serialized

The class writes `MergeData` with Json.NET and a camel-case naming strategy: the capital letters at the start of each property name and dictionary key become lowercase. A property `InvoiceNo` is sent as `invoiceNo` and `ID` as `id`, while `invoice_no` stays as it is. Give your properties the names of the merge fields, as the anonymous type above does, so that the JSON keys match the template. [Merge Data](https://docs.textcontrol.com/reporting-cloud/mail-merge/data-sources/llms-full.txt) describes the structure of records, fields and blocks.

### ReportingCloud Methods

| Method | Web API endpoint | Returns |
|---|---|---|
| `MergeDocument` | [POST /v1/document/merge](https://docs.textcontrol.com/reporting-cloud/reference/web-api/document/merge/post/llms-full.txt) | `List<byte[]>`, the merged documents |
| `AppendDocument` | [POST /v1/document/append](https://docs.textcontrol.com/reporting-cloud/reference/web-api/document/append/post/llms-full.txt) | `byte[]`, one document combined from an `AppendBody` |
| `ConvertDocument` | [POST /v1/document/convert](https://docs.textcontrol.com/reporting-cloud/reference/web-api/document/convert/post/llms-full.txt) | `byte[]`, the document in the `ReturnFormat` |
| `FindAndReplaceDocument` | [POST /v1/document/findandreplace](https://docs.textcontrol.com/reporting-cloud/reference/web-api/document/findandreplace/post/llms-full.txt) | `byte[]`, the document with the text replaced |
| `GetDocumentThumbnails` | [POST /v1/document/thumbnails](https://docs.textcontrol.com/reporting-cloud/reference/web-api/document/thumbnails/post/llms-full.txt) | One image per page, see [Platform Differences](#platform-differences) |
| `ShareDocument` | [GET /v1/document/share](https://docs.textcontrol.com/reporting-cloud/reference/web-api/document/share/get/llms-full.txt) | `string`, the encrypted name of a stored template for the viewer widget |
| `UploadTemplate` | [POST /v1/templates/upload](https://docs.textcontrol.com/reporting-cloud/reference/web-api/templates/upload/post/llms-full.txt) | Nothing |
| `ListTemplates` | [GET /v1/templates/list](https://docs.textcontrol.com/reporting-cloud/reference/web-api/templates/list/get/llms-full.txt) | `List<Template>` with `TemplateName`, `Modified` and `Size` |
| `GetTemplateCount` | [GET /v1/templates/count](https://docs.textcontrol.com/reporting-cloud/reference/web-api/templates/count/get/llms-full.txt) | `int` |
| `TemplateExists` | [GET /v1/templates/exists](https://docs.textcontrol.com/reporting-cloud/reference/web-api/templates/exists/get/llms-full.txt) | `bool` |
| `GetTemplateInfo` | [GET /v1/templates/info](https://docs.textcontrol.com/reporting-cloud/reference/web-api/templates/info/get/llms-full.txt) | `TemplateInfo` with the `MergeFields` and `MergeBlocks` of the template |
| `GetTemplatePageCount` | [GET /v1/templates/pagecount](https://docs.textcontrol.com/reporting-cloud/reference/web-api/templates/pagecount/get/llms-full.txt) | `int` |
| `GetTemplateThumbnails` | [GET /v1/templates/thumbnails](https://docs.textcontrol.com/reporting-cloud/reference/web-api/templates/thumbnails/get/llms-full.txt) | One image per page, see [Platform Differences](#platform-differences) |
| `DownloadTemplate` | [GET /v1/templates/download](https://docs.textcontrol.com/reporting-cloud/reference/web-api/templates/download/get/llms-full.txt) | `byte[]` |
| `DeleteTemplate` | [DELETE /v1/templates/delete](https://docs.textcontrol.com/reporting-cloud/reference/web-api/templates/delete/delete/llms-full.txt) | Nothing |
| `GetAccountSettings` | [GET /v1/account/settings](https://docs.textcontrol.com/reporting-cloud/reference/web-api/account/settings/get/llms-full.txt) | `AccountSettings` with the serial number, the quotas and their usage |
| `GetAccountAPIKeys` | [GET /v1/account/apikeys](https://docs.textcontrol.com/reporting-cloud/reference/web-api/account/apikeys/get/llms-full.txt) | `List<APIKey>` with `Key` and `Active` |
| `CreateAccountAPIKey` | [PUT /v1/account/apikey](https://docs.textcontrol.com/reporting-cloud/reference/web-api/account/apikey/put/llms-full.txt) | `string`, the new key |
| `DeleteAccountAPIKey` | [DELETE /v1/account/apikey](https://docs.textcontrol.com/reporting-cloud/reference/web-api/account/apikey/delete/llms-full.txt) | `bool` |
| `ListFonts` | [GET /v1/fonts/list](https://docs.textcontrol.com/reporting-cloud/reference/web-api/fonts/list/get/llms-full.txt) | `string[]` |
| `CheckText` | [GET /v1/proofing/check](https://docs.textcontrol.com/reporting-cloud/reference/web-api/proofing/check/get/llms-full.txt) | `List<IncorrectWord>` |
| `GetAvailableDictionaries` | [GET /v1/proofing/availabledictionaries](https://docs.textcontrol.com/reporting-cloud/reference/web-api/proofing/availabledictionaries/get/llms-full.txt) | `string[]` |
| `GetSuggestions` | [GET /v1/proofing/suggestions](https://docs.textcontrol.com/reporting-cloud/reference/web-api/proofing/suggestions/get/llms-full.txt) | `string[]` |
| `Processing.Review.GetTrackedChanges` | [POST /v1/processing/review/trackedchanges](https://docs.textcontrol.com/reporting-cloud/reference/web-api/processing/review-trackedchanges/post/llms-full.txt) | `List<TrackedChange>` |
| `Processing.Review.RemoveTrackedChange` | [POST /v1/processing/review/removetrackedchange](https://docs.textcontrol.com/reporting-cloud/reference/web-api/processing/review-removetrackedchange/post/llms-full.txt) | `TrackedChangeModifiedDocument` with the `Document` and whether the change was `Removed` |

`MergeDocument`, `AppendDocument`, `ConvertDocument` and `FindAndReplaceDocument` take a `test` argument, the `test` parameter of the Web API: a test run adds a "TEST MODE" watermark, and a Free account can't use it. On a trial account, test runs of convert and append aren't counted against the document quota, and test runs of merge and find and replace are.

The methods add template names, the text of `CheckText` and the word of `GetSuggestions` to the query string without encoding them. A value with `&` or `#` arrives cut off, so encode such a value with `Uri.EscapeDataString` before you pass it.

### Request Objects

| Class | Used by | Properties |
|---|---|---|
| `MergeBody` | `MergeDocument` | `MergeData`, `Template`, `MergeSettings` |
| `MergeSettings` | `MergeDocument`, `FindAndReplaceDocument` | `RemoveEmptyFields`, `RemoveEmptyBlocks`, `RemoveEmptyImages`, `RemoveEmptyLines`, `RemoveTrailingWhitespace`, `MergeHtml`, `Culture` and the properties of `DocumentSettings`; a property left `null` keeps the default of the Web API |
| `DocumentSettings` | `AppendDocument` | `Author`, `CreationDate`, `CreatorApplication`, `DocumentSubject`, `DocumentTitle`, `LastModificationDate`, `UserPassword` |
| `AppendBody` | `AppendDocument` | `Documents`, a list of `AppendDocument` objects, each with the `Document` as a byte array and a `DocumentDivider` (`None`, `NewParagraph` or `NewSection`); `DocumentSettings` |
| `FindAndReplaceBody` | `FindAndReplaceDocument` | `FindAndReplaceData`, a `List<string[]>` of text to find and its replacement, `Template` and `MergeSettings` |

`GetDocumentThumbnails` and `GetTemplateThumbnails` take an `ImageFormat`: `JPG`, `PNG`, `BMP` or `GIF`.

### Platform Differences

The builds for the three target frameworks differ in these members:

| Member | .NET Framework 4.5 | .NET Standard 1.3 and .NET Core 1.1 |
|---|---|---|
| `GetDocumentThumbnails`, `GetTemplateThumbnails` | Return `List<System.Drawing.Image>` | Return `List<string>`, Base64-encoded images |
| `MergeSettings.Culture` | `System.Globalization.CultureInfo` | `string`, such as `"de-DE"` |
| `TrackedChange.HighlightColor`, `TrackedChange.DefaultHighlightColor` | `System.Drawing.Color` | `string` |

### Errors

The methods are synchronous: each one waits for the response before it returns. When the Web API answers with an error, the method throws an `ArgumentException` whose `Message` is the response body; the HTTP status code isn't passed on. A request that gets no answer, such as one to an unreachable server, throws an `AggregateException` that holds the `HttpRequestException`. [Errors and Status Codes](https://docs.textcontrol.com/reporting-cloud/document-processing/errors/llms-full.txt) lists the status codes and their causes, and its section [Handle Errors in the SDKs](https://docs.textcontrol.com/reporting-cloud/document-processing/errors/#handle-errors-in-the-sdks) tells the causes apart in code.

### API Documentation and Source

- **API documentation.** The [ReportingCloud .NET Wrapper API Documentation](https://textcontrol.github.io/TXTextControl.ReportingCloud.DotNet/api.html) describes every class, property and method of the namespace `TXTextControl.ReportingCloud`.
- **Source code.** The repository [TextControl/TXTextControl.ReportingCloud.DotNet](https://github.com/TextControl/TXTextControl.ReportingCloud.DotNet) holds the source under a BSD license and unit test projects for .NET Framework and .NET Core, which need the credentials of an account. Its last change to the code is from September 2, 2019, the day version 1.205.500 was published.

### Related Pages

- [SDKs](https://docs.textcontrol.com/reporting-cloud/sdks/llms-full.txt): the SDKs compared, with their status.
- [Installing an SDK](https://docs.textcontrol.com/reporting-cloud/installation/sdks/llms-full.txt): add the NuGet package to a project.
- [ASP.NET Core](https://docs.textcontrol.com/reporting-cloud/getting-started/dotnet/aspnet-core/llms-full.txt): a web application that merges a template with this package.
- [Authentication](https://docs.textcontrol.com/reporting-cloud/document-processing/authentication/llms-full.txt): API keys and Basic authentication.
- [Web API](https://docs.textcontrol.com/reporting-cloud/reference/web-api/llms-full.txt): the endpoints the methods call.

---

## Nearby

- **Previous:** [SDKs](https://docs.textcontrol.com/reporting-cloud/sdks/llms-full.txt)
- **Next:** [PHP](https://docs.textcontrol.com/reporting-cloud/sdks/php/llms-full.txt)
