FMData 5.0.0-beta.2

This is a prerelease version of FMData.
There is a newer version of this package available.
See the version list below for details.
dotnet add package FMData --version 5.0.0-beta.2
NuGet\Install-Package FMData -Version 5.0.0-beta.2
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="FMData" Version="5.0.0-beta.2" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add FMData --version 5.0.0-beta.2
#r "nuget: FMData, 5.0.0-beta.2"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install FMData as a Cake Addin
#addin nuget:?package=FMData&version=5.0.0-beta.2&prerelease

// Install FMData as a Cake Tool
#tool nuget:?package=FMData&version=5.0.0-beta.2&prerelease

FMData

FMData repository/commit activity the past year FMData issues Code size in bytes Language Count license

fmdata logo a C# client for FIleMaker

Package Build Status MyGet Nuget
FMData .NET CI Build Myget NuGet
FMData.Rest .NET CI Build MyGet Pre Release NuGet
FMData.Rest.Auth.FileMakerCloud .NET CI Build FMData.Rest.Auth.FileMakerCloud NuGet
FMData.Xml .NET CI Build FMData.Xml NuGet

There are plenty of ways to consume RESTful APIs from .NET, but the goal of this project is to provide a blended FileMaker-idiomatic and .NET-idiomatic experience for developers consuming data from FileMaker databases in .NET applications.

The project is organized as three packages.

  • FMData is the core and it contains the base and abstract classes utilized by the other implementations.
  • FMData.Rest is for the Data API and
    • FMData.Rest.Auth.FileMakerCloud is used for authentication to the Data API hosted by FileMaker Cloud
  • FMData.Xml is for consuming the legacy Xml/CWP API.

Note: Xml support is experimental, if you need full cwp/xml coverage check out fmDotNet.

If you've found a bug, please submit a bug report. If you have a feature idea, open an issue and consider creating a pull request.

Grade Activity License
CodeFactor FMData repository/commit activity license

Breaking changes

Version 5 has breaking changes. Please review the changes prior to updating your project.

Version 4 has several breaking changes. Please review the changes prior to updating your project.

Installation

Install via dotnet add or nuget. Stable releases are on NuGet and CI builds are on MyGet.

dotnet add package FMData.Rest

Example Usage

The recommended way to consume this library is using a strongly typed model as follows.

Setting up your model

A model should roughly match a table in your solution. Its accessed via layout.

// use the DataContract attribute to link your model to a layout
[DataContract(Name="NameOfYourLayout")]
public class Model
{
    [DataMember]
    public string Name { get; set; }

    // if your model name does not match use DataMember
    [DataMember(Name="overrideFieldName")] // the internal database field to use
    public string Address { get; set; }

    [DataMember]
    public string SomeContainerField { get; set; }

    // use the ContainerDataFor attribute to map container data to a byte[]
    [ContainerDataFor("SomeContainerField")] // use the name in your C# model
    public byte[] DataForSomeContainerField { get; set; }

    // if your model has properties you don't want mapped use
    [IgnoreDataMember] // to skip mapping of the field
    public string NotNeededField { get; set; }
}

Using IHttpClientFactory

Constructors take an HttpClient and you can setup the DI pipeline in Startup.cs like so for standard use:

services.AddSingleton<FMData.ConnectionInfo>(ci => new FMData.ConnectionInfo
{
    FmsUri = "https://example.com",
    Username = "user",
    Password = "password",
    Database = "FILE_NAME"
});
services.AddHttpClient<IFileMakerApiClient, FileMakerRestClient>();

If you prefer to use a singleton instance of IFileMakerApiClient you have to do a little bit more work in startup. This can improve performance if you're making lots of hits to the Data API over a single request to your application:

services.AddHttpClient(); // setup IHttpClientFactory in the DI container
services.AddSingleton<FMData.ConnectionInfo>(ci => new FMData.ConnectionInfo
{
    FmsUri = "https://example.com",
    Username = "user",
    Password = "password",
    Database = "FILE_NAME"
});
// Keep the FileMaker client as a singleton for speed
services.AddSingleton<IFileMakerApiClient, FileMakerRestClient>(s => {
    var hcf = s.GetRequiredService<IHttpClientFactory>();
    var ci = s.GetRequiredService<ConnectionInfo>();
    return new FileMakerRestClient(hcf.CreateClient(), ci);
});

Behind the scenes, the injected HttpClient is kept alive for the lifetime of the FMData client (rest/xml) and reused throughout. This is useful to manage the lifetime of IFileMakerApiClient as a singleton, since it stores data about FileMaker Data API tokens and reuses them as much as possible. Simply using services.AddHttpClient<IFileMakerApiClient, FileMakerRestClient>(); keeps the lifetime of our similar to that of a 'managed HttpClient' which works for simple scenarios.

Test both approaches in your solution and use what works.

Authentication with FileMaker Cloud

We can use the FileMakerRestClient, when the setup is done. Just create a new ConnectionInfo object and set the required properties:

var conn = new ConnectionInfo();
conn.FmsUri = "https://{NAME}.account.filemaker-cloud.com";
conn.Username = "user@domain.com";
conn.Password = "********";
conn.Database = "Reporting";

Then instantiate the FileMakerRestClient with a FileMakerCloudAuthTokenProvider as follows:

var fm = new FileMakerRestClient(new HttpClient(), new FileMakerCloudAuthTokenProvider(conn));

For a full description of using FileMaker Data API with FileMaker Cloud, see this comment.

Performing a Find

var client = new FileMakerRestClient("server", "fileName", "user", "pass"); // without .fmp12
var toFind = new Model { Name = "someName" };
var results = await client.FindAsync(toFind);
// results = IEnumerable<Model> matching with Name field matching "someName" as a FileMaker FindRequest.

Create a new record

var client = new FileMakerRestClient("server", "fileName", "user", "pass"); // without .fmp12
var toCreate = new Model { Name = "someName", Address = "123 Main Street" };
var results  = await client.CreateAsync(toCreate);
//  results is an ICreateResponse which indicates success (0/OK or Failure with FMS code/message)

Updating a record

var client = new FileMakerRestClient("server", "fileName", "user", "pass"); // without .fmp12
var fileMakerRecordId = 1; // this is the value from the calculation: Get(RecordID)
var toUpdate = new Model { Name = "someName", Address = "123 Main Street" };
var results = await client.EditAsync(fileMakerRecordId, toCreate);
//  results is an IEditResponse which indicates success (0/OK or Failure with FMS code/message)

Find with FileMaker Id Mapping

Note you need to add an int property to the Model public int FileMakerRecordId { get; set; } and provide the Func to the FindAsync method to tell FMData how to map the FileMaker Id returned from the API to your model.

Func<Model, int, object> FMRecordIdMapper = (o, id) => o.FileMakerRecordId = id;
var client = new FileMakerRestClient("server", "fileName", "user", "pass"); // without .fmp12
var toFind = new Model { Name = "someName" };
var results = await client.FindAsync(toFind, FMRecordIdMapper);
// results is IEnumerable<Model> matching with Name field matching "someName" as a FileMaker FindRequest.

Alternatively, if you create a calculated field Get(RecordID) and put it on your layout then map it the normal way.

Find and load Container Data

Make sure you use the [ContainerDataFor("NameOfContainer")] attribute along with a byte[] property for processing of your model.

var client = new FileMakerRestClient("server", "fileName", "user", "pass"); // without .fmp12
var toFind = new Model { Name = "someName" };
var results = await client.FindAsync(toFind);
await client.ProcessContainers(results);
// results = IEnumerable<Model> matching with Name field matching "someName" as a FileMaker FindRequest.

Insert or Update Container Data

// assume recordId = a FileMaker RecordId mapped using FMIdMapper
// assume containerDataByteArray is a byte array with file contents of some sort
var client = new FileMakerRestClient("server", "fileName", "user", "pass"); // without .fmp12
_client.UpdateContainerAsync(
    "layout",
    recordId,
    "containerFieldName",
    "filename.jpg/png/pdf/etc",
    containerDataByteArray);

Note: In order to create a record with container data two calls must be made. One that creates the actual record ( see above) and one that updates the container field contents.

FileMaker Documentation

Latest Versions

Older Versions

Versioning

We use Semantic Versioning. Using the Major.Minor.Patch syntax, we attempt to follow the basic rules

  1. MAJOR version when you make incompatible API changes,
  2. MINOR version when you add functionality in a backwards-compatible manner, and
  3. PATCH version when you make backwards-compatible bug fixes.
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp1.0 was computed.  netcoreapp1.1 was computed.  netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard1.3 is compatible.  netstandard1.4 was computed.  netstandard1.5 was computed.  netstandard1.6 was computed.  netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net45 is compatible.  net451 was computed.  net452 was computed.  net46 was computed.  net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen30 was computed.  tizen40 was computed.  tizen60 was computed. 
Universal Windows Platform uap was computed.  uap10.0 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (3)

Showing the top 3 NuGet packages that depend on FMData:

Package Downloads
FMData.Rest

A client library for accessing FileMaker databases using the FileMaker Data API (RESTful API) in FileMaker Server.

FMData.Xml

A client library for accessing FileMaker data through the Custom Web Publishing XML API in FileMaker Server.

FMData.Rest.Auth.FileMakerCloud

FileMaker Data API Authentication for FileMaker Cloud.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
5.2.0 815 1/23/2024
5.2.0-beta.0 152 12/5/2023
5.1.2 868 11/2/2023
5.1.1 812 8/23/2023
5.1.0 1,244 6/12/2023
5.0.0 2,765 10/12/2022
5.0.0-beta.3 162 9/17/2022
5.0.0-beta.2 127 9/12/2022
5.0.0-beta.1 152 8/2/2022
4.3.3 848 10/12/2022
4.3.2 1,364 10/29/2021
4.3.1 824 8/17/2021
4.3.0 1,217 2/16/2021
4.2.3 880 11/25/2020
4.2.2 1,553 3/10/2020
4.2.1 1,611 10/29/2019
4.2.0 851 10/21/2019
4.1.0 840 10/15/2019
4.0.2 1,136 9/23/2019
4.0.1 1,118 8/2/2019
4.0.0 1,100 6/13/2019
3.2.2 1,121 3/26/2019
3.2.1 1,216 1/18/2019
3.1.9 1,167 1/11/2019
3.1.8 1,132 12/31/2018
3.1.6 1,186 12/27/2018
3.0.0 1,029 12/19/2018
2.3.2 1,181 10/23/2018
2.3.1 1,110 10/22/2018
2.3.0 1,157 10/5/2018
2.2.0 1,158 9/13/2018
2.1.1 1,198 9/11/2018
2.1.0 1,224 9/5/2018
2.0.0 1,436 7/2/2018
1.0.5 1,072 5/7/2018