You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure REST API插入实体时OData类型指定失败问题咨询

Azure Table Storage REST API 正确指定OData类型的方法

在使用REST API插入实体时,OData类型标记的格式必须严格匹配协议要求,格式错误会直接导致400 Bad Request。以下是两种常用请求格式的正确实现方式:

Atom XML格式

这是官方文档示例中常用的格式,核心注意点是命名空间声明和类型属性的正确使用:

  • 请求头必须设置Content-Type: application/atom+xml
  • 必须在<entry>标签中声明三个命名空间:Atom、d(数据服务)、m(元数据服务)
  • 自定义字段的类型通过m:type属性指定,属性值为官方定义的Edm类型(大小写敏感)
  • 字段内容必须与指定类型兼容(比如Edm.Guid必须是标准GUID字符串)

正确示例XML结构:

<entry xmlns="http://www.w3.org/2005/Atom" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
  <title />
  <updated>2024-05-20T12:34:56Z</updated>
  <author><name /></author>
  <id />
  <content type="application/xml">
    <m:properties>
      <d:PartitionKey>TestPartition</d:PartitionKey>
      <d:RowKey>TestRow001</d:RowKey>
      <d:SessionID m:type="Edm.Guid">550e8400-e29b-41d4-a716-446655440000</d:SessionID>
      <d:TotalCount m:type="Edm.Int64">9876543210</d:TotalCount>
      <d:IsActive m:type="Edm.Boolean">true</d:IsActive>
    </m:properties>
  </content>
</entry>

JSON格式

如果使用JSON提交请求,类型标记的格式与XML不同,需注意:

  • 请求头设置为Content-Type: application/json;odata=nometadata(最简格式,推荐)
  • 类型标记通过[字段名]@odata.type的形式指定,与字段值同级
  • Edm.Int64类型建议用字符串传递,避免数字精度丢失

正确示例JSON结构:

{
  "PartitionKey": "TestPartition",
  "RowKey": "TestRow002",
  "SessionID": "550e8400-e29b-41d4-a716-446655440000",
  "SessionID@odata.type": "Edm.Guid",
  "TotalCount": "9876543210",
  "TotalCount@odata.type": "Edm.Int64",
  "IsActive": true,
  "IsActive@odata.type": "Edm.Boolean"
}

通用注意事项

  • Edm类型名称必须严格匹配:Edm.String、Edm.Guid、Edm.Int64、Edm.Double、Edm.Boolean、Edm.DateTimeOffset等,大小写敏感
  • 字段内容必须符合类型要求:比如Edm.DateTimeOffset必须是ISO 8601格式(如2024-05-20T12:34:56Z)
  • 确保PartitionKey和RowKey字段存在且格式正确,这两个是必填项
  • 检查请求签名的正确性:虽然移除类型标记后请求成功,但如果签名有误也可能触发400,需确认签名逻辑正确

代码示例

PowerShell(JSON格式)

$storageAccount = "your-storage-account"
$tableName = "your-table-name"
$accountKey = "your-storage-key"
$apiVersion = "2020-08-04"

# 生成RFC1123格式的日期
$date = [DateTime]::UtcNow.ToString("R")
$resourcePath = "/$storageAccount/$tableName"

# 计算SharedKey签名(需自行实现或使用Azure模块的签名函数)
$authHeader = "SharedKey $storageAccount : $(Get-StorageSharedKey -AccountName $storageAccount -AccountKey $accountKey -Resource $resourcePath -Date $date)"

# 构建请求体
$requestBody = @"
{
  "PartitionKey": "TestPartition",
  "RowKey": "PS-Test-001",
  "UserID": "1234567890123",
  "UserID@odata.type": "Edm.Int64",
  "SessionID": "550e8400-e29b-41d4-a716-446655440000",
  "SessionID@odata.type": "Edm.Guid"
}
"@

# 发送请求
$headers = @{
    "x-ms-date" = $date
    "Authorization" = $authHeader
    "Content-Type" = "application/json;odata=nometadata"
    "x-ms-version" = $apiVersion
}

try {
    $response = Invoke-RestMethod -Uri "https://$storageAccount.table.core.windows.net/$tableName" -Method Post -Headers $headers -Body $requestBody
    Write-Host "实体插入成功:$($response.RowKey)"
} catch {
    Write-Host "错误:$($_.Exception.Response.StatusCode) $($_.Exception.Response.StatusText)"
    Write-Host "响应内容:$($_.Exception.Response.Content.ReadAsStringAsync().Result)"
}

VBScript(Atom XML格式)

Set xmlHttp = CreateObject("MSXML2.XMLHTTP.6.0")
storageAccount = "your-storage-account"
tableName = "your-table-name"
accountKey = "your-storage-key"
apiVersion = "2020-08-04"

' 生成RFC1123格式日期
dateStr = GetRFC1123Date()
resourcePath = "/" & storageAccount & "/" & tableName
authHeader = GetSharedKeyAuth(storageAccount, accountKey, resourcePath, dateStr)

' 构建请求URL和头部
requestUrl = "https://" & storageAccount & ".table.core.windows.net/" & tableName
xmlHttp.Open "POST", requestUrl, False
xmlHttp.setRequestHeader "x-ms-date", dateStr
xmlHttp.setRequestHeader "Authorization", authHeader
xmlHttp.setRequestHeader "Content-Type", "application/atom+xml"
xmlHttp.setRequestHeader "x-ms-version", apiVersion

' 构建XML请求体
xmlBody = "<entry xmlns='http://www.w3.org/2005/Atom' xmlns:d='http://schemas.microsoft.com/ado/2007/08/dataservices' xmlns:m='http://schemas.microsoft.com/ado/2007/08/dataservices/metadata'>" & _
          "<title />" & _
          "<updated>" & GetISODate() & "</updated>" & _
          "<author><name /></author>" & _
          "<id />" & _
          "<content type='application/xml'>" & _
          "<m:properties>" & _
          "<d:PartitionKey>TestPartition</d:PartitionKey>" & _
          "<d:RowKey>VBS-Test-001</d:RowKey>" & _
          "<d:UserID m:type='Edm.Int64'>1234567890123</d:UserID>" & _
          "<d:SessionID m:type='Edm.Guid'>550e8400-e29b-41d4-a716-446655440000</d:SessionID>" & _
          "</m:properties>" & _
          "</content>" & _
          "</entry>"

' 发送请求
xmlHttp.send xmlBody

If xmlHttp.Status = 201 Then
    WScript.Echo "实体插入成功"
Else
    WScript.Echo "错误代码:" & xmlHttp.Status & " " & xmlHttp.statusText
    WScript.Echo "响应详情:" & xmlHttp.responseText
End If

' 辅助函数:生成RFC1123格式日期
Function GetRFC1123Date()
    Dim dt, tz
    dt = UTCNow()
    tz = "GMT"
    GetRFC1123Date = WeekdayName(Weekday(dt), False) & ", " & _
                      Right("0" & Day(dt), 2) & " " & _
                      MonthName(Month(dt), True) & " " & _
                      Year(dt) & " " & _
                      Right("0" & Hour(dt), 2) & ":" & _
                      Right("0" & Minute(dt), 2) & ":" & _
                      Right("0" & Second(dt), 2) & " " & tz
End Function

' 辅助函数:生成ISO格式日期
Function GetISODate()
    Dim dt
    dt = UTCNow()
    GetISODate = Year(dt) & "-" & Right("0" & Month(dt), 2) & "-" & Right("0" & Day(dt), 2) & "T" & _
                 Right("0" & Hour(dt), 2) & ":" & Right("0" & Minute(dt), 2) & ":" & Right("0" & Second(dt), 2) & "Z"
End Function

' 辅助函数:获取UTC时间
Function UTCNow()
    UTCNow = DateAdd("h", -DateDiff("h", Now(), UTCNow()), Now())
End Function

' 辅助函数:计算SharedKey签名(需自行实现完整的HMAC-SHA256签名逻辑)
Function GetSharedKeyAuth(accountName, accountKey, resource, dateStr)
    ' 实现签名逻辑,生成符合要求的Authorization头部
    GetSharedKeyAuth = "SharedKey " & accountName & ": [签名内容]"
End Function

内容的提问来源于stack exchange,提问作者Tim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 06:24:35