Scotty H
Scotty H

Reputation: 6714

Azure Function Cosmos DB Output Binding - Custom JsonSerializerSettings

I have an Azure Function with a CosmosDB output binding, like this:

public static class ComponentDesignHttpTrigger
{
    [FunctionName("ComponentDesignInserter-Http-From-ComponentDesign")]
    public static IActionResult Run(
        [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "fromComponentDesign")] HttpRequest request,
        [CosmosDB(
            databaseName: StorageFramework.CosmosDb.DatabaseId,
            collectionName: Storage.ComponentDesignCollectionId,
            ConnectionStringSetting = "CosmosDBConnection")] out ComponentDesign componentDesignToInsert,
        ILogger log)
    {
        var requestBody = new StreamReader(request.Body).ReadToEnd();
        componentDesignToInsert = JsonConvert.DeserializeObject<ComponentDesign>(requestBody);

        return new OkObjectResult(componentDesignToInsert);
    }
}

In this function componentDesignToInsert is automatically serialized and put into CosmosDB after the function finishes executing. But the default serialization does not put things in camelCase. For this Json.NET lets you provide custom serializer settings, like this:

var settings = new JsonSerializerSettings
{
    ContractResolver = new CamelCasePropertyNamesContractResolver()
};

var json = JsonConvert.SerializeObject(yourObject, settings);

but I'm unsure how I can integrate this with my output binding. How can I accomplish this?

Upvotes: 8

Views: 961

Answers (1)

Matias Quaranta
Matias Quaranta

Reputation: 15603

Output binding does not expose the serializer settings at this moment.

One thing you can do though, is leverage your own custom DocumentClient for the operation.

One important thing though is that the DocumentClient instance needs to be static (more details on https://github.com/Azure/azure-functions-host/wiki/Managing-Connections).

private static Lazy<DocumentClient> lazyClient = new Lazy<DocumentClient>(InitializeDocumentClient);
private static DocumentClient documentClient => lazyClient.Value;

private static DocumentClient InitializeDocumentClient()
{
    // Perform any initialization here
    var uri = new Uri("example");
    var authKey = "authKey";

    var settings = new JsonSerializerSettings
    {
        ContractResolver = new CamelCasePropertyNamesContractResolver()
    };
    return new DocumentClient(uri, authKey, settings);
}

[FunctionName("ComponentDesignInserter-Http-From-ComponentDesign")]
public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "fromComponentDesign")] HttpRequest request,
    ILogger log)
{
    var requestBody = new StreamReader(request.Body).ReadToEnd();
    var componentDesignToInsert = JsonConvert.DeserializeObject<ComponentDesign>(requestBody);

    var collectionUri = UriFactory.GetDocumentCollectionUri(StorageFramework.CosmosDb.DatabaseId, Storage.ComponentDesignCollectionId);
    await documentClient.UpsertDocumentAsync(collectionUri, componentDesignToInsert);
    return new OkObjectResult(componentDesignToInsert);
}

Another option is to decorate the class with JsonProperty if that suits your scenario.

Upvotes: 3

Related Questions