Azure Function .Net8 Json Deserialization Error

Adonis Briceno 46 Reputation points
2024-05-03T16:43:16.76+00:00

I'm developing an azure function in .Net8 which is a migration from a .net6 in-process function.

The code always breaks while trying to deserialize a json object that comes within the EventGridEvent.Data which triggers the function, the deserialization using System.Text.Json.JsonSerializer.Deserialize works locally but in Azure fails with the message:

The JSON value could not be converted to UpdateRunnersEvent. Path: $ | LineNumber: 0 | BytePositionInLine: 3603.; Src: System.Text.Json; Stack: at System.Text.Json.ThrowHelper.ThrowJsonException_DeserializeUnableToConvertValue(Type propertyType) at System.Text.Json.Serialization.Converters.ObjectDefaultConverter1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value) at System.Text.Json.Serialization.JsonConverter1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue) at System.Text.Json.Serialization.JsonConverter1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state) at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan1 utf8Json, JsonTypeInfo1 jsonTypeInfo, Nullable1 actualByteCount) at System.Text.Json.JsonSerializer.Deserialize[TValue] at FunctionName(EventGridEvent eventGridEvent) . The code is below:

var options = new JsonSerializerOptions
{
    WriteIndented = true,
    DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault,
    NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString,
    ReadCommentHandling = JsonCommentHandling.Skip,
    PropertyNameCaseInsensitive = true,
    AllowTrailingCommas = true,
    Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
    UnknownTypeHandling = JsonUnknownTypeHandling.JsonElement,
    UnmappedMemberHandling = JsonUnmappedMemberHandling.Skip,
};
var eventObject = System.Text.Json.JsonSerializer.Deserialize<UpdateRunnersEvent>		 (eventGridEvent.Data, options);

Things that I tried:

Deserializing to a string and serializing back such string to the object, Fails. The json object properties matches the properties of my object class (works locally)

Is there anything else that could be tried? ...

Azure Functions
Azure Functions
An Azure service that provides an event-driven serverless compute platform.
4,351 questions
ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,227 questions
Azure Event Grid
Azure Event Grid
An Azure event routing service designed for high availability, consistent performance, and dynamic scale.
320 questions
{count} votes

2 answers

Sort by: Most helpful
  1. SurferOnWww 1,996 Reputation points
    2024-05-04T03:35:25.7733333+00:00

    You defined public class UpdateRunnersOddEventLocal, not UpdateRunnersEvent used in your code Deserialize<UpdateRunnersEvent>.

    Please try:

    var eventObject = System.Text.Json.JsonSerializer.Deserialize<UpdateRunnersOddEventLocal>(eventGridEvent.Data, options);
    

    Deserialize<UpdateRunnersOddEventLocal> can successfully deserialize the JSON string to the UpdateRunnersOddEventLocal object as shown below:

    enter image description here

    0 comments No comments

  2. Adonis Briceno 46 Reputation points
    2024-05-15T09:37:31.9066667+00:00

    Thanks for your replies @SurferOnWww and @AgaveJoe .
    BTW @SurferOnWww you are correct on what you pointed out, but is just that when I pasted here the code I altered a bit the names to not use exactly the working code, just a version of it here and then I missed that renamed, but thank you for spotting it.

    The application sending the event to the EventGrid was making a double serialization of the object within the EventgridEvent.Data. This was happening because as the object was instantiated when added to the EventGridEvent it was serialized to Json, but when the event is publish using Azure.Messaging.EventGrid; there is an additional Json serialization. The object in Data was been serialized twice. Ultra confusing because when the event is received at the function, and is deserialized during the triggering and binding for the function, the Data object is seem as a properly formed Json object, when in fact is being Serialized twice and the string contains the UTF8 scape characters.

    My solution was going back to the source application publishing the event, removing the double json serialization, just leaving the Json serialization executed when the event is published and that was the fixed. The deserialization of the EventGridEvent.Data worked at the function receiving side.

    thanks for your suggestion of the console app @AgaveJoe , when I was setting up a new console I came up with the idea of going back to strip the publishing application, so your suggestion actually led me to find the issue.

    One thing to note is that the double serialization was being properly Deserialized when using .NET6 and Newtonsoft 13.0.1 which is part of the packages used by the azure-function Microsoft.NET.SDK.Functions 4.1.0. but failing with a very confusing generic error message when using same code with .NET8 sdks Microsoft.Azure.Functions.Worker.Sdk 1.16.4 with the underlying Azure.Core 1.36.0 which uses System.Text.Json 4.7.2

    0 comments No comments