考虑以下代码。它使用确切的 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
插入时指定数据类型的正确方法是什么 实体与 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
的表,如下所示:
要生成SAS令牌,我在允许的服务中选择了
Table
,如下所示:
点击如下Generate SAS and connection string
选项后,我成功生成了
SAS令牌:
现在我尝试通过 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
当我在 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"
}
回复:
要确认,您可以在下面调用
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
回复:
请注意,您需要明确地包含OData数据类型仅 当 not 通过
JSON 类型检测推断出来时 启发式。OData
因此,即使您不包括 OData 数据类型,插入实体也可以正常工作,因为 OData 启发式算法 在某些情况下会检测到数据类型。
参考文献: