Search code examples
c#azure-functionsjson.netazure-http-trigger

Unable to deserialize an object in HTTP-triggered Azure Functions v4 dotnet-isloated


I have a POST function like the following pattern:

    [Function("save")]
    public async Task<HttpResponseData?> SaveAppAsync([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "v1/save")] HttpRequestData req) { ... }

The following method tries to deserialize the received object to the target model but it keeps failing and I guess it's because the received JSON is improperly received:

    protected async Task<T?> InstantiateAsync<T>(HttpRequestData requestData)
    {
        try
        {
            var body = await new StreamReader(requestData.Body).ReadToEndAsync();
            return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(body);
        }
        catch (Exception ex)
        {
            _logger?.LogError(ex, ex.Message);
        }
        return default;
    }

This is an example of how the "body" string variable looks like:

"{\n    \"id\": \"-1\",\n    \"name\": \"MyWebApp\",\n    \"comments\": \"My web app comments\",\n    \"tenantId\": \"1224\",\n    \"components\": [\n        {\n            \"id\": \"-1\",\n            \"name\": \"Component1\",\n            \"comments\": \"Some comments for this component\"\n        }\n    ]\n}"

I guess the reason for deserialization failure is the escape characters of "" but I could not find a solution for this problem.

My question is that whether I am missing a certain configuration in the Azure Function's middleware despite I am using the proper one per the following code snippet:

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults(app =>
    {
        app.UseNewtonsoft();
    })

Or should I somehow come up with a solution to fix that string? If so, how? Replacing those escape characters with string.Empty does not help.


Solution

    • I was able to deserialize the string using the JsonConvert.DeserializeObject function.

    • we can use dynamic data type which will represent the data in the Json string.

    dynamic type = JsonConvert.DeserializeObject(name);
    

    name is the string from the request object.

    Now here I am sending the following string to function:

    {\n    \"id\": \"-1\",\n    \"name\": \"MyWebApp\",\n    \"comments\": \"My web app comments\",\n    \"tenantId\": \"1224\"}
    

    and I am returning only value of comments and name tag in response.

    Entire function code:

    public static class Function1
        {
            [FunctionName("Function1")]
            public static async Task<IActionResult> Run(
                [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
                ILogger log)
            {
            
      // code to fetch the string from the req  
                
                log.LogInformation("C# HTTP trigger function processed a request.");
                string name = req.Query["name"];
                string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
                dynamic data = JsonConvert.DeserializeObject(requestBody);
                name = name ?? data?.name;
                
     // Actual logic of  deserialization 
                
                dynamic type = JsonConvert.DeserializeObject(name);
    
    // here I am creating a string and appending the "name" and "comment" string from the deserialized object
    
              
                string responseMessage = type.name+"  "+type.comments;
    
                return new OkObjectResult(responseMessage);
            }
    

    enter image description here