FMData.Rest
4.3.1
See the version list below for details.
dotnet add package FMData.Rest --version 4.3.1
NuGet\Install-Package FMData.Rest -Version 4.3.1
<PackageReference Include="FMData.Rest" Version="4.3.1" />
paket add FMData.Rest --version 4.3.1
#r "nuget: FMData.Rest, 4.3.1"
// Install FMData.Rest as a Cake Addin
#addin nuget:?package=FMData.Rest&version=4.3.1
// Install FMData.Rest as a Cake Tool
#tool nuget:?package=FMData.Rest&version=4.3.1
Package | Build Status | MyGet | Nuget |
---|---|---|---|
FMData | |||
FMData.Rest | |||
FMData.Xml |
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 andFMData.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.
Tests | Grade | Activity | License |
---|---|---|---|
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.
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
- FileMaker Data API Documentation (FMS18)
- FileMaker Server 18 Custom Web Publishing Guide
- FileMaker Data API Documentation (FMS17)
- FileMaker REST API Documentation (FMS16) -- Not Supported by this project.
- FileMaker Server 16 Web Publishing Guide
- FileMaker Server 15 Web Publishing Guide
Versioning
We use Semantic Versioning. Using the Major.Minor.Patch syntax, we attempt to follow the basic rules
- MAJOR version when you make incompatible API changes,
- MINOR version when you add functionality in a backwards-compatible manner, and
- PATCH version when you make backwards-compatible bug fixes.
Repository Statistics
Product | Versions |
---|---|
.NET | net5.0 net5.0-windows net6.0 net6.0-android net6.0-ios net6.0-maccatalyst net6.0-macos net6.0-tvos net6.0-windows net7.0 net7.0-android net7.0-ios net7.0-maccatalyst net7.0-macos net7.0-tvos net7.0-windows |
.NET Core | netcoreapp1.0 netcoreapp1.1 netcoreapp2.0 netcoreapp2.1 netcoreapp2.2 netcoreapp3.0 netcoreapp3.1 |
.NET Standard | netstandard1.3 netstandard1.4 netstandard1.5 netstandard1.6 netstandard2.0 netstandard2.1 |
.NET Framework | net45 net451 net452 net46 net461 net462 net463 net47 net471 net472 net48 net481 |
MonoAndroid | monoandroid |
MonoMac | monomac |
MonoTouch | monotouch |
Tizen | tizen30 tizen40 tizen60 |
Universal Windows Platform | uap uap10.0 |
Xamarin.iOS | xamarinios |
Xamarin.Mac | xamarinmac |
Xamarin.TVOS | xamarintvos |
Xamarin.WatchOS | xamarinwatchos |
-
.NETFramework 4.5
- FMData (>= 4.3.1)
- Newtonsoft.Json (>= 13.0.1)
- System.ValueTuple (>= 4.5.0)
-
.NETStandard 1.3
- FMData (>= 4.3.1)
- NETStandard.Library (>= 1.6.1)
- Newtonsoft.Json (>= 13.0.1)
- System.Net.Http (>= 4.3.4)
- System.ValueTuple (>= 4.5.0)
-
.NETStandard 2.0
- FMData (>= 4.3.1)
- Newtonsoft.Json (>= 13.0.1)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on FMData.Rest:
Package | Downloads |
---|---|
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.0.0 | 1,218 | 10/12/2022 |
5.0.0-beta.3 | 79 | 9/17/2022 |
5.0.0-beta.2 | 66 | 9/12/2022 |
5.0.0-beta.1 | 83 | 8/2/2022 |
4.3.3 | 264 | 10/12/2022 |
4.3.2 | 900 | 10/29/2021 |
4.3.1 | 429 | 8/17/2021 |
4.3.0 | 559 | 2/16/2021 |
4.2.3 | 497 | 11/25/2020 |
4.2.2 | 1,035 | 3/10/2020 |
4.2.1 | 1,170 | 10/29/2019 |
4.2.0 | 416 | 10/21/2019 |
4.1.0 | 429 | 10/15/2019 |
4.0.2 | 586 | 9/23/2019 |
4.0.1 | 468 | 8/2/2019 |
4.0.0 | 728 | 6/13/2019 |
3.2.2 | 614 | 3/26/2019 |
3.2.1 | 588 | 1/18/2019 |
3.1.9 | 610 | 1/11/2019 |
3.1.8 | 581 | 12/31/2018 |
3.1.6 | 577 | 12/27/2018 |
3.0.0 | 534 | 12/19/2018 |
2.3.2 | 670 | 10/23/2018 |
2.3.1 | 631 | 10/22/2018 |
2.3.0 | 611 | 10/5/2018 |
2.2.0 | 638 | 9/13/2018 |
2.1.1 | 620 | 9/11/2018 |
2.1.0 | 672 | 9/5/2018 |
2.0.0 | 803 | 7/2/2018 |