azure-functions-host: [.Net] HttpTrigger Model Binding - Collections not desearilized in v2.0.12050.0
I have an HTTP trigger function. The binding attribute is set to a custom POCO model. When sending a POST request with JSON content, array properties are not being deserialized in the model (they are left as null). This was working before the update.
Investigative information
- Function App version: 2.0.1-beta.36
- Function App name: Localy hosted function with Azure SDK. (Also happens on hosted functions)
Repro steps
- Create a simple Azure function with HttpTrigger bound to a POCO model. The model should have at least one collection property (Array<>, ICollection<>, IEnuerable<>, etc)
- Send a POST request to the function with correctly formed payload.
Expected behavior
The deserialized model should have collection properties correctly deserialized.
Actual behavior
All collection properties are null instead. Non collection properties deserialize as expected, including complex objects.
Related information
You can test the issue with the following: Function code:
[FunctionName("Test")]
public static async Task<IActionResult> Test(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "test")] TestPayload payload,
HttpRequest req,
TraceWriter log,
ExecutionContext context)
{
return new OkObjectResult(true);
}
TestPayload class (you can change the IEnumerable for any collection type, Nested[], ICollection<Nested>, IList<Netsed>, List<Nested>, etc):
public class TestPayload
{
public IEnumerable<Nested> Foo { get; set; }
}
public class Nested
{
public string Bar { get; set; }
}
Example payloads (none of them work):
{
"Foo": [{"Bar":'bar'}]
}
{
"Foo": []
}
{
"Foo": [{"Bar":"bar"}, {"Bar":"baz"}]
}
I also tried with camelCasing and with the property names without double quotes.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 16
- Comments: 41 (5 by maintainers)
Has a workaroud so bumping to P1
@ChristianWeyer and others, let me share a way to address this that requires a bit of code, but it’s relatively clean…
You can use the DI support (add a reference to
Microsoft.Azure.Functions.Extensions
) to configure some of this behavior. The following should address your issue:We’re looking into options to do this out of the box with an opt-in model (as some of the behavior differences introduced by this could break other customers). But this should give you what you need for now.
Is there an update on a fix for this or a pull request that is in progress at least? This workaround doesn’t work with .net core 3.0. You get an error stating a provider is null on startup. Seems that something else needs to be defined in order for this to be injected as a workaround.
Could not load type 'Microsoft.AspNetCore.Mvc.Formatters.Json.Internal.MvcJsonMvcOptionsSetup' from assembly 'Microsoft.AspNetCore.Mvc.Formatters.Json, Version=3.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. Value cannot be null. (Parameter 'provider')
It’s truly amazing that such a basic feature (which goes back to before 2013 in newtonsoft.json) is still an open issue here. Especially since it is a clear regression between v1 and v2/3. @jeffhollan how can a regression and only partial object deserialization ever be a breaking change? Who on earth would rely on this “feature”?
Just ran into this one myself - any indication of when this will be merged? Workaround is fine but a touch messy for such a core feature.
Chop, chop!
It is still reproducible in v3. (in 3.0.3), can’t check in 3.0.4 as a Critical bug was introduced their and Startup is not being called.
Thanks for the ping. Been working through and triaging some things. Not sure how this fell off but will move it to the top of the backlog and make sure we pick up in an upcoming sprint (or at least circle back if the fix is non-trivial for some reason)
I’m seeing the same, currently just having to accept a string and manually use JsonConvert.DeserializeObject<> to properly deserialise to my POCO.
👌🏼 This is a working workaround (hence the name 😅)
Would be great to see it fixed in the product, though. Maybe @fabiocav could look at it?
Here is a simple repro: https://github.com/ChristianWeyer/azure-functions-serialization-repro
Thanks!
The issue is fixed in the V3. Please reopen the issue if it’s still reproducible in V3.
1½ years later and still not fixed? Reports say this worked in V1 so it is clearly a regression and should be fixed ASAP (no opt-in this should just work)
Where do I find the fix? And what about V2. This issue is raised against a 2.0.1 beta and according to https://github.com/Azure/azure-functions-host/issues/3370#issuecomment-436106870 it worked in V1. I would expect this bug to be fixed in V2 as well unless it has publicly been deprecated?
Hi guys - just wanted to check about the status of this. It has been open since September 2018 - and it really is a very basic and essential feature of a Web API-like facade framework.
Some customers talked to me at conferences, and they really have a hard time in building faith and trust into Azure Functions when even such a basic thing is not working - or is not being fixed for such a long time.
@jeffhollan @fabiocav
Thanks!
So I did some digging and I believe I found a potentially candidate for the guilty line of code within a binding utility class used by the HttpTriggerAttributeBindingProvider of the HttpTrigger.
https://github.com/Azure/azure-webjobs-sdk-extensions/blob/cdeb65faacf04c53845fb76c4b513c9998fc97de/src/WebJobs.Extensions.Http/Utility.cs#L29
It appears that the binding logic is explicitly excluding arrays for some reason (p.Value.Type != JTokenType.Array) while deserializing the json body contents.
Please advice if I should create a new issue over on that Repo since it looks like the issue is actually out of that code base (azure-webjobs-sdk-extensions). Also feel free to tell me I’m going down the wrong rabbit hole 😃
Thanks!
Running into this issue as well. Manual workaround with JsonConvert is less then elegant but does work. I was about to create a new issue until I found this one so just in case you needed another repository to reproduce this issue you can find mine over here - https://github.com/joshdcar/azure-func-v2-httptrigger-model-binding-bug . It’s probably not worth mentioning but this works as expected under Azure Function 1.x.
Hopefully this will get addressed soon 😃
Thanks!