0

I am trying to use the WebJobs SDK extensions (and the Azure Functions tools for VS) to migrate my Azure functions to pre-compiled binaries, but I'm having problems with the DocumentDB bindings.

I'm trying to create an input binding to an existing DocumentDB document that I can read from, then update the data. When I do this in a script-based Azure function, everything works the way I want. Here's the code I'm using:

public static void Run(TimerInfo myTimer, JObject document, TraceWriter log)
{
    log.Info(document.ToString());

    var active = document["active"] as JArray;
    foreach (var item in active)
    {
        log.Info($"Polling {item}...");
    }

    document["processed"] = DateTime.Now;
    log.Info(document.ToString());
}

The document in question looks like this:

{
    "id": "sites",
    "_rid": "(hash)",
    "_self": "(stuff)",
    "_etag": "\"(guid)\"",
    "_attachments": "attachments/",
    "active": [
        "scifi"
    ],
    "_ts": 1497184149
}

If I try to move this exact code into a pre-compiled function, using WebJobs attributes:

    [FunctionName("TimerFeed")]
    public static void Run(
        [TimerTrigger("0 */5 * * * *")]TimerInfo myTimer,
        [DocumentDB("FeedStateDatabase", "FeedItemsCollection", ConnectionStringSetting = "feed_DOCUMENTDB", Id = "sites")] JObject document,
        TraceWriter log)

then I get an error trying to run the function:

2017-06-11T12:26:36.046 Exception while executing function: Functions.TimerFeed. Newtonsoft.Json: Cannot create and populate list type Newtonsoft.Json.Linq.JToken. Path 'active', line 1, position 219.

Note that the error is thrown before any of my function's code runs. It is thrown even if I remove all of the code and just do a simple diagnostic log. So, I'm pretty sure there's something wrong with my binding. The functions.json file that is being generated looks off, specifically it's claiming that this is an output binding:

{
  "type": "documentDB",
  "databaseName": "FeedStateDatabase",
  "collectionName": "FeedItemsCollection",
  "createIfNotExists": false,
  "connection": "feed_DOCUMENTDB",
  "id": "sites",
  "direction": "out",
  "name": "document"
}
Michael Edenfield
  • 28,070
  • 4
  • 86
  • 117
  • I'm not familiar with using JObject type as your document - I've only been using dynamic or a POCO that represents the document structure. Any reason you couldn't use one of those options? I logged that github issue referenced in the other answer, agree that it's unlikely to be your problem here. – Garth Mason Jun 12 '17 at 12:11
  • I can try dynamic, I was just following the Web Jobs SDK example. – Michael Edenfield Jun 12 '17 at 12:24
  • No worries. Might be worth logging this on the Azure Functions github if you don't get a definitive answer here, in my experience they have been really responsive to queries on there, particularly since the VS tooling was released. – Garth Mason Jun 12 '17 at 12:50
  • Switching to `dynamic` appears to solve the problem; it actually looks unrelated to the binding direction (at least, the "broken" binding works fine as a `dynamic`. – Michael Edenfield Jun 13 '17 at 18:29
  • Sounds like what I found - the binding direction didn't seem to stop my function from running as expected either. – Garth Mason Jun 13 '17 at 23:54
  • If it is useful, please mark it as an answer that will help more communities who have the same issue. – Tom Sun - MSFT Jun 19 '17 at 00:41
  • @TomSun-MSFT I haven't really gotten my question answered: I still can't use `JObject` for my binding, and manually fixing the direction didn't help. Switching to `dynamic` types merely circumvented the problem but it has other different problems of its own. – Michael Edenfield Jun 19 '17 at 02:53
  • I tested with JObject, it works correctly on side. – Tom Sun - MSFT Jun 19 '17 at 05:01
  • @TomSun-MSFT I tried JObject, I also get null. If I use dynamic it crashes VS. If I use object it works fine, sorta. – 123 456 789 0 Jun 26 '17 at 05:42
  • As I mentioned I also get null with JObject during debug in VS. But If I publish it to Azure then it works correctly. – Tom Sun - MSFT Jun 27 '17 at 01:25

2 Answers2

3

I'm using Visual Studio 2017 v15.3 Preview with the Azure Function Tools extension installed. After publish to Azure function, the code you mentioned could work correctly after change direction from out to in and add new documentdb connection string. The following is my detail steps:

1.Install Visual Studio 2017 v15.3 Preview and Azure function tool extension

2.Create Azure Function project and add timetrigger function add reference Microsoft.Azure.WebJobs.Extensions.DocumentDB

enter image description here

3.Add the storage connection string to AzureWebStorage and AzureWebJobsDashboard in the local.setting.json file

4.From the Azure WebJob Extension SDK we cloud know that documentdb default connection string name is AzureWebJobsDocumentDBConnectionString. Add the corresponding value for it.

enter image description here

5.Add the following code in the timetrigger function

[FunctionName("TimerTriggerCSharp")]
        public static void Run([TimerTrigger("0 */1 * * * *")]TimerInfo myTimer, [DocumentDB("database name", "collection name", ConnectionStringSetting = "AzureWebJobsDocumentDBConnectionString", Id = "document Id")] JObject document, TraceWriter log)
        {
            log.Info($"C# Timer trigger function executed at: {DateTime.Now}");
            log.Info($"My property: {documents["MyProperty"]}");
        }

My test document is:

{
    "MyProperty": "hello1",
    "id": "a3e6a493-7c2c-4a73-8715-e7efad107d96",
    "_rid": "IgcwAN0Etg8BAAAAAAAAAA==",
    "_self": "dbs/IgcwAA==/colls/IgcwAN0Etg8=/docs/IgcwAN0Etg8BAAAAAAAAAA==/",
    "_etag": "\"0600e070-0000-0000-0000-590152cc0000\"",
    "_attachments": "attachments/",
    "_ts": 1493258955
}

6.I debug it in the local, I find that document always get null. I assume it may be the SDK issue.

enter image description here

7.Skip the issue and publish the project to Azure and I also reproduce the issue that Naren mentioned .

Visual Studio 2017 tooling always generates direction out for DocumentDb

8.Then I changed "direction": "in" in the function.json manually.

enter image description here

9.Save the change and switch to integrate tab and create corresponding documentdb connectionstring.

enter image description here

10.Run the function from the azure portal, it works correctly

enter image description here

Tom Sun - MSFT
  • 24,161
  • 3
  • 30
  • 47
1

This looks like a known issue. Visual Studio 2017 tooling always generates direction out for DocumentDb. For storage bindings like blob. FileAccess is used to identify whether it is an input binding or output binding.

https://github.com/Azure/azure-functions-vs-build-sdk/issues/41

Naren
  • 847
  • 4
  • 7