Обновление данных клиента в MS NAV с использованием OData из PHP не работает - PullRequest
0 голосов
/ 11 октября 2019

Я пытаюсь обновить данные о клиентах в MS NAV 2017, используя OData и PHP. Я могу читать и создавать клиентов с помощью / CustomerCard URI. Но я не могу заставить работать обновление (PATCH, MERGE или PUT). Я пробую несколько комбинаций, но безуспешно. Я также уже прочитал множество тем, форумов и т. Д.

Когда я хочу сделать PATCH для / Customer (No = XXXXXX), я получаю сообщение об ошибке: Ресурс не найден для сегмента 'Customer'.

Но когда я хочу сделать PATCH для / CustomerCard (No = XXXX), я получаю сообщение об ошибке: Bad Request - ошибка в синтаксисе запроса.

И когда я хочу сделатьPATCH на / CustomerCard без параметров, я получаю сообщение об ошибке: Запросы «PATCH» на «Collection» не поддерживаются веб-службами Microsoft Dynamics NAV OData.

Я отправляю 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));

1 Ответ

0 голосов
/ 14 октября 2019

Я нашел решение и документирую его здесь для других разработчиков. Вот изменения, которые я внес в свой предыдущий код:

  1. URI, который я сейчас использую: https://MYDOMAIN/ODatav4/CustomerCard('R1500000'), где R1500000 - номер клиента (уникальный идентификатор).
  2. Я не добавляю ETag и заголовок ETag в тело клиентской структуры JSON. Но я все еще отправляю заголовок ETag, полученный от операции GET, как значение заголовка If-Match в операции PATCH.
  3. Структура моего заголовка HTTP в вызове PATCH была неправильной. Я указал отдельно Accept, Content-Type и If-Match.

Итак, подведя итог, я исправил URI и HTTP-заголовок. Остальное было хорошо. Вот мой новый код:

$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));
...