简体   繁体   中英

Azure Function HTTP trigger to receive nested JSON and store in Cosmos DB

  • Azure Function and C# virgin here. Forgive my ignorance.

I am attempting to create an Azure Function HTTP trigger that will take the received nested JSON data and store into Cosmos DB using POST. I have created a function that will store JSON that has nothing nested, but can not understand how to handle the nested portion.

Code Sample(run.csx):

    using System.Net;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Primitives;
    using Newtonsoft.Json;
    
    public static IActionResult Run(HttpRequest req, out object testDocument, ILogger log) 
{
      log.LogInformation("C# HTTP trigger function processed a request.");
    
      dynamic body = await req.Content.ReadAsStringAsync();
      var e = JsonConvert.DeserializeObject < Root > (body as string);
      return req.CreateResponse(HttpStatusCode.OK, e);
    }
    public class Vehicles {
      public string car {
        get;
        set;
      }
      public string bike {
        get;
        set;
      }
      public string plane {
        get;
        set;
      }
    }
    
    public class Root {
      public string name {
        get;
        set;
      }
      public int age {
        get;
        set;
      }
      public Vehicles vehicles {
        get;
        set;
      }
    }
    }
    if (!string.IsNullOrEmpty(Category) && !string.IsNullOrEmpty(Label)) {
      testDocument = new {
        name,
        age,
        vehicles,
        car,
        bike,
        plane
      }
    
      return (ActionResult) new OkResult();
    } else {
      testDocument = null;
      return (ActionResult) new BadRequestResult();
    }
}

Bindings(function.json):

 {
  "bindings": [
    {
      "authLevel": "anonymous",
      "name": "req",
      "type": "httpTrigger",
      "direction": "in",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "name": "$return",
      "type": "http",
      "direction": "out"
    },
    {
      "name": "testDocument",
      "direction": "out",
      "type": "cosmosDB",
      "connectionStringSetting": "XXXX-test_DOCUMENTDB",
      "databaseName": "testDatabase",
      "collectionName": "testCollection",
      "createIfNotExists": true
    }
  ]
}

Input:

{
  "name":"Ram",
  "age":27,
  "vehicles": {
     "car":"limousine",
     "bike":"ktm-duke",
     "plane":"lufthansa"
   }
}

This code produces 500 Internal Server Error when run.
If anyone could point out where the errors are or if it is even structured correctly, I would appreciate it greatly.
Thank you in advance.

The error is because your class structure is not complete. It looks like you have cut'n'pasted from two different code files. This has nothing to do with the fact that the Root class has a nested class property.

It helps to create a C# function project that you can debug with locally if you want to persist with doing this purely in the browser.

If you comment out the erroneous code, it should compile:

using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
    
public static IActionResult Run(HttpRequest req, out object testDocument, ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");

    dynamic body = await req.Content.ReadAsStringAsync();
    var e = JsonConvert.DeserializeObject<Root>(body as string);
    return req.CreateResponse(HttpStatusCode.OK, e);
}

public class Vehicles
{
    public string car
    {
        get;
        set;
    }
    public string bike
    {
        get;
        set;
    }
    public string plane
    {
        get;
        set;
    }
}

public class Root
{
    public string name
    {
        get;
        set;
    }
    public int age
    {
        get;
        set;
    }
    public Vehicles vehicles
    {
        get;
        set;
    }
}


//    }
//    if (!string.IsNullOrEmpty(Category) && !string.IsNullOrEmpty(Label))
//    {
//        testDocument = new
//        {
//            name,
//            age,
//            vehicles,
//            car,
//            bike,
//            plane
//        }
//
//
//          return (ActionResult)new OkResult();
//    }
//    else
//    {
//        testDocument = null;
//        return (ActionResult)new BadRequestResult();
//    }
//}

However you will see this doesn't do anything with your CosmosDB logic.


Also, please DO NOT abuse dynamic the way you have there, the response from ReadAsStringAsync is a Task<string> , just use it:

string body = await req.Content.ReadAsStringAsync();
var e = JsonConvert.DeserializeObject<Root>(body);
return req.CreateResponse(HttpStatusCode.OK, e);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM