CRMScript HTTP call to Azure Function returns empty response (works in Postman and C#)

lock
push_pin
done
Besvaret
10

Hi everyone,

I'm currently trying to make a GET request from CRMScript to an Azure Function endpoint (*.azurewebsites.net).
The call works perfectly when I test it using Postman and with a simple C# console app.
However, when I try it using CRMScript, the response is empty.

What I'm doing

  • The function expects a requestid to be sent in the body.

  • Headers include Accept: application/json and a x-functions-key.

  • I've tried both GET and POST methods in CRMScript.

    JSONBuilder payload;
    payload.pushObject("");
    payload.addString("requestid", "example-request-id-1234"); //I get the requestid from the first function which also is a request to azurewebsites.
    payload.popLevel();
    
    printLine(payload.getString());
    
    HTTP httpClient;
    httpClient.addHeader("Accept", "application/json");
    httpClient.addHeader("Content-Type", "application/json; charset=utf-8");
    httpClient.addHeader("x-functions-key", "example-functions-key");
    httpClient.setOption("parameters", "?" + payload.getString());
    
    String response = String(httpClient.post("https://example-function.azurewebsites.net/api/MyFunctionEndpoint"));
    
    printLine("Response: " + response);
    

But response is always empty.

🔹 How it works correctly in C# (for comparison)

Here’s a minimal C# example that works correctly:

static async Task Main(string[] args) {
    var client = new HttpClient();
    var request = new HttpRequestMessage(HttpMethod.Get, "https://example-function.azurewebsites.net/api/MyFunctionEndpoint");
    request.Headers.Add("Accept", "application/json");
    request.Headers.Add("x-functions-key", "example-functions-key");
    
    var content = new StringContent("{ \"requestid\": \"example-request-id-1234\" }", null, "application/json");
    request.Content = content;
    
    var response = await client.SendAsync(request);
    response.EnsureSuccessStatusCode();
    Console.WriteLine(await response.Content.ReadAsStringAsync());
}

 

What am I doing wrong here ?

Just to add little preface. I'm trying first to trigger an azure job with crmscript, this works fine and then i use the request id from the response in trigging the azure job to check the status which for some odd reason does not work.

29. apr. 2025 | 02.22 PM

Alle Svar (10)

Hi,

Try enable http debug mode and printing the results from that:

HTTP httpClient;
httpClient.setDebugMode(true);

httpClient.addHeader("Accept", "application/json");
httpClient.addHeader("Content-Type", "application/json; charset=utf-8");
httpClient.addHeader("x-functions-key", "example-functions-key");
httpClient.setOption("parameters", "?" + payload.getString());

String response = String(httpClient.post("https://example-function.azurewebsites.net/api/MyFunctionEndpoint"));

printLine("Response: " + response);

printLine(http.getDebug());
printLine(http.getErrorMessage());

Map headers = http.getResponseHeaders();

for (headers.first(); !headers.eof(); headers.next())
{
  	printLine (headers.getKey() + " => " + headers.getVal());
}
29. apr. 2025 | 03.21 PM

Hi Ummair!

try adding the status code to the  output and see if it is 200. 

String statusCode = httpClient.getValue("statusCode");

printLine(statusCode + "-" + response);
 
Alternatively, use https://webhook.site to inspect what is being sent. Example:
 
#setLanguageLevel 4;

/*
{
  "status": "success",
  "data": {
    "authToken": "b0akv5svtdyTGiuWYAtAf1tt-D5ck4VJUrJWALVUR3L",
    "userId": "ksyrss7Ktue72o2XX"
  }
}
*/

String postUrl = "https://webhook.site/3595942d-0425-4638-9eb4-1573dbb2b5b6";
JSONBuilder jb;
jb.pushObject("");
jb.addString("status", "success" );
jb.pushObject("data");
jb.addString("authToken", "b0akv5svtdyTGiuWYAtAf1tt-D5ck4VJUrJWALVUR3L");
jb.addString("userId", "ksyrss7Ktue72o2XX");
jb.popLevel();
jb.popLevel();

String jsonString = jb.getString();
//print(jsonString);

HTTP httpPost;
httpPost.addHeader("Content-Type", "Application/json");
httpPost.addHeader("x-functions-key", "example-functions-key");

httpPost.setOption("parameters","?"+ jsonString);

String resPost = String(httpPost.post(postUrl));
String statusCode = httpPost.getValue("statusCode");

printLine(statusCode+""+resPost);


Best regards
29. apr. 2025 | 03.22 PM

Hey Tony and David. 

Adding status didnt make any difference.

Debug gives this (removed sensitive keywords)

== Info
  Trying 10.xx.xx.xx:3128...

== Info
CONNECT tunnel: HTTP/1.1 negotiated

== Info
allocate connect buffer

== Info
Establish HTTP proxy tunnel to function-host.example.net:443

=> Send header
CONNECT function-host.example.net:443 HTTP/1.1
Host: function-host.example.net:443
Proxy-Connection: Keep-Alive

<= Recv header
HTTP/1.1 200 Connection established

<= Recv header

== Info
CONNECT phase completed

== Info
CONNECT tunnel established, response 200

== Info
ALPN: curl offers http/1.1

== Info
TLSv1.3 (OUT), TLS handshake, Client hello (1):

== Info
 CAfile: ..\..\..\CS\curl-ca-bundle.crt

== Info
 CApath: none

== Info
TLSv1.3 (IN), TLS handshake, Server hello (2):

== Info
TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):

== Info
TLSv1.3 (OUT), TLS handshake, Client hello (1):

== Info
TLSv1.3 (IN), TLS change cipher, Change cipher spec (1):

== Info
TLSv1.3 (IN), TLS handshake, Server hello (2):

== Info
TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):

== Info
TLSv1.3 (IN), TLS handshake, Certificate (11):

== Info
TLSv1.3 (IN), TLS handshake, CERT verify (15):

== Info
TLSv1.3 (IN), TLS handshake, Finished (20):

== Info
TLSv1.3 (OUT), TLS handshake, Finished (20):

== Info
SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / secp521r1 / RSASSA-PSS

== Info
ALPN: server accepted http/1.1

== Info
Server certificate:

== Info
 subject: C=US; ST=WA; L=Redmond; O=Microsoft Corporation; CN=*.azurewebsites.net

== Info
 start date: Apr 14 21:33:25 2025 GMT

== Info
 expire date: Oct 11 21:33:25 2025 GMT

== Info
 subjectAltName: host "function-host.example.net" matched cert's "*.azurewebsites.net"

== Info
 issuer: C=US; O=Microsoft Corporation; CN=Microsoft Azure RSA TLS Issuing CA 07

== Info
 SSL certificate verify ok.

== Info
  Certificate level 0: Public key type RSA (2048/112 Bits/secBits), signed using sha384WithRSAEncryption

== Info
  Certificate level 1: Public key type RSA (4096/152 Bits/secBits), signed using sha384WithRSAEncryption

== Info
  Certificate level 2: Public key type RSA (2048/112 Bits/secBits), signed using sha256WithRSAEncryption

== Info
Connected to 10.xx.xx.xx (10.xx.xx.xx) port 3128

== Info
using HTTP/1.x

=> Send header
POST /api/MyFunctionEndpoint HTTP/1.1
Host: function-host.example.net
Accept: application/json
Content-Type: application/json; charset=utf-8
x-functions-key: [REDACTED-KEY]
traceparent: [REDACTED-TRACEPARENT]
Content-Length: 83

=> Send data
{"status": "success","data": {"requestid": "example-request-id-uuid"}}

== Info
upload completely sent off: 83 bytes

== Info
TLSv1.3 (IN), TLS handshake, NewSession Ticket (4):

<= Recv header
HTTP/1.1 404 Not Found

<= Recv header
Content-Length: 0

<= Recv header
Date: Tue, 29 Apr 2025 15:54:06 GMT

<= Recv header
Request-Context: appId=cid-v1:[REDACTED-APP-ID]

<= Recv header

== Info
Connection #0 to host 10.xx.xx.xx left intact


And printing headers gives statuscode 404. 

content-length => 0
date => Tue, 29 Apr 2025 15:54:06 GMT
http/1.1 200 connection established => 
http/1.1 404 not found => 
request-context => appId=cid-v1:dd845549-256c-45ba-a07b-ab21d0d5b2df

How come it works in postman and with C# httpClient and not in CRMScript ?

29. apr. 2025 | 04.00 PM

Your csharp example show's that you are doing a GET operation, while in the crmscript example you are doing a POST operation. Maybe that is the issue?

29. apr. 2025 | 04.08 PM
I've tried with GET in CRMScript. It doesent work either.
In the headers it gives me:

HTTPConnection::endRequest(): URL using bad/illegal format or missing URL
29. apr. 2025 | 04.11 PM
Not sure if the CRMScript implementation supports sending a body with a GET operation..
29. apr. 2025 | 04.13 PM
The first method that retrieves the requestid is also a GET method in Postman and C#, but it works only when I use post in CRMScript. Was expecting the same for this method aswell.
29. apr. 2025 | 04.19 PM

I have checked the code, and from what I can see, we do not support a body for GET, DELETE or HEAD. I would argue that sending a body on a GET (which obviously impacts the response) is not recomended. Some more details here: https://stackoverflow.com/questions/978061/http-get-with-request-body

I don't expect us to change this implementation, so I suggest rewriting the endpoint to accepting all relevant parameters in the URI.

Sverre

30. apr. 2025 | 07.48 AM

Ummair, are there any codepaths in the Azure Function that returns a 404 result? 

In your second example your JSON has a different structure, you send in a status as well. Can that cause the azure function to return 404?

Is your Azure Function hosted on any other ports than 80 or 443?

I've got a feeling there is something in the redacted info that is relevant to why it's failing.

 

David, for the fun of it, you can send a body in a GET by messing around with the headers. Not recommended though 😀

String body = String('{"Food": "Blåbærsyltetøy"}').utf8Encode();

HTTP http;
http.addHeader("Content-Length", body.getLength().toString() + "\n\n" + body);
http.get(URL);
30. apr. 2025 | 08.21 AM
You're a legend, @Frode? 💎
The workaround actually did the trick! 🙌
I've also asked the dev to include requestId in the URL instead of the body so we can make it "work the proper way".
30. apr. 2025 | 09.47 AM

Tilføj svar