Azure REST API 插入操作中的 OData 类型有什么问题?

问题描述 投票:0回答:1

考虑以下代码。它使用确切的 JSON 字符串作为 MSLearn 中的示例,除了获取数字分区键和行键。

sTableName = "timstesttable"
tableSASToken = "sv=2021-10-04&ss=btqf&srt=sco&se=2123-02-16T22%3A02%3A00Z&sp=rwdxftlacup&sig={sig}"

sJSON = "{""TableName"":""" & sTableName & """}"
sURL = "https://mystorage.table.core.windows.net/Tables?" & tableSASToken
Set oRequest = CreateObject("MSXML2.XMLHTTP.6.0")
oRequest.Open "POST", sURL
oRequest.setRequestHeader "Date", getUTC
oRequest.setRequestHeader "Content-Type", "application/json"
oRequest.setRequestHeader "Accept", "application/json;odata=nometadata"
oRequest.setRequestHeader "Prefer", "return-content"
oRequest.setRequestHeader "Content-Length", Len(sJSON)
oRequest.Send sJSON
WScript.Echo oRequest.Status & ": " & oRequest.statusText
WScript.Echo oRequest.responseText
Set oRequest = Nothing

sURL = "https://mystorage.table.core.windows.net/Tables('" & sTableName & "')?" & tableSASToken
Set oRequest = CreateObject("MSXML2.XMLHTTP.6.0")
oRequest.Open "GET", sURL
oRequest.setRequestHeader "Date", getUTC
oRequest.setRequestHeader "x-ms-version", "2021-10-04"
oRequest.setRequestHeader "Accept", "application/json;odata=nometadata"
oRequest.Send
WScript.Echo oRequest.Status & ": " & oRequest.statusText
WScript.Echo oRequest.responseText
Set oRequest = Nothing

sJSON = "{""Address"":""MountainView"",""Age"":23,""AmountDue"":200.23,""[email protected]"":""Edm.Guid"",""CustomerCode"":""c9da6455-213d-42c9-9a793e9149a57833"",""[email protected]"":""Edm.DateTime"",""CustomerSince"":""2008-0710T00:00:00"",""IsActive"":true,""[email protected]"":""Edm.Int64"",""NumberOfOrders"":""255"",""PartitionKey"":""12345"",""RowKey"":""6789""}"

sURL = "https://mystorage.table.core.windows.net/" & sTableName & "?" & tableSASToken
Set oRequest = CreateObject("MSXML2.XMLHTTP.6.0")
oRequest.Open "POST", sURL
oRequest.setRequestHeader "Date", getUTC
oRequest.setRequestHeader "x-ms-version", "2021-10-04"
oRequest.setRequestHeader "Content-Type", "application/json"
oRequest.setRequestHeader "Content-Length", Len(sJSON)
oRequest.setRequestHeader "Accept", "application/json;odata=nometadata"
oRequest.setRequestHeader "Prefer", "return-content"
oRequest.Send sJSON
WScript.Echo oRequest.Status & ": " & oRequest.statusText
WScript.Echo oRequest.responseText

--------------------------------------------------------------------------------------
Output:

201: Created
{"TableName":"timstesttable"}

200: OK
{"TableName":"timstesttable"}

400: Bad Request
{"odata.error":{"code":"InvalidInput","message":{"lang":"en-US","value":"An error occurred while processing this request.\nRequestId:74bcc6ea-b002-000d-5521-43570a000000\nTime:2023-02-17T22:44:18.4850227Z"}}}

但是,如果我从 JSON 字符串中删除 OData 数据类型,它就可以工作。

sTableName = "timstesttable"
tableSASToken = "sv=2021-10-04&ss=btqf&srt=sco&se=2123-02-16T22%3A02%3A00Z&sp=rwdxftlacup&sig={sig}"

sJSON = "{""TableName"":""" & sTableName & """}"
sURL = "https://mystorage.table.core.windows.net/Tables?" & tableSASToken
Set oRequest = CreateObject("MSXML2.XMLHTTP.6.0")
oRequest.Open "POST", sURL
oRequest.setRequestHeader "Date", getUTC
oRequest.setRequestHeader "Content-Type", "application/json"
oRequest.setRequestHeader "Accept", "application/json;odata=nometadata"
oRequest.setRequestHeader "Prefer", "return-content"
oRequest.setRequestHeader "Content-Length", Len(sJSON)
oRequest.Send sJSON
WScript.Echo oRequest.Status & ": " & oRequest.statusText
WScript.Echo oRequest.responseText
Set oRequest = Nothing

sURL = "https://mystorage.table.core.windows.net/Tables('" & sTableName & "')?" & tableSASToken
Set oRequest = CreateObject("MSXML2.XMLHTTP.6.0")
oRequest.Open "GET", sURL
oRequest.setRequestHeader "Date", getUTC
oRequest.setRequestHeader "x-ms-version", "2021-10-04"
oRequest.setRequestHeader "Accept", "application/json;odata=nometadata"
oRequest.Send
WScript.Echo oRequest.Status & ": " & oRequest.statusText
WScript.Echo oRequest.responseText
Set oRequest = Nothing

sJSON = "{""Address"":""MountainView"",""Age"":23,""AmountDue"":200.23,""CustomerCode"":""c9da6455-213d-42c9-9a793e9149a57833"",""CustomerSince"":""2008-0710T00:00:00"",""IsActive"":true,""NumberOfOrders"":""255"",""PartitionKey"":""12345"",""RowKey"":""6789""}"
sURL = "https://mystorage.table.core.windows.net/" & sTableName & "?" & tableSASToken
Set oRequest = CreateObject("MSXML2.XMLHTTP.6.0")
oRequest.Open "POST", sURL
oRequest.setRequestHeader "Date", getUTC
oRequest.setRequestHeader "x-ms-version", "2021-10-04"
oRequest.setRequestHeader "Content-Type", "application/json"
oRequest.setRequestHeader "Content-Length", Len(sJSON)
oRequest.setRequestHeader "Accept", "application/json;odata=nometadata"
oRequest.setRequestHeader "Prefer", "return-content"
oRequest.Send sJSON
WScript.Echo oRequest.Status & ": " & oRequest.statusText
WScript.Echo oRequest.responseText

--------------------------------------------------------------------------------------
Output:

201: Created
{"TableName":"timstesttable"}

200: OK
{"TableName":"timstesttable"}

201: Created
{"PartitionKey":"12345","RowKey":"6789","Timestamp":"2023-02-17T22:39:21.1436354Z","Address":"MountainView","Age":23,"AmountDue":200.23,"CustomerCode":"c9da6455-213d-42c9-9a793e9149a57833","CustomerSince":"2008-0710T00:00:00","IsActive":true,"NumberOfOrders":"255"}

如果我所有的数字都是数字数据类型,这会很好,但情况并非总是如此。使用 Azure REST API 插入实体时指定数据类型的正确方法是什么?


附录: 它不仅仅是 VBScript 代码。使用 PowerShell 时也会出现同样的问题。正确指定 odata 数据类型会导致插入操作失败。省略它们是可行的(但可能会导致推断出错误的数据类型)。

$sTableName = "timstesttable"
$tableSASToken = "sv=2021-10-04&ss=btqf&srt=sco&st=2023-02-15T22%3A02%3A13Z&se=2123-02-16T22%3A02%3A00Z&sp=rwdxftlacup&sig={sig}"
$sURL = "https://mytable.table.core.windows.net/"+$sTableName+"?$tableSASToken"

$badJSON = '{"Address":"MountainView","Age":23,"AmountDue":200.23,"[email protected]":"Edm.Guid","CustomerCode":"c9da6455-213d-42c9-9a793e9149a57833","[email protected]":"Edm.DateTime","CustomerSince":"2008-0710T00:00:00","IsActive":true,"[email protected]":"Edm.Int64","NumberOfOrders":"255","PartitionKey":"12345","RowKey":"6789"}'
$goodJSON = '{"Address":"MountainView","Age":23,"AmountDue":200.23,"CustomerCode":"c9da6455-213d-42c9-9a793e9149a57833","CustomerSince":"2008-0710T00:00:00","IsActive":true,"NumberOfOrders":"255","PartitionKey":"12345","RowKey":"6789"}'
$headers = @{
    "Date" = $(Get-Date)
    "Accept" = "application/json;odata=nometadata"
    "x-ms-version" = "2021-10-04"
    "Content-Type" = "application/json"
    "Prefer" = "return-content"
    "Content-Length" = $badJSON.length
}
Invoke-RestMethod -uri $sURL -Method Post -Headers $headers -Body $badJSON 

$headers = @{
    "Date" = $(Get-Date)
    "Accept" = "application/json;odata=nometadata"
    "x-ms-version" = "2021-10-04"
    "Content-Type" = "application/json"
    "Prefer" = "return-content"
    "Content-Length" = $goodJSON.length
}
Invoke-RestMethod -uri $sURL -Method Post -Headers $headers -Body $goodJSON


Invoke-RestMethod : The remote server returned an error: (400) Bad Request.
At line:15 char:1
+ Invoke-RestMethod -uri $sURL -Method Post -Headers $headers -Body $ba ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand


PartitionKey   : 12345
RowKey         : 6789
Timestamp      : 2023-02-20T16:45:45.3443571Z
Address        : MountainView
Age            : 23
AmountDue      : 200.23
CustomerCode   : c9da6455-213d-42c9-9a793e9149a57833
CustomerSince  : 2008-0710T00:00:00
IsActive       : True
NumberOfOrders : 255
vba powershell vbscript azure-table-storage azure-rest-api
1个回答
0
投票

插入时指定数据类型的正确方法是什么 实体与 Azure REST API?

在使用 Azure REST API 插入实体时,您需要以

@odata.type
格式指定数据类型,如下所示:

{property_name}@odata.type: "Edm.{data_type}"

possible 值是 Edm.String, Edm.Int32, Edm.Int64, Edm.Guid, Edm.Boolean 等....您需要根据数据类型和 odata 中的值包括

Accept 
标题。

我试图通过邮递员在我的环境中重现相同的内容并得到以下结果:

我在我的存储帐户中创建了一个名为

timstesttable
的表,如下所示:

enter image description here

要生成SAS令牌,我在允许的服务中选择了

Table
,如下所示:

点击如下Generate SAS and connection string选项后,我成功生成了

SAS令牌

enter image description here

现在我尝试通过 Postman 使用以下标头调用 REST API 来插入实体

POST https://<storageaccname>.table.core.windows.net/<table name>?sv=2021-06-08&ss=t&srt=sco&sp=rwdlacu&se=2023-02-18T14:47:19Z&st=2023-02-18T06:47:19Z&spr=https&sig=<sig>

Date:18 February 2023
x-ms-version:2021-10-04
Content-Type:application/json
Accept:application/json;odata=nometadata
Prefer:return-content

enter image description here

当我在 Body 部分包含相同的

JSON
字符串以及 OData 数据类型 时,实体成功插入并带有 response 如下所示:

POST https://<storageaccname>.table.core.windows.net/<table name>?sv=2021-06-08&ss=t&srt=sco&sp=rwdlacu&se=2023-02-18T14:47:19Z&st=2023-02-18T06:47:19Z&spr=https&sig=<sig>
{  
   "Address":"Mountain View",  
   "Age":23,  
   "AmountDue":200.23,  
   "[email protected]":"Edm.Guid",  
   "CustomerCode":"c9da6455-213d-42c9-9a79-3e9149a57833",  
   "[email protected]":"Edm.DateTime",  
   "CustomerSince":"2008-07-10T00:00:00",  
   "IsActive":true,  
   "[email protected]":"Edm.Int64",  
   "NumberOfOrders":"255",  
   "PartitionKey":"12345",  
   "RowKey":"6789"  
}

回复:

enter image description here

确认,您可以在下面调用

GET
请求列出表的实体:

GET https://<storageaccname>.table.core.windows.net/<table name>?sv=2021-06-08&ss=t&srt=sco&sp=rwdlacu&se=2023-02-18T14:47:19Z&st=2023-02-18T06:47:19Z&spr=https&sig=<sig>

Date:18 February 2023
x-ms-version:2021-10-04
Content-Type:application/json
Accept:application/json;odata=nometadata
Prefer:return-content

回复:

enter image description here

请注意,您需要明确地包含OData数据类型not 通过

OData
JSON 类型检测推断出来时 启发式。

因此,即使您不包括 OData 数据类型,插入实体也可以正常工作,因为 OData 启发式算法 在某些情况下会检测到数据类型。

参考文献:

插入和更新实体 (REST API) - Azure 存储 |微软

表服务操作(REST API)的有效负载格式 - Azure 存储 |微软

© www.soinside.com 2019 - 2024. All rights reserved.