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 ax-functions-key
. -
I've tried both
GET
andPOST
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.
All Replies (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());
}
Hi Ummair!
try adding the status code to the output and see if it is 200.
#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
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 ?
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?
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
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);