Google-cloud-dotnet: [Dialogflow] WebhookRequest parse exception in .NET Core app

Created on 23 Feb 2020  路  5Comments  路  Source: googleapis/google-cloud-dotnet

Environment details

  • OS: Windows 10
  • .NET version: .NET Core 3.1
  • Package name and version:

    • Google.Cloud.Dialogflow.V2 1.2.0;

    • Google.Protobuf 3.11.4.

Steps to reproduce

  1. Run the sample from https://googleapis.github.io/google-cloud-dotnet/docs/Google.Cloud.Dialogflow.V2/index.html for .NET Core;
  2. When calling the following line in the sample:
request = jsonParser.Parse<WebhookRequest>(reader);

I get the following exception:

Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.

To try to fix this issue I included the following lines in my ConfigureServices method in the Startup class:

services.Configure<KestrelServerOptions>(options =>
{
    options.AllowSynchronousIO = true;
});

services.Configure<IISServerOptions>(options =>
{
    options.AllowSynchronousIO = true;
});

However after doing this I start getting this exception:

Unexpected end of document in state: StartOfDocument

   at Google.Protobuf.JsonTokenizer.JsonTextTokenizer.ValidateState(State validStates, String errorPrefix)
   at Google.Protobuf.JsonTokenizer.JsonTextTokenizer.NextImpl()
   at Google.Protobuf.JsonTokenizer.Next()
   at Google.Protobuf.JsonParser.Merge(IMessage message, JsonTokenizer tokenizer)
   at Google.Protobuf.JsonParser.Merge(IMessage message, TextReader jsonReader)
   at Google.Protobuf.JsonParser.Parse[T](TextReader jsonReader)

The workaround I found for this was replacing:

request = jsonParser.Parse<WebhookRequest>(reader);

To:

string requestAsString;
// (...)
requestAsString = await reader.ReadToEndAsync();
request = jsonParser.Parse<WebhookRequest>(requestAsString);

Here is the request I'm getting from DialogFlow:

{
  "responseId": "55727bcc-7d89-4fd5-8c1f-20f9e4d8d19c-7f245a81",
  "queryResult": {
    "queryText": "Meu nome 茅 Fagner",
    "parameters": {
      "name": "Fagner"
    },
    "allRequiredParamsPresent": true,
    "fulfillmentMessages": [{
      "text": {
        "text": [""]
      }
    }],
    "outputContexts": [{
      "name": "projects/<project id>/agent/sessions/<session id>/contexts/actions_capability_account_linking",
      "parameters": {
        "name": "Fagner",
        "name.original": "Fagner"
      }
    }, {
      "name": "projects/<project id>/agent/sessions/<session id>/contexts/actions_capability_audio_output",
      "parameters": {
        "name": "Fagner",
        "name.original": "Fagner"
      }
    }, {
      "name": "projects/<project id>/agent/sessions/<session id>/contexts/actions_capability_media_response_audio",
      "parameters": {
        "name": "Fagner",
        "name.original": "Fagner"
      }
    }, {
      "name": "projects/<project id>/agent/sessions/<session id>/contexts/actions_capability_screen_output",
      "parameters": {
        "name": "Fagner",
        "name.original": "Fagner"
      }
    }, {
      "name": "projects/<project id>/agent/sessions/<session id>/contexts/google_assistant_input_type_voice",
      "parameters": {
        "name": "Fagner",
        "name.original": "Fagner"
      }
    }, {
      "name": "projects/<project id>/agent/sessions/<session id>/contexts/__system_counters__",
      "lifespanCount": 1,
      "parameters": {
        "no-input": 0.0,
        "no-match": 0.0,
        "name": "Fagner",
        "name.original": "Fagner"
      }
    }],
    "intent": {
      "name": "projects/<project id>/agent/intents/<session id>",
      "displayName": "greetings-intent"
    },
    "intentDetectionConfidence": 1.0,
    "languageCode": "en"
  },
  "originalDetectIntentRequest": {
    "source": "google",
    "version": "2",
    "payload": {
      "user": {
        "locale": "en-US",
        "lastSeen": "2020-02-22T23:44:35Z",
        "userVerificationStatus": "VERIFIED"
      },
      "conversation": {
        "conversationId": "<conversation id>",
        "type": "ACTIVE",
        "conversationToken": "[\"__system_counters__\"]"
      },
      "inputs": [{
        "intent": "actions.intent.TEXT",
        "rawInputs": [{
          "inputType": "VOICE",
          "query": "Meu nome 茅 Fagner"
        }],
        "arguments": [{
          "name": "text",
          "rawText": "Meu nome 茅 Fagner",
          "textValue": "Meu nome 茅 Fagner"
        }]
      }],
      "surface": {
        "capabilities": [{
          "name": "actions.capability.ACCOUNT_LINKING"
        }, {
          "name": "actions.capability.AUDIO_OUTPUT"
        }, {
          "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
        }, {
          "name": "actions.capability.SCREEN_OUTPUT"
        }]
      },
      "isInSandbox": true,
      "availableSurfaces": [{
        "capabilities": [{
          "name": "actions.capability.WEB_BROWSER"
        }, {
          "name": "actions.capability.AUDIO_OUTPUT"
        }, {
          "name": "actions.capability.SCREEN_OUTPUT"
        }]
      }],
      "requestType": "SIMULATOR"
    }
  },
  "session": "projects/<project id>/agent/sessions/<session id>"
}

Can we update the docs with my fix?

Also, I will report this issue in the protobuf repo to keep you in the loop for when this is fixed.

docs

All 5 comments

Can we update the docs with my fix?

Yup, will do that on Monday. Thanks very much for the suggestion, and for your work on the workaround. (I believe that the protobuf team is already working on async parsing as part of a very large change, but I don't know when that's likely to land.)

(I don't understand why allowing synchronous IO doesn't just make it work, but it's simpler to document the workaround.)

Yep, setting the AllowSynchronousIO option to true and calling Parse is working for me right now, I can't reproduce the exception in Parse anymore. I added more details in https://github.com/protocolbuffers/protobuf/issues/7245.

Righto - I've got a PR out to update the docs to show the ReadToEndAsync version, so let's just not worry about the other exception :)

I'm closing this now, because the docs are ready to go - but they won't actually be published until our next release, which I expect to be within the next few weeks.

Was this page helpful?
0 / 5 - 0 ratings