使用 PHP 中的 OData 更新 MS NAV 中的客户数据无效
Update Customer data in MS NAV using OData from PHP not working
我正在尝试使用 OData 和 PHP 更新 MS NAV 2017 中的客户数据。
我可以使用 /CustomerCard uri 读取和创建客户。
但是我无法使更新工作(PATCH、MERGE 或 PUT)。
我尝试了几种组合但没有成功。我也已经阅读了很多帖子、论坛等
当我想在 /Customer(No=XXXXXX) 上执行 PATCH 时,我收到错误消息:找不到段 'Customer' 的资源。
但是当我想在 /CustomerCard(No=XXXX) 上执行 PATCH 时,我收到错误消息:错误请求 - 查询语法错误。
当我想在不带参数的情况下对 /CustomerCard 执行 PATCH 时,我收到错误消息:Microsoft Dynamics NAV OData Web 服务不支持 'PATCH' 对 'Collection' 的请求。
我正在 header 中发送 ETag。我尝试使用 PATCH、MERGE 和 PUT。相同的结果。
我是否缺少某些配置?
感谢您的帮助。
这是我的代码。
$customernb = "R1500000";
$url1 = 'https://MYDOMAIN/ODatav4/CustomerCard';
$url2 = '?$filter=No%20eq%20%27';
$url3 = '%27';
$url = $url1.$url2.$customernb.$url3;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
$username = "MYUSER";
$password = "MYPWD";
curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
$result = curl_exec($ch);
curl_close($ch);
$j = json_decode($result);
print_r($j);
// THIS WORKS FINE !
/*
* Update
*/
$newcustomer = new stdClass();
$newcustomer->Name = "OMEGA SHIRT UPDATED";
$newcustomer->Salesperson_Code = "JVP";
$newcustomer->Sales_Contact_Code = "TFS";
$etag = $j->value[0]->ETag;
$headeretag = $j->value[0]->{'@odata.etag'};
$newcustomer->ETag = $etag;
$newcustomer->{'@odata.etag'} = $headeretag;
$jsonDataEncoded = json_encode($newcustomer);
$url5 = 'https://MYDOMAIN/ODatav4/CustomerCard('.$j->value[0]->No.')';
//$url5 = 'https://MYDOMAIN/ODatav4/CustomerCard';
//$url5 = 'https://MYDOMAIN/ODatav4/CustomerCard?$filter=No%20eq%20%27'.$j->value[0]->No.'%27';
$ch = curl_init($url5);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PATCH");
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonDataEncoded);
//$encodedetag = "W/\"'".urlencode($etag)."'\"";
$encodedetag = $headeretag;
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json;If-Match: '.$encodedetag));
//$headers.Add("If-Match",'W/"' + "'" + [uri]::EscapeDataString($JToken.ETag.ToString()) + "'" + '"') #Etag Value
curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
//CURLAUTH_NTLM
$result = curl_exec($ch);
print_r(json_decode($result));
我找到了解决方案并将其记录在此处供其他开发人员使用。
以下是我对以前的代码所做的更改:
- 我现在使用的 URI 是:https://MYDOMAIN/ODatav4/CustomerCard('R1500000') 其中 R1500000 是客户编号(唯一 ID)。
- 我没有在 JSON 客户结构的 body 中添加 ETag 和 header ETag。但我仍然提交从 GET 操作收到的 header ETag 作为 PATCH 操作中的 If-Match header 值。
- 我的 HTTP Header 在 PATCH 调用中的结构不正确。我分别指定了 Accept、Content-Type 和 If-Match。
总而言之,我修复了 URI 和 HTTP Header。其余的都很好。
这是我的新代码:
$customernb = "R1500000";
$url1 = 'https://MYDOMAIN/ODatav4/CustomerCard';
$url2 = '(\'';
$url3 = '\')';
$url = $url1.$url2.$customernb.$url3;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
$username = "MYUSER";
$password = "MYPWD";
curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
$result = curl_exec($ch);
curl_close($ch);
$j = json_decode($result);
print_r($j);
/*
* Update
*/
$newcustomer = new stdClass();
$newcustomer->Name = "OMEGA SHIRT UPDATED";
$newcustomer->Salesperson_Code = "JVP";
$newcustomer->Sales_Contact_Code = "TFS";
$etag = $j->value[0]->ETag;
$headeretag = $j->value[0]->{'@odata.etag'};
$jsonDataEncoded = json_encode($newcustomer);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PATCH");
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonDataEncoded);
$encodedetag = $headeretag;
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json','Content-Type: application/json','If-Match: '.$encodedetag));
curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
$result = curl_exec($ch);
print_r(json_decode($result));
我正在尝试使用 OData 和 PHP 更新 MS NAV 2017 中的客户数据。 我可以使用 /CustomerCard uri 读取和创建客户。 但是我无法使更新工作(PATCH、MERGE 或 PUT)。 我尝试了几种组合但没有成功。我也已经阅读了很多帖子、论坛等
当我想在 /Customer(No=XXXXXX) 上执行 PATCH 时,我收到错误消息:找不到段 'Customer' 的资源。
但是当我想在 /CustomerCard(No=XXXX) 上执行 PATCH 时,我收到错误消息:错误请求 - 查询语法错误。
当我想在不带参数的情况下对 /CustomerCard 执行 PATCH 时,我收到错误消息:Microsoft Dynamics NAV OData Web 服务不支持 'PATCH' 对 'Collection' 的请求。
我正在 header 中发送 ETag。我尝试使用 PATCH、MERGE 和 PUT。相同的结果。
我是否缺少某些配置?
感谢您的帮助。
这是我的代码。
$customernb = "R1500000";
$url1 = 'https://MYDOMAIN/ODatav4/CustomerCard';
$url2 = '?$filter=No%20eq%20%27';
$url3 = '%27';
$url = $url1.$url2.$customernb.$url3;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
$username = "MYUSER";
$password = "MYPWD";
curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
$result = curl_exec($ch);
curl_close($ch);
$j = json_decode($result);
print_r($j);
// THIS WORKS FINE !
/*
* Update
*/
$newcustomer = new stdClass();
$newcustomer->Name = "OMEGA SHIRT UPDATED";
$newcustomer->Salesperson_Code = "JVP";
$newcustomer->Sales_Contact_Code = "TFS";
$etag = $j->value[0]->ETag;
$headeretag = $j->value[0]->{'@odata.etag'};
$newcustomer->ETag = $etag;
$newcustomer->{'@odata.etag'} = $headeretag;
$jsonDataEncoded = json_encode($newcustomer);
$url5 = 'https://MYDOMAIN/ODatav4/CustomerCard('.$j->value[0]->No.')';
//$url5 = 'https://MYDOMAIN/ODatav4/CustomerCard';
//$url5 = 'https://MYDOMAIN/ODatav4/CustomerCard?$filter=No%20eq%20%27'.$j->value[0]->No.'%27';
$ch = curl_init($url5);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PATCH");
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonDataEncoded);
//$encodedetag = "W/\"'".urlencode($etag)."'\"";
$encodedetag = $headeretag;
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json;If-Match: '.$encodedetag));
//$headers.Add("If-Match",'W/"' + "'" + [uri]::EscapeDataString($JToken.ETag.ToString()) + "'" + '"') #Etag Value
curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
//CURLAUTH_NTLM
$result = curl_exec($ch);
print_r(json_decode($result));
我找到了解决方案并将其记录在此处供其他开发人员使用。 以下是我对以前的代码所做的更改:
- 我现在使用的 URI 是:https://MYDOMAIN/ODatav4/CustomerCard('R1500000') 其中 R1500000 是客户编号(唯一 ID)。
- 我没有在 JSON 客户结构的 body 中添加 ETag 和 header ETag。但我仍然提交从 GET 操作收到的 header ETag 作为 PATCH 操作中的 If-Match header 值。
- 我的 HTTP Header 在 PATCH 调用中的结构不正确。我分别指定了 Accept、Content-Type 和 If-Match。
总而言之,我修复了 URI 和 HTTP Header。其余的都很好。 这是我的新代码:
$customernb = "R1500000";
$url1 = 'https://MYDOMAIN/ODatav4/CustomerCard';
$url2 = '(\'';
$url3 = '\')';
$url = $url1.$url2.$customernb.$url3;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
$username = "MYUSER";
$password = "MYPWD";
curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
$result = curl_exec($ch);
curl_close($ch);
$j = json_decode($result);
print_r($j);
/*
* Update
*/
$newcustomer = new stdClass();
$newcustomer->Name = "OMEGA SHIRT UPDATED";
$newcustomer->Salesperson_Code = "JVP";
$newcustomer->Sales_Contact_Code = "TFS";
$etag = $j->value[0]->ETag;
$headeretag = $j->value[0]->{'@odata.etag'};
$jsonDataEncoded = json_encode($newcustomer);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PATCH");
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonDataEncoded);
$encodedetag = $headeretag;
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json','Content-Type: application/json','If-Match: '.$encodedetag));
curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
$result = curl_exec($ch);
print_r(json_decode($result));