Azure / azure-functions-powershell-worker

PowerShell language worker for Azure Functions.
MIT License
203 stars 51 forks source link

Runtime fails to serialize json into hashtable #669

Open 4c74356b41 opened 2 years ago

4c74356b41 commented 2 years ago

Repro steps

Provide the steps required to reproduce the problem:

  1. Create a powershell function with the following parameters image
  2. add an http trigger function with following code:
    using namespace System.Net
    param($Request, $TriggerMetadata)
    Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = [HttpStatusCode]::OK
    Body = $Request.Body.GetType()
    })
  3. call the function with something like this:
    {"buildId":"id","sourceVersion":"version","scopes":["/subscriptions/fdbb6770-4977-44e9-9ee4-4cf0fcc1e6b3","/subscriptions/51c2c6a2-e6bd-492d-8a9d-0b02d6a325d8"],"certValue":"MIIDDjCCAfagAwIBAgIQFZlpQaNVZYpFor0BFa4zHzANBgkqhkiG9w0BAQUFADAaMRgwFgYDVQQDDA9zZWNvcHMtMDEwLWhhc2gwHhcNMjEwODEzMDc1MDQzWhcNMjEwODE0MTE1MDQzWjAaMRgwFgYDVQQDDA9zZWNvcHMtMDEwLWhhc2gwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaZTnBjT+szkqvd4FZS2hm+oww9jVZZAxwBNhLLhbq+N7y9EgtiWVsdlFgmoKH3hBaZca1631hqGafNdRGHZJu8DTmnyzgpHZLitzlmq3n4G65yC2kr4r88VSJvJieoCdSmOLjdmkl5Nm2Cedvp7EIs/u5VmjFw6dtYI1pgRmJAECYsxsKhABRnsUua7i2gAqEQs/TMgMoUXNnZ9y7aEDoLWgN7WlvMoOi2gFDFIxYhGoEQXD+EOexawbRMS2kfvAG2dE/fotSruSAf4zIabD0KjMVsAxHZiaAJ2LDEf/wVDWMzZ8CLq3R3XD807qE9RRbshZ+TefHZhBO7j/y00OBAgMBAAGjUDBOMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwHQYDVR0OBBYEFHy8F1cMI0ajtKr5+aizJNeBLatXMA0GCSqGSIb3DQEBBQUAA4IBAQCvPpBv8Uz2loVd/VhcUQNuCcam14vl5AS/mW72A37MVqi5BOjDLfUFzkrAIUiPRZSwuy+4JQrwRCdIZidWpcQXILwGA2FwXE7P4K4TNAKru2EUgbHL1TMUM73+/Epn2Pj5VtA5zrYbmToNYkDp3juYPieGV//9A112rStFc1mAl+OziQb0YMv2X255ECOe+eliSODxzupzUs9VEHsYPHWJLPnufVsGrGRSEmpbu3dy+YsTbB6dtLZE2AqdTDPhbKJBvLb78FgGiDide4gcp4MhC1Rm9k2NYpNf/EDcPHcWRGvSZ+49JsZup9CWec/7EbZ5MrGJxHt2fpw19khAGyMw"}

Expected behavior

returns System.Collections.Hashtable

Actual behavior

returns System.String

Known workarounds

forcefully cast to an object with $Request.Body | ConvertFrom-Json

Related information

https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-powershell?tabs=portal#request-object

v-anvari commented 2 years ago

Hi @4c74356b41 , the payload that would not be automatically handled by the runtime or PowerShell in this case with a type conversion to hash table. Currently this behavior is by design. The simple payload example uses just the string, but your actual code example uses both string and an Array, which will need to be casted.

Transferring this issue to the appropriate repo for more insights

4c74356b41 commented 2 years ago

fix the docs in this case ;) but I don't understand why is it an issue at all, if convertfrom-json handles this np

AnatoliB commented 2 years ago

I suspect this is because of: https://github.com/Azure/azure-functions-powershell-worker/blob/23de458d7c4271870bb0126d8deb5e92ab4ed4e3/src/Utility/TypeExtensions.cs#L145

We need to either increase it or make it configurable (or both).

4c74356b41 commented 2 years ago

I doubt thats the case, my json is only 2 levels "deep" and I'm using ConvertFrom-Json without -Depth parameter (its default is 3). so there is something else in play here most likely.

4c74356b41 commented 2 years ago

I'm observing the same behaviour when passing an object with an array as an input between durable functions. If I use an hashtable where one of the properties contain an array I get this as input:

arrayProperty: "obj1 obj2 obj2"

instead of:

arrayProperty: obj1, obj2, obj3
4c74356b41 commented 2 years ago

sample repro:

$myInput= @{
    prop1= "somestring" # work fine
    prop2 = $array # gets passed as a string you would get if you execute this: $array -join " "
}

Invoke-DurableActivity -FunctionName function -Input $myInput

so inside my durable activity I have to do:

$myInput.prop2.split().foreach{xxx]

instead of:

$myInput.prop2.foreach{xxx}
4c74356b41 commented 2 years ago

basically I'm suggesting something is wrong with how you try and parse arrays

4c74356b41 commented 2 years ago

forgot to add: if I'm passing a hashtable like this (between durable activities):

@{
   prop1 = "121r13r53"
   prop2 = "ewgwgeyw"
   prop3 = "325tg24yg24"
   etc
}

so all properties are strings - it gets passed fine

Francisco-Gamino commented 2 years ago

Set up a local repo without Durable Functions. If this issue is present, this will be a breaking change.

Francisco-Gamino commented 2 years ago

Hello @4c74356b41 -- I am still looking into this; however, as a workaround you can specified the Content-Type header in the request to be 'application/json'. This will ensure that the request body is deserialized to a hashtable if the content is a valid JSON.

4c74356b41 commented 2 years ago

okay, that seems to work, what about when passing data in between activities?

Francisco-Gamino commented 2 years ago

@4c74356b41 -- I've created a separate issue to track the Durable activities scenario: Runtime fails to serialize json into hashtable for Durable activities.

Francisco-Gamino commented 2 years ago

To close on this, to deserialize the body into a hashtable, the request should specify the Content-Type header to be 'application/json'. We will update the docs to reflect this.