Azure / Azure/azure-functions-host
JSON string output binding data was unexpectedly formatted with \n and indents by FunctionHost
- Dominant language
- C#
- Stars
- 2k
- Forks
- 482
- Avg merge
- 2d 12h
- Merged PRs (30d)
- 38
Description
This issue was previously discussued internal ICM(424890513), But navigated to file GitHub Issue.
#### Investigative information
This issue is reproducible locally.
- Timestamp: N/A
- Function App version: 4.21.1.20667
- Function App name: N/A
- Function name(s) (as appropriate): N/A
- Invocation ID: N/A
- Region: N/A
#### Repro steps
1. Create EventHub output binding function with Python. Set output binding data with json string.
```python
def main(req: func.HttpRequest, outEventHubMsg: func.Out[str]) -> func.HttpResponse:
logging.info('Python HTTP trigger function processed a request.')
reading = {'from': 'function', 'id': str(uuid.uuid4()), 'timestamp': str(datetime.datetime.utcnow()), 'uv': random.random(), 'temperature': random.randint(70, 100), 'humidity': random.randint(70, 100)}
s = json.dumps(reading)
logging.info('Message created: %s', s)
outEventHubMsg.set(s)
# outEventHubMsg.set("single string line")
return func.HttpResponse(
s,
status_code=200
)
```
```function.json
{
"scriptFile": "__init__.py",
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get",
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "$return"
},
{
"type": "eventHub",
"name": "outEventHubMsg",
"eventHubName": "myeventhub",
"connection": "MyEventHubSendAppSetting",
"direction": "out"
}
]
}
```
2. Check captured EventHub data
[Event Hubs - Capture streaming events using Azure portal - Azure Event Hubs | Microsoft Learn](https://learn.microsoft.com/en-us/azure/event-hubs/event-hubs-capture-enable-through-portal)
Ingested data by FunctionApp.
I've confirmed that ingested data without FunctionApp was not formatted using below tutorial.
[Quickstart: Read Azure Event Hubs captured data (Python) - Azure Event Hubs | Microsoft Learn](https://learn.microsoft.com/en-us/azure/event-hubs/event-hubs-capture-python)
Ingested data by EventHubProducerClient without Function.
#### Expected behavior
Output binding data must be processed exactly as written by the application (function) code.
Adding `\n` and indents cause bigger byte size.
#### Actual behavior
Functions host format JSON string with `\n` and indents.
Same issue happens with Node/Dotnet-isolated worker. But not happens with .NET in-process.
As fa as I debugged FunctionsHost, unexpected `\n` and indents were inserted by [FunctionBinding.cs](https://github.com/Azure/azure-functions-host/blob/dev/src/WebJobs.Script/Binding/FunctionBinding.cs)
It [`JToken.Parse(stringValue)`](https://github.com/Azure/azure-functions-host/blob/dev/src/WebJobs.Script/Binding/FunctionBinding.cs#L119) once then using [`value.ToString()`](https://github.com/Azure/azure-functions-host/blob/dev/src/WebJobs.Script/Binding/FunctionBinding.cs#L188C43-L188C59).
https://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_Linq_JToken_ToString.htm
> Return Value
> Type: [String](http://msdn2.microsoft.com/en-us/library/s1wwdcbf)
> The indented JSON for this token.
I think this cause unexpected formatting before processing data to EventHub OutputBinding.
Also this is not EventHub OutputBinding specific problem, same formatting happen with other output-binding such as Queue Storage.
#### Known workarounds
No workaround found.
#### Related information
Provide any related information
* Programming language used: Python,Node,DotNet-isolated
* Links to source: https://github.com/Azure/azure-functions-host/blob/dev/src/WebJobs.Script/Binding/FunctionBinding.cs
* Bindings used: EventHubOutput, QueueOutput
Contributor guide
Research direction
Start in src/WebJobs.Script/Binding/FunctionBinding.cs at the JToken.Parse(stringValue) and value.ToString() calls identified in the issue. Reproduce the Python Event Hub output-binding example, then compare the serialized output with the application string for Event Hub and Queue Storage bindings across the listed worker types. Done means the host preserves the application's JSON string without added newlines or indentation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- azure, csharp, node.js, python
- Domain
- backend, cloud
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100