0

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.

Arash
  • 3,628
  • 5
  • 46
  • 70

2 Answers2

1
  • 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

Mohit Ganorkar
  • 1,917
  • 2
  • 6
  • 11
1

I want to add a second answer as in the question it is used HttpRequestData whereas HttpRequest is used in the other answer. The first type is typically used in Isolated-Process functions and the second in In-Process functions.

In such case the easier and straightforward solution:

var model = await request.ReadFromJsonAsync<YourModelType>();

Ref here

Marco Medrano
  • 2,530
  • 1
  • 21
  • 35