Hi Franz,
Here is my complete C# code:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace OData_Test_comm
{
public partial class Form1 : Form
{
//Added Nuget: Install-Package Newtonsoft.Json -Version 12.0.3
//Added Nuget: Install-Package Microsoft.AspNet.WebApi.Client -Version 5.2.7
public List<WorkersClass> WorkersReadFromAlWebService = new List<WorkersClass>();
static HttpClient Http_client = new HttpClient();
public class WorkersClass
{
public string E_Tag = string.Empty; // Unique key
public string No = string.Empty; // In AL No. is renamed to No during serialisation
public string First_name = string.Empty;// In AL First Name is renamed to First_Name during serialisation ====> used by accident First name (small n) in D365BC!!
public string Last_Name = string.Empty;
public string FunctionName = string.Empty;
}
public class WorkersWS
{//For creation I tried passing this record or above, makes no difference, but as there is no E-tag when you create the record, I tried this.
public string No = string.Empty; // In AL No. is renamed to No during serialisation
public string First_name = string.Empty;// In AL First Name is renamed to First_Name during serialisation ====> used by accident First name (small n) in D365BC!!
public string Last_Name = string.Empty;
public string FunctionName = string.Empty;
}
public Form1()
{
InitializeComponent();
}
private void btnFindWorkerOdata_Click(object sender, EventArgs e)
{//WORKS OK
listBox1.Items.Clear();
WorkersReadFromAlWebService = new List<WorkersClass>();
string _url = "">api.businesscentral.dynamics.com/…/CardPage
HttpWebRequest _request = (HttpWebRequest)WebRequest.Create(_url);
_request.ContentType = "application/json; charset=utf-8";
_request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes("UserName:Password"));
_request.PreAuthenticate = true;
HttpWebResponse _response = _request.GetResponse() as HttpWebResponse;
using (Stream _responseStream = _response.GetResponseStream())
{
var x = _response.Headers.AllKeys;
StreamReader _reader = new StreamReader(_responseStream, Encoding.UTF8);
string _content = _reader.ReadToEnd();
string _jasonPart = GetJsonPartMultiRecord(_content);
List<WorkersClass> _jWorkers = JsonConvert.DeserializeObject<List<WorkersClass>>(_jasonPart);
foreach (var _worker in _jWorkers)
{
WorkersReadFromAlWebService.Add(_worker);
listBox1.Items.Add(_worker.Last_Name + " / " + _worker.First_name + " (No: " + _worker.No + ")");
}
}
ClearWorker();
}
private void btnGetWorker1002Odata_Click(object sender, EventArgs e)
{//WORKS OK
listBox1.Items.Clear();
WorkersReadFromAlWebService = new List<WorkersClass>();
string _url = "">api.businesscentral.dynamics.com/.../CardPage
//string _url = "">api.businesscentral.dynamics.com/.../List Page
HttpWebRequest _request = (HttpWebRequest)WebRequest.Create(_url);
_request.ContentType = "application/json; charset=utf-8";
_request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes("UserName:Password"));
_request.PreAuthenticate = true;
HttpWebResponse _response = _request.GetResponse() as HttpWebResponse;
using (Stream _responseStream = _response.GetResponseStream())
{
var x = _response.Headers.AllKeys;
StreamReader _reader = new StreamReader(_responseStream, Encoding.UTF8);
string _content = _reader.ReadToEnd();
string _jasonPart = GetJsonPartSingleRecord(_content);
WorkersClass _worker = JsonConvert.DeserializeObject<WorkersClass>(_jasonPart);
WorkersReadFromAlWebService.Add(_worker);
listBox1.Items.Add(_worker.Last_Name + " / " + _worker.First_name + " (No: " + _worker.No + ")");
}
ClearWorker();
}
private async void btnDeleteSelectedRecordOdatas_Click(object sender, EventArgs e)
{//WORKS OK
try
{
//string _url = "">api.businesscentral.dynamics.com/.../Card Page
string _url = "">api.businesscentral.dynamics.com/.../List Page
string _userName = "UserName";
string _wsKey = "Password";
byte[] _authenticationParameter = Encoding.UTF8.GetBytes(_userName + ":" + _wsKey);
Http_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(_authenticationParameter));
//HttpResponseMessage response = await _client.DeleteAsync(_url + rtbE_Tag.Text);//.PostAsJsonAsync(_url, _worker);
HttpResponseMessage response = await Http_client.DeleteAsync(_url + "(No='" + tbNo.Text + "')");
response.EnsureSuccessStatusCode();
}
catch (Exception ex)
{
}
}
private async void btnCreateRecordOdata_Click(object sender, EventArgs e)
{//Here is the problem, it doesn't work
WorkersWS _data = new WorkersWS();
_data.No = tbNo.Text;
_data.First_name = tbFirstName.Text;
_data.Last_Name = tbLastName.Text;
_data.FunctionName = tbFunctionName.Text;
var url = await CreateWorkerAsync(_data);
}
public string GetJsonPartMultiRecord(string _webServiceReply)
{
string _retVal = _webServiceReply.Remove(0, _webServiceReply.IndexOf("[")); // Remove part before JSON
_retVal = _retVal.Replace("@odata.etag", "E_Tag"); // E_Tag can be a property name, @odata.etag cannot
_retVal = _retVal.Remove(_retVal.Length - 1); // Remove last } (part of what we removed at the start)
_retVal = _retVal.Replace("\\\"", ""); // Remove wrong quotes in value
return _retVal;
}
public string GetJsonPartSingleRecord(string _webServiceReply)
{
string _retVal = _webServiceReply.Remove(1, _webServiceReply.IndexOf("\"@odata.etag") - 1); // Remove part before JSON
_retVal = _retVal.Replace("@odata.etag", "E_Tag"); // E_Tag can be a property name, @odata.etag cannot
_retVal = _retVal.Replace("\\\"", ""); // Remove wrong quotes in value
return _retVal;
}
private void ClearWorker()
{
rtbE_Tag.Text = string.Empty;
tbNo.Text = string.Empty;
tbFirstName.Text = string.Empty;
tbLastName.Text = string.Empty;
tbFunctionName.Text = string.Empty;
}
static async Task<Uri> CreateWorkerAsync(WorkersWS _worker)
{
string _url = "https://api.businesscentral.dynamics.com/v2.0/SomeFunkyGuid/Sandbox/ODataV4/Company('CRONUS%20NL')/WorkersWebService";//Card Page
string _userName = "UserName";
string _wsKey = "Password";
byte[] _authenticationParameter = Encoding.UTF8.GetBytes(_userName + ":" + _wsKey);
Http_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(_authenticationParameter));
HttpResponseMessage response = await Http_client.PostAsJsonAsync(_url, _worker);
try
{
response.EnsureSuccessStatusCode();//Error 400 bad request for both _worker and data
}
catch (Exception ex)
{
}
// return URI of the created resource.
return response.Headers.Location;
}
}
}
D365BBC/AL code:
Table: TabWorkers.al
table 50109 "Workers"
{
DataClassification = ToBeClassified;
fields
{
field(1; "No."; Code[20])
{
DataClassification = ToBeClassified;
}
field(10; "First name"; Text[50])
{
DataClassification = ToBeClassified;
}
field(20; "Last Name"; Text[50])
{
DataClassification = ToBeClassified;
}
field(40; FunctionName; Text[50])
{
DataClassification = ToBeClassified;
}
}
trigger OnInsert()
var
myInt: Integer;
begin
end;
trigger OnModify()
var
myInt: Integer;
begin
end;
trigger OnDelete()
var
myInt: Integer;
begin
end;
}
Card page: CpWorkers.al
page 50108 "Workers Card"
{
PageType = Card;
ApplicationArea = All;
UsageCategory = Administration;
SourceTable = Workers;
layout
{
area(Content)
{
group(General)
{
field("No."; "No.")
{
ApplicationArea = Basic;
Importance = Promoted;
}
field("First name"; "First name")
{
ApplicationArea = Basic;
}
field("Last name"; "Last name")
{
ApplicationArea = Basic;
}
field(FunctionName; FunctionName)
{
ApplicationArea = Basic;
}
}
}
}
}
List page: LpWorkers.al
page 50109 "Workers List"
{
PageType = List;
ApplicationArea = All;
UsageCategory = Lists;
SourceTable = Workers;
layout
{
area(Content)
{
repeater(Group)
{
field("No."; "No.")
{
ApplicationArea = Basic;
}
field("First name"; "First name")
{
ApplicationArea = Basic;
}
field("Last Name"; "Last Name")
{
ApplicationArea = Basic;
}
field(FunctionName; FunctionName)
{
ApplicationArea = Basic;
}
}
}
}
}
WorkersWebService.xml:
<?xml version = "1.0" encoding = "utf-8" ?>
<ExportedData>
<TenantWebServiceCollection>
<TenanatWebService>
<ObjectType>Page</ObjectType>
<ObjectID>50108</ObjectID>
<ServiceName>WorkersWebService</ServiceName>
<Published>true</Published>
</TenanatWebService>
</TenantWebServiceCollection>
</ExportedData>
When I insert a record, It is like:
_data.No = tbNo.Text;// 1003
_data.First_name = tbFirstName.Text;//aaa
_data.Last_Name = tbLastName.Text;//bbb
_data.FunctionName = tbFunctionName.Text;/ccc
I hope this give you an insight to my problem.
Kind regards,
Clemens Linders