Azure table api 从 PowerShell 中的函数应用程序调用失败错误不是有效的 Content-Type header

Azure table api call failing from function app in PowerShell Error not a valid Content-Type header

我在 PowerShell 中有一个 azure 函数应用程序,在这个 azure 函数应用程序中,我正在调用 azure table api 来更新 azure table 中的数据。 (相同的代码在 powershell 控制台中运行良好) 在 azure 函数应用程序中出现错误:“cmdlet 不能 运行 因为 -ContentType 参数不是有效的 Content-Type header。为 -ContentType 指定一个有效的 Content-Type,然后重试."

脚本:

$hash = "045tgh4fd"
$Id = "12345"
$StorageAccountName = "mystaccname"
$resourceGroup = "myrgname"

$StorageAccountAccessKey = "mystacckey";
try {
    #Add data in table.
   
    $entity = @{"Id" = $Id; "Hash" = $hash; "SoftDeleted" = "Y"};
    #$body = $entity | ConvertTo-Json

    $RFC1123TimeUTC  = [datetime]::UtcNow.ToString("R")       
    Write-Verbose "Time stamp for authorization header signature: '$RFC1123TimeUTC'"
    $RequestHeaders = @{
      'x-ms-version' = '2015-04-05'
      'x-ms-date' = $RFC1123TimeUTC
      'Accept-Charset' = 'UTF-8'
      'DataServiceVersion' = '1.0;NetFx'
      'MaxDataServiceVersion' = '3.0;NetFx'
    }

    $urlPath = "mytable(PartitionKey='12345',RowKey='rw12345')";
    $TableStorageUri = "https://mystacc.table.core.windows.net/mytable(PartitionKey='12345',RowKey='rw12345')";

    [Byte[]] $StorageAccountAccessKeyByteArray = [System.Convert]::FromBase64String($StorageAccountAccessKey)
    $hasher = New-Object System.Security.Cryptography.HMACSHA256
    $hasher.key = $StorageAccountAccessKeyByteArray
    $strToSign = $RFC1123TimeUTC + "`n" + "/" + $StorageAccountName + "/" + $UrlPath
    $AuthKey = [System.Convert]::ToBase64String($hasher.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($strToSign)))
    $SharedKeyLiteAuthorizationHeader = "SharedKeyLite $StorageAccountName`:$AuthKey"

    $RequestHeaders.Add('Accept', 'application/json;odata=nometadata')
    $RequestHeaders.Add('Authorization', $SharedKeyLiteAuthorizationHeader)
    $RequestHeaders.Add('If-Match', "*")
    $RequestBody = ConvertTo-Json -InputObject $entity -Depth 2
    $ContentType = "application/json"
    $HttpMethod = "Put"

    $RequestHeaders.Add("Content-Length", $requestBody.Length)
    $UpdateRequest = Invoke-WebRequest -UseBasicParsing -Uri $TableStorageUri -Method $HttpMethod -Body $RequestBody -ContentType $ContentType -Headers $RequestHeaders
    
    Write-Host "Updated Successfully"
}
catch
{
    Write-Host $_
}

尝试了下面的脚本,该脚本也可以在本地 PS 控制台中运行,但不能在 azure 函数应用程序中运行:

try {
    $entity = @{"Id" = "12345"; "hash" = "34f45gfh"; "SoftDeleted" = "N"};
    $body = $entity | ConvertTo-Json

    $version = "2017-04-17"
    $resource = "tableName(PartitionKey='myPartitionKey',RowKey='myRowkey')"
    $table_url = "https://StorageAccountName.table.core.windows.net/$resource"
    $GMTTime = (Get-Date).ToUniversalTime().toString('R')
    $stringToSign = "$GMTTime`n/StorageAccountName/$resource"

    $hmacsha = New-Object System.Security.Cryptography.HMACSHA256
    $hmacsha.key = [Convert]::FromBase64String("storageaccoutkey")
    $signature = $hmacsha.ComputeHash([Text.Encoding]::UTF8.GetBytes($stringToSign))
    $signature = [Convert]::ToBase64String($signature)
   
    $headers = @{
        'x-ms-date'      = $GMTTime
        Authorization    = "SharedKeyLite " + $StorageAccountName + ":" + $signature
        "x-ms-version"   = $version
        Accept           = "application/json;odata=minimalmetadata"
        'If-Match'       = "*"
        'Content-Length' = $body.length
    }
    $response = Invoke-RestMethod -Method MERGE -Uri $table_url -Headers $headers -Body $body -ContentType "application/json;odata=minimalmetadata"
    Write-Host "Updated Successfully"
}
catch
{
    Write-Host $_
}

您收到此错误的原因与 Content-Type 请求 header 无关:)。真正的罪魁祸首是相同的 header 被多次添加(Content-Length 在你的情况下)。

本质上发生的事情是您手动添加 Content-Length header 并且 Invoke-RestMethod 也在添加 Content-Length 请求 header。因为这个 header 被添加了多次,所以你会收到这个错误。从您的请求中删除 Content-Length header 后,问题就解决了,因为现在这个 header 只添加了一次。

有关详细信息,请参阅 Github 上的此问题:https://github.com/PowerShell/PowerShell/issues/12500#issuecomment-777757252。这是我找到这个解决方案的地方。