Custom Connector as C# Sandbox for PowerAutomate Flow

Ever wanted to habe a Code Sandbox to run a script in Flow? I had this issue to calculate an SHA1 hash value which is not possible with builtin flow functions. Obvious solution would be to put it in an Azure Function. There is a solution by Valentin Gasenko to create a custom connector and utilize the Code feature.

You may create a custom connector that connects to nowhere😉 with a fake method and place C# code there. It has some limitations to an Azure Function e.g. you can’t install packages etc. but it might help for many other issues.

OpenAPI Definiton

Create a new OpenAPI Definition Swagger file that defines a method you would like to use in your flow. Here is an example for an API with a method called executeScript that takes a string as input and returns a string as output.

{
  "openapi": "3.0.0",
  "info": {
    "title": "Script Execution Service",
    "version": "1.0.0",
    "description": "A simple REST API that executes a script and returns text output."
  },
  "paths": {
    "/ExecuteScript": {
      "get": {
        "summary": "Executes a script and returns text output",
        "operationId": "executeScript",
        "parameters": [
          {
            "name": "input",
            "in": "query",
            "description": "The script input as a string",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful execution",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "output": {
                      "type": "string",
                      "description": "The output of the executed script"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input provided"
          }
        }
      }
    }
  }
}

Create a custom connector in PowerAutomate

In PowerAutomate create a new custom connector. You may have to lookup the custom connector link by clicking on “… More” on the left pane.

Enable Custom Connector in PowerAutomate

Create a new custom connector by importing the OpenAPI definition file. Provide name and description if you like. Make sure to set the Host to valid URL. It doesn’t matter if there is no real host with this name. I use fakeapi.local in my example.

Create a custom connector that connects to nowhere

Place C# code

Go to the Code section and enable code by selection the slider. Choose the method you want to use. In my example it’s the executeScript Method. Copy the C# code you want to execute in the code editor window below. This is an example code that reads the input parameter from the request and returns it in a Hello statement.

public class Script : ScriptBase
{
  public override async Task ExecuteAsync()
  {
    HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
    string url = this.Context.Request.RequestUri.PathAndQuery;
    string parsedUrl = url.Split('?')[1];

    var paramsCollection = HttpUtility.ParseQueryString(parsedUrl);
    string value = paramsCollection["input"];

    response.Content = CreateJsonContent("{\"message\": \"Hello "+value+"\"}");
    return response;
  }
}
Place C# script in the custom connectors code section

Save and Test

You have to select “Create Connector” before testing. If your code is not working you will get an error here. If the creation was successful you can test your connector.

Test C# sandbox in PowerAutomate

Use C# Sandbox in your Flow

Simply create a new flow or use an existing one. You we’ll find the connector under the custom connectors. In my example it has a single action to execute the code to which I pass the value of the variable Name.

Include C# sandbox in PowerAutomate Flow
C# code executed in PowerAutomate Flow

Like in the connector test scenario, it executes the C# script and returns Hello and the provided value.

Windows Mobile & CE

They say Windows Mobile is dead. I agree, its dead on the mobile phone market. However Mobile and CE legacy OS’ are still relevant to develop mobile applications on barcode reader and RFID reader / writer devices. Just to mention Smiley ..

scanner

Receive large texts via AIF

One of our customer’s business partner transmits data as XML file. However, they did not make it to use a structured xml document service, but send a string that (in most cases) contains a valid xml document. Therefore we’ve setup an AIF service, using a class that takes one str parameter called _txt and stores it at a memo field.

public void storeText(str _text)
{
    AifBigData bigData;
    ;
    bigData.Text = _text;
    bigData.insert();
}

However, the business partner recently told us they get an error message while transmitting data to the AIF service telling them the transmitted data is too large. We were able to reproduce the issues by calling the service using a larger random-generated text.

class Program
{
    static void Main(string[] args)
    {
        var client = new BigData.BigDataServiceClient();
        client.ClientCredentials.Windows.ClientCredential = new
         System.Net.NetworkCredential("user","pass123","domain");

        // works fine
        client.storeText("Hello World");

        // fails 😦
        string txt = GenerateBigText();
        client.storeText(txt);
    }

    private static string GenerateBigText()
    {
        var random = new Random(); 
        var sb = new StringBuilder();
        for (int i = 0; i < 61440; i++)
        {
            char c =  (char)random.Next(65, 122);
            sb.Append(c);
        }

        return sb.ToString();
    }
}

The second call results in an exception

The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://insideax.at/bigdata:_text. The maximum string content length quota (8192) has been exceeded while reading XML data. This quota may be increased by changing the MaxStringContentLength property on the XmlDictionaryReaderQuotas object used when creating the XML reader.

However, the exception is well explained and contains a solution proposal to set the MaxStringContentLength

Go to Basic > AIF > Services > Button Configure

image

Select Binding > basicHTTPBinding > ReaderQuotas > MaxStringContentLenght and set e.g. 2147483647

image

Save and generate the .NET artifacts. Open windows explorer and navigate to the AIF virtual directory e.g. C:\Program Files\Microsoft Dynamics AX\50\AifWebServices . Select the web.config and open it with internet explorer. Make sure the MaxStringContentLength value is set

image

With this configuration the service call will work and a large text message is stored properly in Dynamics AX

image

Make Motorola/Symbol 9090 Scanner scan

I was recently working on a Motorola 9090 scanner device, loaded with Windows Mobile 6.5, developing a .NET Compact Framework application. Most scanner devices automatically trigger the scanner when pressing the scan button and write the decoded barcode text in any text field or document. This device didn’t and there was no preinstalled scanner tool to configure the devices behavior. However, there is a nice application called DataWegde provided by Motorola to make the scanner scan without using any obscure APIs.

Connect a Windows Mobile Device with Dynamics AX

It’s easy to connect a mobile device like a smartphone with Dynamics AX using web services. This tutorial requires Microsoft Dynamics AX 2009 with AIF Webservices installed and Visual Studio for Smart Device development.

Deploy AIF Service

  1. Go to Basic → Setup → Application Integration Framework → Services
  2. Select Refresh button to update service list
  3. Enable CustCustomerService
  4. Generate the webservice

    Aif Services

    Aif Service

  5. To verify your service is working open the IIS manager
  6. Go to → Sites → Default Web Site  → MicrosoftDynamicsAxAif50  → Content View

    IIS 7 Manager on Windows Server 2008

    IIS 7 Manager on Windows Server 2008

  7. Right Click on CustomerSerivce.svc and Browser
  8. You should see a web page with a link to a WSDL file
  9. Follow the link an you should see an XML document containing the service contract

Implement Mobile Device Project

  1. Open Visual Studio and Create a new Solution
  2. Add a new Smart Device Project
  3. Go to References and add a new service reference
  4. Provide the URL of your Dynamics AX CustomerService
  5. Open Form1.cs file
  6. Add a text field (Name: textBoxAccountNum),
    a button (Name: buttonLookup)
    and a label (Name: labelName) to your form
  7. Double Click on the button and implement the service call:
private void buttonLookup_Click(object sender, EventArgs e)
{
    System.Net.NetworkCredential credentials = new System.Net.NetworkCredential();
    credentials.Domain = "YOUR_DOMAIN_NAME";
    credentials.UserName = "YOUR_USER_NAME";
    credentials.Password = "YOUR_USER_PASSWORD";

    QueryCriteria query = new QueryCriteria();
    query.CriteriaElement = new CriteriaElement[1];
    query.CriteriaElement[0] = new CriteriaElement();
    query.CriteriaElement[0].DataSourceName = "CustTable";
    query.CriteriaElement[0].FieldName = "AccountNum";
    query.CriteriaElement[0].Operator = Operator.Equal;
    query.CriteriaElement[0].Value1 = textBoxAccountNum.Text;

    CustomerService service = new CustomerService();
    service.Credentials = credentials;
    try
    {
        AxdCustomer customer = service.find(query);
        if (customer != null &&
            customer.CustTable != null &&
            customer.CustTable.Length > 0)
        {
            labelName.Text = customer.CustTable[0].Name;
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("Service Call failed",
                        "Error",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Hand,
                        MessageBoxDefaultButton.Button1);               
    }           
}

You application should look like that:

Windows Mobile 5 Emulator

Windows Mobile 5 Emulator