使用 Web API 执行条件操作

 

发布日期: 2017年1月

适用于: Dynamics 365 (online),Dynamics 365 (on-premises),Dynamics CRM 2016,Dynamics CRM Online

Microsoft Dynamics 365 为由称为 ETag 的标准版本控制机制 HTTP 资源的一组条件操作提供支持。

本主题内容

ETags

If-Match 和 If-None-Match 标头

条件检索

限制 upsert 操作

应用乐观并发

ETags

HTTP 协议定义实体标记,或简称 ETag,确定资源的具体版本。 ETag 是其具体值为实施依赖项的不透明标识符。 ETag 值有两种变体:强验证和弱验证。 强验证表示由具体 URI 标识的一个唯一资源,如果其对应的 ETag 值不变,则将在二进制级别上相同。 弱验证仅保证资源表征在语义上与相同的 ETag 值相等。

Dynamics 365 为每一个实体案例生成一个弱验证的 @odata.etag 属性,且该属性与每一个被检索的实体记录一起自动返回。 有关详细信息,请参阅使用 Web API 检索实体

If-Match 和 If-None-Match 标头

使用 If-MatchIf-None-Match 标头与 ETag 值一起检测资源的当前版本是否匹配上一次检索的版本,匹配以前的版本或者不匹配任何版本。 这些对比构成条件操作支持的基础。 Dynamics 365 提供 ETag 以支持条件检索、乐观并发和受限 upsert 操作。

警告

客户端节点不应对 ETag 的特定值或 ETag 间的任何明显关系赋予任何超越相等或不相等的意义。 例如,一个较新版本的资源的 ETag 值不保证优越于较早版本的 ETag 值。 此外,用于生成新 ETag 值的算法可能在不同的服务版本之间有所更改, 恕不另行通知。

条件检索

Etag 允许您在多次访问相同记录时优化记录检索。 如果您以前检索了某条记录,您可以跳过具有 If-None-Match 标题的 ETag 值,请求仅当数据在上次检索后被更改时才进行检索。 如果数据已更改,请求将返回 HTTP 状态 200 (OK),并在请求正文中返回最新数据。 如果数据未更改,HTTP 状态代码 304 (Not Modified) 将返回,指示实体未修改。 如果数据自从上次检索后未发生更改,下列示例消息对将返回 accountid 的账户实体的数据,等于 00000000-0000-0000-0000-000000000001。

  • 请求

    GET cc_WebAPI_ServiceURI/accounts(00000000-0000-0000-0000-000000000001)?$select=accountcategorycode,accountnumber,creditonhold,createdon,numberofemployees,name,revenue   HTTP/1.1
    Accept: application/json
    OData-MaxVersion: 4.0
    OData-Version: 4.0
    If-None-Match: W/"468026"
    
  • 响应

    HTTP/1.1 304 Not Modified
    Content-Type: application/json; odata.metadata=minimal
    OData-Version: 4.0
    

限制 upsert 操作

upsert 通常通过创建不存在的实体进行操作;或者更新现有实体。 但是,ETag 可用来进一步限制 upsert 阻止创建或阻止更新。

阻止在 upsert 中创建

如果更新数据,并且有某种可能会有意删除实体,则您不想再创建实体。 若要防止出现此情况,添加 If-Match 标题到值为 "*" 的请求。

  • 请求

    PATCH cc_WebAPI_ServiceURI/accounts(00000000-0000-0000-0000-000000000001) HTTP/1.1
    Content-Type: application/json
    OData-MaxVersion: 4.0
    OData-Version: 4.0
    If-Match: "*"
    
    {
        "name": "Updated Sample Account ",
        "creditonhold": true,
        "address1_latitude": 47.639583,
        "description": "This is the updated description of the sample account",
        "revenue": 6000000,
        "accountcategorycode": 2
    }
    
  • 响应
    如果找到实体,您将收到状态 204 的正常响应 (No Content)。 如果未找到实体,您将收到状态 404 的以下响应 (Not Found)。

    HTTP/1.1 404 Not Found
    OData-Version: 4.0
    Content-Type: application/json; odata.metadata=minimal
    
    {
     "error": {
      "code": "",
      "message": "account With Id = 00000000-0000-0000-0000-000000000001 Does Not Exist",
      "innererror": {
       "message": "account With Id = 00000000-0000-0000-0000-000000000001 Does Not Exist",
       "type": "System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=8.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]",
       "stacktrace": <stack trace removed for brevity>
      }
     }
    }
    

阻止在 upsert 中更新

如果在插入数据,有某种可能具有相同 id 值的记录已存在于系统中,您可能不希望更新它。 若要防止出现此情况,添加 If-None-Match 标题到值为 "*" 的请求。

  • 请求

    PATCH cc_WebAPI_ServiceURI/accounts(00000000-0000-0000-0000-000000000001) HTTP/1.1
    Content-Type: application/json
    OData-MaxVersion: 4.0
    OData-Version: 4.0
    If-None-Match: "*"
    
    {
        "name": "Updated Sample Account ",
        "creditonhold": true,
        "address1_latitude": 47.639583,
        "description": "This is the updated description of the sample account",
        "revenue": 6000000,
        "accountcategorycode": 2
    }
    
  • 响应
    如果未找到实体,您将收到状态 204 的正常响应 (No Content)。 如果找到实体,您将收到状态 412 的以下响应 (Precondition Failed)。

    HTTP/1.1 412 Precondition Failed
    OData-Version: 4.0
    Content-Type: application/json; odata.metadata=minimal
    
    {
      "error":{
       "code":"",
       "message":"A record with matching key values already exists.",
       "innererror":{
        "message":"Cannot insert duplicate key.",
        "type":"System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=8.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]",
        "stacktrace":<stack trace removed for brevity>
        }
      }
    }
    

应用乐观并发

可以使用乐观并发检测实体自上次检索后是否被修改。 如果您在服务器上更新或删除的实体在您检索后已更改,您可能不希望完成更新或删除操作。 通过应用此处显示的模式,您可以检测此情况,检索最新的实体版本,应用所有必要条件以评估是否重试该操作。

在删除中应用乐观并发

具有 accountid of00000000-0000-0000-0000-000000000001 的帐户的以下删除请求失败,原因是随 If-Match 标头发送的 ETag 值与当前值不同。 如果值匹配,则状态 204 (No Content) 是预期结果。

  • 请求

    DELETE cc_WebAPI_ServiceURI/accounts(00000000-0000-0000-0000-000000000001) HTTP/1.1
    If-Match: W/"470867"
    Accept: application/json
    OData-MaxVersion: 4.0
    OData-Version: 4.0
    
  • 响应

    HTTP/1.1 412 Precondition Failed
    Content-Type: application/json; odata.metadata=minimal
    OData-Version: 4.0
    
    {
      "error":{
        "code":"","message":"The version of the existing record doesn't match the RowVersion property provided.",
        "innererror":{
          "message":"The version of the existing record doesn't match the RowVersion property provided.",
          "type":"System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=8.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]",
    "stacktrace":"  <stack trace details omitted for brevity>
        }
      }
    }
    

在更新中应用乐观并发

具有 accountid00000000-0000-0000-0000-000000000001 的帐户的以下更新请求失败,原因是随 If-Match 标头发送的 ETag 值与当前值不同。 如果值匹配,则状态 204 (No Content) 是预期结果。

  • 请求

    PATCH cc_WebAPI_ServiceURI/accounts(00000000-0000-0000-0000-000000000001) HTTP/1.1
    If-Match: W/"470867"
    Accept: application/json
    OData-MaxVersion: 4.0
    OData-Version: 4.0
    
    {"name":"Updated Account Name"}
    
  • 响应

    HTTP/1.1 412 Precondition Failed
    Content-Type: application/json; odata.metadata=minimal
    OData-Version: 4.0
    
    {
      "error":{
        "code":"","message":"The version of the existing record doesn't match the RowVersion property provided.",
        "innererror":{
          "message":"The version of the existing record doesn't match the RowVersion property provided.",
          "type":"System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=8.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]",
    "stacktrace":"  <stack trace details omitted for brevity>
        }
      }
    }
    

另请参阅

Web API 条件操作示例 (C#)
Web API 条件操作示例(客户端 JavaScript)
使用 Web API 执行操作
撰写 HTTP 请求并处理错误
使用 Web API 查询数据
使用 Web API 创建实体
使用 Web API 检索实体
使用 Web API 更新和删除实体
使用 Web API 关联和解除关联实体
使用 Web API 功能
使用 Web API 操作
使用 Web API 执行批处理操作
使用 Web API 模拟其他用户

Microsoft Dynamics 365

© 2017 Microsoft。 保留所有权利。 版权