Work with all available parameter types in Custom API

By | March 10, 2021

Introduction

In our previous blog, we have shown brief of custom API and have executed one Custom API request. In this blog, we will be discussing about the different data types available for the Custom API. We will also be explaining to you each one of them, and how we can incorporate it into our solution.

We have already created parameters with all the data types and for the reference to create parameters you have to have one Custom API. For that Custom API you can create Custom API request Parameters and Custom API Response Properties.

Move to Make.Powerapps.com>>Solutions>>Open your solution and Add New Item>>Select Custom API, Custom API Request Parameter or Custom API Response Property. The form will appear as shown below.

execute all available data types in Custom API

Following are the data types available at the time of writing this blog for the custom API request parameter and custom API response property

• Value: 0 Label: Boolean
• Value: 1 Label: DateTime
• Value: 2 Label: Decimal
• Value: 3 Label: Entity
• Value: 4 Label: EntityCollection
• Value: 5 Label: EntityReference
• Value: 6 Label: Float
• Value: 7 Label: Integer
• Value: 8 Label: Money
• Value: 9 Label: Picklist
• Value: 10 Label: String
• Value: 11 Label: StringArray
• Value: 12 Label: Guid

We will see each different type of data type with an example.

As mentioned above, we have already created Custom API and its parameters. The below Image shows the metadata information of the Custom API Action

execute all available data types in Custom API

1) Entity Logical Name can only be set for Entity and Entity Reference type of parameter on Custom API Request Parameter form.
2) Entity Logical Name field is optional even if the parameter type is Entity or Entity Reference.
3) If you set Entity Logical Name for any Entity and Entity Reference then it must only contain defined Entity data and Entity Reference.
4) Picklist and integer type parameter defined as the same in metadata similarly Decimal and Money type are same in metadata

Please Note: – Executing Custom API from plugin and workflow are very straightforward so we will not be looking into that. We will check in the script how we can execute our Custom API with all possible parameters.

We will be using the Xrm.WebApi.online.execute function to execute our Custom API and in order to execute, we have to create a Request and that request must define our parameter types using Entity Data Model. e.g. Edm.String
Parameter Types require three properties viz enumProperties(Optional), structuralProperty and typeName. For more details, refer to this.

Structural Property: Structural Property is divided into 5 category and we have to define the value of one them for each parameter.

• Value 0 for Unknown
• Value 1 for Primitive Type
• Value 2 for Complex Type
• Value 3 for Enumeration Type
• Value 4 for Collection
• Value 5 for Entity Type

Type Name: Must be string and it is the qualified name of the parameter type. (Shown into the above image. e.g. Edm.Double )

For Boolean, String, Double, Decimal, Money (Decimal), Date Time, Float, and Integer:

1) Passing as Input Parameter from the script:

var Sdk = window.Sdk || {};
Sdk.PrimitiveRequest = function(stringattribute ,datetimeattribute,moneyattribute,booleanattribute,floatattribute,integerattribute) {
this.stringattribute = stringattribute;
this.datetimeattribute = datetimeattribute;
this.moneyattribute = moneyattribute;
this.booleanattribute = booleanattribute;
this.floatattribute = floatattribute;
this.integerattribute =integerattribute;
};
// NOTE: The getMetadata property should be attached to the function prototype instead of the
// function object itself.
Sdk.PrimitiveRequest.prototype.getMetadata = function () {
return {
boundParameter: null,
parameterTypes: {
“stringattribute”: {
“typeName”: “Edm.String”,
“structuralProperty”: 1 // Primitive Type
},
“datetimeattribute”: {
“typeName”: “Edm.DateTimeOffset”,
“structuralProperty”: 1 // Primitive Type
},
“moneyattribute”: {
“typeName”: “Edm.Decimal”,
“structuralProperty”: 1 // Primitive Type
},
“booleanattribute”: {
“typeName”: “Edm.Boolean”,
“structuralProperty”: 1 // Primitive Type
},
“floatattribute”: {
“typeName”: “Edm.Double”,
“structuralProperty”: 1 // Primitive Type
},
“integerattribute”: {
“typeName”: “Edm.Int32”,
“structuralProperty”: 1 // Primitive Type
}
},
operationType: 0, // This is an action. Use ‘1’ for functions and ‘2’ for CRUD
operationName: “new_passandretrievealldatatypes”,
};
};
var request =new Sdk.PrimitiveRequest(“string value”,new Date(),500,true,20.5,5);
var result = await Xrm.WebApi.online.execute(request);

2) Read and pass as output parameter from plugin

public void Execute(IServiceProvider serviceProvider)
{
try
{ // tracing object
ITracingService tracing = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
// ExecutionContext object
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
// object Organization service factory object
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
// object organization object
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

//check the key is present
//Check the input parameter of string type
if (context.InputParameters.Contains(“stringattribute”))
{
string inputString = context.InputParameters[“stringattribute”] as string;
tracing.Trace($”String Input {inputString}”);
//Pass string attribute to the output parameter
context.OutputParameters[“stringresponse”] = $”This is the response of string parameter {inputString}”;
}
//Check the input parameter of Money type
if (context.InputParameters.Contains(“moneyattribute”))
{
Money moneyValue = context.InputParameters[“moneyattribute”] as Money;
tracing.Trace($”Money input value {(moneyValue != null ? moneyValue.Value.ToString() : ” : Money value is null “)}”);
//Pass money value in the output parameter
context.OutputParameters[“moneyresponse”] = moneyValue;
}
//Check the input parameter of boolean type
if (context.InputParameters.Contains(“booleanattribute”))
{
bool booleanAttributeInput = Convert.ToBoolean(context.InputParameters[“booleanattribute”]);
tracing.Trace($”Boolean input value : {booleanAttributeInput}”);
//Pass the boolean value to output parameter
context.OutputParameters[“booleanresponse”] = booleanAttributeInput;
}
//Check the input parameter of Date and Time type
if (context.InputParameters.Contains(“datetimeattribute”))
{
DateTime dateInput = Convert.ToDateTime(context.InputParameters[“datetimeattribute”]);
tracing.Trace($”Date and Time input value : {dateInput}”);
//pass guid to output parameter
context.OutputParameters[“datetimeresponse”] = dateInput;
}
//Check the input parameter of integer type
if (context.InputParameters.Contains(“integerattribute”))
{
int integerInput = Convert.ToInt32(context.InputParameters[“integerattribute”]);
tracing.Trace($”integer input value : {integerInput}”);
//pass interger output parameter
context.OutputParameters[“integerresponse”] = integerInput;
}
//Check the input parameter of double type
if (context.InputParameters.Contains(“floatattribute”))
{
double doubleValue = Convert.ToDouble(context.InputParameters[“floatattribute”]);
tracing.Trace($”value in double : {doubleValue}”);
//pass double output parameter
context.OutputParameters[“floatresponse”] = doubleValue;
}

}
catch (Exception ex)
{
throw new InvalidPluginExecutionException(ex.InnerException != null && ex.InnerException.Message != null ? ex.InnerException.Message : ex.Message);
}

}

For Guid, StringArray, Entity, EntityCollection, EntityReference, PickList:

1) Passing as Input Parameter from script:

var Sdk = window.Sdk || {};
Sdk.Request = function(stringarrayattribute,entityattribute,entitycollectionattribute,entityreferenceattribute,guidattribute,picklistattribute) {
this.stringarrayattribute = stringarrayattribute;
this.entitycollectionattribute = entitycollectionattribute;
this.entityreferenceattribute = entityreferenceattribute;
this.entityattribute = entityattribute;
this.guidattribute = guidattribute;
this.picklistattribute = picklistattribute;
};

// NOTE: The getMetadata property should be attached to the function prototype instead of the
// function object itself.
Sdk.Request.prototype.getMetadata = function () {
return {
boundParameter: null,
parameterTypes: {
“stringarrayattribute”: {
“typeName”: “Collection(Edm.String)”,
“structuralProperty”: 4 // Enumeration
},
“entityattribute”: {
“typeName”: “mscrm.crmbaseentity”,
“structuralProperty”: 5 // Entity Type
},
“entitycollectionattribute”: {
“typeName”: “Collection(mscrm.crmbaseentity)”,
“structuralProperty”: 4 // Collection
},
“entityreferenceattribute”:{
“typeName”: “mscrm.crmbaseentity”,
“structuralProperty”: 5 // Entity Type
},
“guidattribute”:{
“typeName”: “Edm.Guid”,
“structuralProperty”: 1 // Primitive Type
},
“picklistattribute”:{
“typeName”: “Edm.Int32”,
“structuralProperty”: 1 // Primitive Type
}
},
operationType: 0, // This is an action. Use ‘1’ for functions and ‘2’ for CRUD
operationName: “new_passandretrievealldatatypes”,
};
};
//Define Entity Record
var contactRecord = {
“@odata.type”: “Microsoft.Dynamics.CRM.contact”,
“firstname”: “Test”,
“lastname”: “Account”
};
//Define Entity Collection
var entityCollection = [contactRecord];
//Define Entity reference
var entityRef = {
“@odata.type”: “Microsoft.Dynamics.CRM.contact”,
“contactid”: “d6208772-d545-eb11-a813-0022481eae24”
};
//Define String Array
var stringArray =[“str1″,”str2″,”str3”];
//Define Guid
guid={guid: “E8C656B7-6AD1-E811-A967-000D3A30D5DB”};
//pass all parameter to request object created.
var requestObj=new Sdk.Request(stringArray,contactRecord,[contactRecord],contactref,guidParameter,5);
var result = await Xrm.WebApi.online.execute(requestObj);
var response =await result.json();

2) Read and pass as output parameter from plugin:

public void Execute(IServiceProvider serviceProvider)
{
try
{ // tracing object
ITracingService tracing = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
// ExecutionContext object
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
// object Organization service factory object
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
// object organization object
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

//check the key is present
//Check the input parameter of PickList type
if (context.InputParameters.Contains(“picklistattribute”))
{
OptionSetValue optionSetInput = context.InputParameters[“picklistattribute”] as OptionSetValue;
tracing.Trace($”Pick List input value : {(optionSetInput != null? optionSetInput.Value.ToString(): “option set value is null”)}”);
//pass optionset value parameter
context.OutputParameters[“picklistresponse”] = optionSetInput != null ? optionSetInput.Value : 0;
}
//Check the input parameter of StringArray type
if (context.InputParameters.Contains(“stringarrayattribute”))
{
string[] inputArrayString = context.InputParameters[“stringarrayattribute”] as string[];
tracing.Trace($”Array Of String Value {string.Join(“,”, inputArrayString)}”);
//Pass string array attribute to the output parameter
context.OutputParameters[“stringarrayresponse”] = new string[] { “Response data provided” };
}
//Check the input parameter of Entity type
if (context.InputParameters.Contains(“entityattribute”))
{
Entity entity = context.InputParameters[“entityattribute”] as Entity;

tracing.Trace($”EntityId Input {(entity != null ? entity.Id.ToString() : “Entity input is null”)}”);
//Pass entity Attribute to the output parameter
context.OutputParameters[“entityresponse”] = entity;
}
//Check the input parameter of Entity Collection type
if (context.InputParameters.Contains(“entitycollectionattribute”))
{
EntityCollection entityColl = context.InputParameters[“entitycollectionattribute”] as EntityCollection;
tracing.Trace($”Entity Collection count {(entityColl != null ? entityColl.TotalRecordCount.ToString() : “Entity Collection is null “)}”);
//pass entity collection to the output parameter
context.OutputParameters[“entitycollectionresponse”] = entityColl;
}
//Check the input parameter of Entity Reference type
if (context.InputParameters.Contains(“entityreferenceattribute”))
{
EntityReference entityRef = context.InputParameters[“entityreferenceattribute”] as EntityReference;
tracing.Trace($”Entity Refernce {(entityRef != null ? entityRef.Id.ToString() : ” : Entity Ref is null “)}”);
//Should be contact
context.OutputParameters[“entityreferenceresponse”] = entityRef;
}
//Check the input parameter of Guid type
if (context.InputParameters.Contains(“guidattribute”))
{
Guid guidInput = new Guid(Convert.ToString( context.InputParameters[“guidattribute”]));
tracing.Trace($”Guid input value : {guidInput}”);
//pass guid to output parameter
context.OutputParameters[“guidresponse”] = guidInput;
}
}
catch (Exception ex)
{
throw new InvalidPluginExecutionException(ex.InnerException != null && ex.InnerException.Message != null ? ex.InnerException.Message : ex.Message);
}
}

Conclusion

Above, we have shown how we can use and execute our Custom API with all possible parameters. In the next blog we will be checking how we can register other plugins on the custom API.

2 thoughts on “Work with all available parameter types in Custom API

  1. s.

    I am not being able to get the stringarrayattribute . I keep receiveing a message: Resource not found for the segment. In the custom Api I set the parameter as EntityCollection, is this right ?
    thanks
    S.

    1. inogic

      In order to set the stringarrayattribute type of Custom API Request Parameter you need to select StringArray in the Type dropdown field as shown in below screenshot.

      StringArray

      In Custom API you have set parameter as EntityCollection because of which you are getting this error.

      Also, while executing the Custom API through code you need to specify the datatype of the request parameter as “Collection(Edm.String)” in the getMetaData property for StringArray type of request parameter in Custom API.

      Hope this helps!

Comments are closed.