Previous videos showed passing a string and an entity reference, but the other parameters are missing an explanation. And while for some types, like integer, this might not be needed, but with complex types, like EntityCollection, it’s not that clear. So here is a reference for all possible inputs for Custom APIs and their respective outputs.
General concepts
The Actions Adapter needs to guess your input, so you will find, that for complex types, there is something chosen to identify them correctly. For example, both OptionSetValue (Picklist) and Money have a Value property in their definition in C#. But how would the Actions Adapter would decide what { Value: 3 }
is?* So instead { OptionSetValue: 3 }
and { Money: 3 }
make for a clear differentiation.
This concept does not apply to the outputs. They are pretty much left untouched and passed as is. So both an OptionSetValue as well as a Money field might be passed back to you as { Value: 3 }
assuming you know by the name of the output what field type is behind this.
*: The adapter could evaluate the Metadata to be sure, but that would have a performance impact with additional queries to Dynamics.
Field Types
For this article, I created a simple Custom API that returns all inputs to the outputs. For every type, there was an input and output defined named like the type. So both the Custom API Request Parameter
and Custom API Response Property
for the type String
are called String.
The following sections will show an example of an input object passing exactly one Custom API Request Parameter
and the construction of an output object with the corresponding Custom API Response Property
. Some sections may contain additional explanations.
String
var inputs = {
String: "Hello"
}
var outputs = {
String: "Hello"
}
StringArray
var inputs = {
StringArray: ["Hello", "World"],
}
var outputs = {
StringArray: ["Hello", "World"],
}
Guid
If a string is parsable as Guid, it will be converted accordingly.
var inputs = {
Guid: "00000000-0000-0000-0000-000000000001"
}
var outputs = {
Guid: "00000000-0000-0000-0000-000000000001"
}
Integer
var inputs = {
Integer: 1
}
var outputs = {
Integer: 1
}
Float
var inputs = {
Float: 5.5
}
var outputs = {
Float: 5.5
}
Decimal
To mark something as a decimal, pass it as a string with an “m” at the end.
var inputs = {
Decimal: "10.4m"
}
var outputs = {
Decimal: 10.4
}
Boolean
var inputs = {
Boolean: true
}
var outputs = {
Boolean: true
}
DateTime
var inputs = {
DateTime: "2024-08-03T15:27:41Z"
}
var outputs = {
DateTime: "2024-08-03T15:27:41Z"
}
Picklist
Notice here that the required property for the input is OptionSetValue
while in the output it is called Value
.
var inputs = {
Picklist: {
OptionSetValue: 1
}
}
var outputs = {
Picklist: {
Value: 1
}
}
Money
Notice here that the required property for the input is Money
while in the output it is called Value
.
var inputs = {
Money: {
Money: 7.8
}
}
var outputs = {
Money: {
Value: 7.8
}
}
EntityReference
To be recognized as an EntityReference, the properties LogicalName
and Id
should be present.
var inputs = {
EntityReference: {
LogicalName: "contact",
Id: "4121902e-0530-ef11-8409-6045bd9e7366"
}
}
var outputs = {
EntityReference: {
Id: "4121902e-0530-ef11-8409-6045bd9e7366",
LogicalName: "contact",
Name: null,
KeyAttributes: [],
RowVersion: null
}
}
Entity
To be recognized as an Entity, the properties LogicalName
and Attributes
should be present. Id
is optional but is displayed here as a common use case.
var inputs = {
Entity: {
LogicalName: "contact",
Id: "4121902e-0530-ef11-8409-6045bd9e7366",
Attributes: {
firstname: "Marius",
lastname: "Wodtke"
}
}
}
var outputs = {
Entity: {
Id: "4121902e-0530-ef11-8409-6045bd9e7366",
LogicalName: "contact",
Attributes: [
{
Key: "firstname",
Value: "Marius"
},
{
Key: "lastname",
Value: "Wodtke"
}
],
EntityState: null,
FormattedValues: [],
KeyAttributes: [],
RelatedEntities: []
RowVersion: null
}
}
EntityCollection
To be recognized as an EntityEntityCollection, the properties EntityName
and Entities
should be present. Entities
then contains Entity objects as seen above.
var inputs = {
EntityCollection: {
EntityName: "contact",
Entities: [
{
LogicalName: "contact",
Id: userid,
Attributes: {
firstname: "Marius",
lastname: "Wodtke"
}
}
]
}
}
var outputs = {
Entities: [
{
Id: "4121902e-0530-ef11-8409-6045bd9e7366",
LogicalName: "contact",
Attributes: [
{
Key: "firstname",
Value: "Marius"
},
{
Key: "lastname",
Value: "Wodtke"
}
],
EntityState: null,
FormattedValues: [],
KeyAttributes: [],
RelatedEntities: []
RowVersion: null
}
]
EntityName: "contact"
MinActiveRowVersion: null
MoreRecords: false
PagingCookie: null
TotalRecordCount: 0
TotalRecordCountLimitExceeded: false
}
Summary
The Power Pages Actions solution can handle all possible input types. Some types like Decimal might need special handling and complex parameters like Entity need extra care to ensure that the properties are named correctly.
The solution can hand out all possible output parameters. Here the properties are what you would find in C#.