As I play around with leveraging code in custom connectors more and more, I just love the possibilities it offers.
One of the original posts I saw was from Alex Shlega where he gives an example sorting an array. Wow this is great! But what if my array is not an array of just string values? What if it has numbers, or complex values, or nulls, etc.?
So I extended his example a bit using custom sorting logic, and added the ability to choose your desired sort order.

Let’s see how that works.
(Please see my other posts where I discuss a few more details on using the custom connector UI and where to apply the YAML and C# script code when building the Regular Expression custom action and add some enhancements.)
Action Definition
Here’s what our custom action can do:
swagger: '2.0'
info: {title: SteelCut Bytes Actions, description: SteelCut Bytes Power Automate Actions,
version: '1.0'}
host: flow.steelcutbytes.com
basePath: /
schemes: [https]
consumes: []
produces: []
paths:
/SortArray:
post:
responses:
default:
description: default
schema:
type: array
items: {}
description: Sorted array
title: Sorted Array
summary: Sort array
operationId: SortArray
description: Sorts the array values using both String and Numeric comparison.
parameters:
- name: value
in: body
required: true
schema:
type: object
properties:
items:
type: array
items: {}
description: Unsorted chaotic array of values
title: Chaotic Array
sort:
title: Sort Order
type: string
enum: [Ascending, Descending, Reverse]
default: Ascending
required: [items, sort]
definitions: {}
parameters: {}
responses: {}
securityDefinitions: {}
security: []
tags: []
Normally, you want to be as specific as possible in the types used in the YAML definition. But, since we are allowing an array of multiple data types (string, numbers, null, objects, etc.) it pays to be vague in this case.
Secret sauce:
Declaring both our input and output array items without a type (items: {}
) allows both our action and code to receive our array of varying data types.
Code
Here’s the C# code for the sorting logic:
public class Script : ScriptBase
{
public override async Task<HttpResponseMessage> ExecuteAsync()
{
switch (this.Context.OperationId)
{
case "SortArray":
return await this.HandleSortArray().ConfigureAwait(false);
}
var response = new HttpResponseMessage(HttpStatusCode.BadRequest);
response.Content = CreateJsonContent($"Unknown operation ID '{this.Context.OperationId}'");
return response;
}
private async Task<HttpResponseMessage> HandleSortArray()
{
var contentAsString = await this.Context.Request.Content.ReadAsStringAsync().ConfigureAwait(false);
var contentAsJson = JObject.Parse(contentAsString);
var stringJArray = (JArray)contentAsJson["items"];
var sortOrder = (string)contentAsJson["sort"];
var objectList = stringJArray.ToObject<List<Object>>();
switch (sortOrder)
{
case "Ascending":
case "Descending":
objectList.Sort((x, y) =>
{
var strX = (x == null ? null : x.ToString());
var strY = (y == null ? null : y.ToString());
decimal decX, decY;
if (decimal.TryParse(strX, out decX) && decimal.TryParse(strY, out decY))
return (decX > decY) ? 1 : (decX < decY) ? -1 : 0;
else
return StringComparer.Ordinal.Compare(strX, strY);
});
break;
}
if (sortOrder != "Ascending")
objectList.Reverse();
var result = JArray.FromObject(objectList);
var response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = CreateJsonContent(result.ToString());
return response;
}
}
The updates I’ve made to Alex Shlega’s example are highlighted in the code above. I’ll quickly explain those.
The first thing I do is make sure the JSON is converted to an array of objects and not strings.
var objectList = stringJArray.ToObject<List<Object>>();
This ensures that the types of numbers and other non-string data are preserved so that the sorting logic will distinguish them correctly. This comes in handy when sorting numbers in logical numeric order instead of string order, i.e. 0, 1, 2, 10
instead of "0", "1", "10", "2"
, and when handling null
values.
Next I handle the sort logic, using the .NET Enumerable.Sort(...)
extension method.
objectList.Sort((x, y) =>
{
var strX = (x == null ? null : x.ToString());
var strY = (y == null ? null : y.ToString());
decimal decX, decY;
if (decimal.TryParse(strX, out decX) && decimal.TryParse(strY, out decY))
return (decX > decY) ? 1 : (decX < decY) ? -1 : 0;
else
return StringComparer.Ordinal.Compare(strX, strY);
});
To handle both integer and float number types, I check if the values are decimal
using TryParse(...)
, and when true
, I sort according to numeric logic.
If not numeric, then I treat all other types as a string (or null
) and sort according to string sorting logic using StringComparer.Ordinal.Compare(...)
.
Here’s the output of the enhanced sort logic:

Simple as that!
But … it can be better!
This is definitely just a quick and easy sort. My main focus was on handling numbers correctly, empty strings, and null
values.
When showing this to one of my brilliant co-workers (Reza Dorrani, thank you!) he suggested an enhancement to handle more complex data type scenarios, such as sorting objects by a specific property value.
This is on my to-do and will be the source of a future post.
Happy coding!
Follow My Blog
Get new content delivered directly to your inbox.