microsoft / cal-open-library Goto Github PK
View Code? Open in Web Editor NEWC/AL Open Library is a repository for .NET Interop wrappers that will be included into Dynamics 365 for Financials and usable from Extensions V2
License: MIT License
C/AL Open Library is a repository for .NET Interop wrappers that will be included into Dynamics 365 for Financials and usable from Extensions V2
License: MIT License
Hello Dev Team,
I was trying to migrate some code from C/AL to new AL language, but unfortunately my old code uses .NET class MemoryStream.
So I tried to use the new wrapper codeunit 704. But when I try that, i have some issues:
Well, I checked the codeunit and none of the functions have FunctionVisiblity = External. I am using the latest (german) developer preview. Is there a way around that or can you please make the functions accessible for extension development?
Thanks and keep on the good work, guys!
The issue has been moved from Microsoft/AL to the cal-open-library; a workaround could be to set the app target to internal
For the request RegEx.Replace from Microsoft/AL #266
Introduction of Regular Expression Replace in Codeunit Type Helper 10:
[External] RegexReplace(StringToReplace : Text;Pattern : Text;NewValue : Text) : Text
Regex := Regex.Regex(Pattern);
NewString := Regex.Replace(StringToReplace,NewValue);
EXIT(NewString);
[External] RegexReplaceIgnoreCase(StringToReplace : Text;Pattern : Text;NewValue : Text) : Text
Regex := Regex.Regex(Pattern,RegexOptions.IgnoreCase);
NewString := Regex.Replace(StringToReplace,NewValue);
EXIT(NewString);
My current requirement is for a Type 4 GUID generated using a secure random number generator.
It is currently possible to indirectly call RNGCryptoServiceProvider
through the GeneratePassword
function in CU1267. But this returns a string that has been heavily processed, so to smooth it out I feed a long password through a hash from CU1266 and convert the returned hex to a text format GUID.
This is a little bit "Heath Robinson" so please would you add wrappers for RNGCryptoServiceProvider
that return a requested number of bytes as hex or base64 and a third wrapper that returns a secure GUID.
Codeunit 408 "Dimension Management" -> DefaultDimObjectNoList
Function is class internal, however, it can be converted intact to Extension level AL code.
The same seems to be true for all other "Internal" functions in CU408.
codeunit 60001 "Table Dimension Extra Checks"
{
trigger OnRun()
begin
end;
[EventSubscriber(ObjectType::Table, 60000, 'OnAfterValidateEvent', 'Create Default Dim', false, false)]
local procedure OnAfterValidateT60000CreateDefaultDim(var Rec: Record "Table Dimension";var xRec: Record "Table Dimension";CurrFieldNo: Integer)
begin
Rec."Create Default Dim" := HasDefaultDims(Rec."Table ID");
end;
procedure HasDefaultDims("Table ID": Integer): Boolean
var
DimMgt: Codeunit DimensionManagement;
TempObject: Record AllObjWithCaption temporary;
begin
/*DimMgt.*/ DefaultDimObjectNoList(TempObject);
TempObject."Object Type" := TempObject."Object Type"::Table;
TempObject."Object ID" := "Table ID";
exit(TempObject.FIND);
end;
local procedure "--Dim Mgt"()
begin
end;
procedure DefaultDimObjectNoList(var TempAllObjWithCaption: Record AllObjWithCaption temporary)
begin
DefaultDimObjectNoWithoutGlobalDimsList(TempAllObjWithCaption);
DefaultDimObjectNoWithGlobalDimsList(TempAllObjWithCaption);
end;
procedure DefaultDimObjectNoWithGlobalDimsList(var TempAllObjWithCaption: Record AllObjWithCaption temporary)
var
TempDimField: Record "Field" temporary;
TempDimSetIDField: Record "Field" temporary;
begin
TempDimField.SETFILTER(TableNo,'<>%1&<>%2',DATABASE::"General Ledger Setup",DATABASE::"Job Task");
TempDimField.SETFILTER(FieldName,'*Global Dimension*');
TempDimField.SETRANGE(Type,TempDimField.Type::Code);
TempDimField.SETRANGE(Len,20);
FillNormalFieldBuffer(TempDimField);
TempDimSetIDField.SETRANGE(RelationTableNo,DATABASE::"Dimension Set Entry");
FillNormalFieldBuffer(TempDimSetIDField);
if TempDimField.FINDSET then
repeat
TempDimSetIDField.SETRANGE(TableNo,TempDimField.TableNo);
if TempDimSetIDField.ISEMPTY then
InsertObject(TempAllObjWithCaption,TempDimField.TableNo);
until TempDimField.NEXT = 0;
// OnAfterSetupObjectNoList(TempAllObjWithCaption);
end;
local procedure DefaultDimObjectNoWithoutGlobalDimsList(var TempAllObjWithCaption: Record AllObjWithCaption temporary)
begin
DefaultDimInsertTempObject(TempAllObjWithCaption,DATABASE::"IC Partner");
DefaultDimInsertTempObject(TempAllObjWithCaption,DATABASE::"Service Order Type");
DefaultDimInsertTempObject(TempAllObjWithCaption,DATABASE::"Service Item Group");
DefaultDimInsertTempObject(TempAllObjWithCaption,DATABASE::"Service Item");
DefaultDimInsertTempObject(TempAllObjWithCaption,DATABASE::"Service Contract Template");
DefaultDimInsertTempObject(TempAllObjWithCaption,DATABASE::"Service Contract Header");
end;
local procedure DefaultDimInsertTempObject(var TempAllObjWithCaption: Record AllObjWithCaption temporary;TableID: Integer)
begin
TempAllObjWithCaption.INIT;
TempAllObjWithCaption."Object Type" := TempAllObjWithCaption."Object Type"::Table;
TempAllObjWithCaption."Object ID" := TableID;
TempAllObjWithCaption.INSERT;
end;
local procedure FillNormalFieldBuffer(var TempField: Record "Field")
var
"Field": Record "Field";
begin
Field.COPYFILTERS(TempField);
Field.SETRANGE(Class,Field.Class::Normal);
if Field.FINDSET then
repeat
TempField := Field;
TempField.INSERT;
until Field.NEXT = 0;
end;
[Scope('Personalization')]
procedure InsertObject(var TempAllObjWithCaption: Record AllObjWithCaption temporary;TableID: Integer)
var
AllObjWithCaption: Record AllObjWithCaption;
begin
if AllObjWithCaption.GET(AllObjWithCaption."Object Type"::Table,TableID) then begin
TempAllObjWithCaption := AllObjWithCaption;
if TempAllObjWithCaption.INSERT then;
end;
end;
}
The latest rev of COL contains codeunits not present in the latest available release of BC -- e.g., COD30XX.txt (XX > 27). I am trying to prepare a submission to the COL but I need to develop against the latest COL version. I pulled the latest BC on-prem image (13.0.24623) and the latest BC docker image (13.0.24630.25789) neither of which contain the latest COL. I am not able to import the .txt files due to license / object range restrictions.
How should I proceed?
(please don't say wait until next month)
Thanks in advance.
Hello
I want to make use of the functions ConvertValueToBase64
and ConvertValueFromBase64
in this new COD10 Type helper, in order to get rid of dotnet-usage.
How do I do this?
Can I download the COD10.txt from the CAL-open-library, import it into NAV CSIDE and compile the object?
If I then do 'download symbols', can I make a variable of codeunit 10 and call those functions?
Kind Regards,
SirBETE
How to get private key from certificate?
For example use to SignXmlText function?
I run through all codeunits and i see no way.
I wanted to make extension that has to sign an xml and send it.
So i would appreciate some help.
Hi, could you add the following method:
[External] ISO88591()
DotNetEncoding := DotNetEncoding.GetEncoding('iso-8859-1');
It would be great if the function were present in the codeunit. This would no longer require a DotNet variable in my calling object.
Thank you!
DateTimes in .NET support several Add* methods, e.g. AddDays, AddHours etc. It would be great to have these in the wrapper codeunit as well, especially since there's also no native C/SIDE way to manipulate datetimes like this that I'm aware of. Thanks for considering!
The codeunit 6227 contains an error when checking a signed XML file. The check is only successful if the XML text passed does not contain any processing instructions. However, as soon as this contains an instruction, the check always fails. The error is in the following line:
SignatureNode := XmlDocument.FirstChild.SelectSingleNode('xmlsig:Signature',XmlNamespaceManager);
Due to the "FirstChild" property, finding the required XML node is only successful if no processing instruction is passed. This is because it is also to be regarded as a child. A correction should be made that enables both cases to be covered and thus a successful XML signature check to be performed.
This also requires an adjustment. In the function where you can create new signatures and return the text, you get an XML text file, which also does not contain any processing instructions. The file starts immediately with the root element.
Hello,
I would like the function ProcessFaultJsonResponse in the codeunit 1297 to be global, but when checking the repository online I saw it differs from the NAVW114.00 version of the codeunit and doesn't contain the function.
Will you still be supporting this codeunit?
Would it be possible to make the function ProcessFaultJsonResponse global?
How could we create a pull request in the future for this kind of changes?
Dear regards,
Sjoerd de Clippelaar
Mysolution BV
Missing dotnet in the codeunits in the 3000 range:
System.IO.FileStream.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
System.IO.FileMode.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
Missing functions in existing 3000:*
cu3026 DotNet_Encoding: Encoding.BigEndianUnicode; Encoding := Encoding.UTF7;
cu3008 DotNet_Convert: Convert.ToInt32(Hex,16)
Can the codeunits in the range 3000 be extended with libraries and functions added above?
Thank you.
Dear,
about: OBJECT Codeunit 3031 DotNet_SmtpMessage
this wrapper is still based on the Microsoft.Dynamics.Nav.SMTP. Why?
We already created in NAV a codeunit our shelves based on
System.Net.Mail.SmtpClient.'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
and
System.Net.Mail.MailMessage.'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
makes a NAV dll less and there are more possibilities .
But the actual problem is this, we need the Alternative view on the MailMessage.
why? Because without it NAV scores very high in the spam filtering rate when mailing because there is no possibility when adding a HTML body, to also add the plain text body as extra view. which is required to score less high as potential spammer.
the difference is a full 1 point on the spam score!
I cannot contribute to the OBJECT Codeunit 3031 DotNet_SmtpMessage because the DotNet Microsoft.Dynamics.Nav.SMTP does not have the alternative view exposed of the dotnet MailMessage.
What to do now? should i add a whole new 3000 SMTP codeunit based on the actual dotnet framework? (will probably be refused) or may i rewrite this codeunit to the actual dotnet framework? or can Alternative view be added in the Microsoft.Dynamics.Nav.SMTP dll?
else this wrapper is worthless because of high spam rate.
Awaiting your request.
Is it allowed to submit wrappers with own. NET library?
Im trying to recreate this c# function in BC and i'm having problem with X509Certificate2, can you please point me in right direction?
public static void SupportPing()
{
string EndPoint = Properties.Settings.Default.SupportServicesEndPoint;
WSHttpBinding binding = new WSHttpBinding();
http://binding.Security .Mode = SecurityMode.Transport;
http://binding.Security .Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
SupportServicesClient service = new SupportServicesClient(binding, new EndpointAddress(EndPoint));
X509Certificate2 cert = new X509Certificate2(Properties.Settings.Default.CertificateFilePath, Properties.Settings.Default.PrivateKeyPassword, X509KeyStorageFlags.PersistKeySet);
service.ClientCredentials.ClientCertificate.Certificate = cert;
service.Endpoint.EndpointBehaviors.Add(new CustomMessageInspector());
SupportPingRequest ping = new SupportPingRequest();
ping.Input = "Hello World!";
SupportPingResponse pingResponse = service.PingSupport(ping);
Console.WriteLine(pingResponse.Output);
}
To transfer files from and to NAV with SOAP web service, we use a parameter of type "BigText".
In the NAV function we uses dotnet to write to OutStream. Suggestion to make 2 cal-open-library funtions to handle this. Please read this post descriping how-to. Please read all comments in the post.
Kauffmann - Binary data with NAV Web Service
Would this function in CU1297 ever be made external?
Thanks!
In the current NAV 2018 on-premises we make use of SQL Command to produce high performing queries and more flexible queries than the current NAV Table and Query objects allow us.
Typical TSQL commands we use are
If we want the current functionality written 100% using C/AL code, we have super bad performance, because it will end up in more and more sub queries and nested loops.
I wrote a library in C/AL to create QR Codes. I can create the Datamatrix without use of any DotNet Libraries. But in order to make an image out of this I need the System.Drawing Dll or any other library that allows it to draw within a Stream.
I'd be happy if you consider to include this.
Thanks
Tobias
CodeUnit 3031 "DotNet_SmtpMessage" overwrites the internal property FromAddress with the function SetFromName.
[External]
PROCEDURE SetFromName@3(FromName@1000 : Text);
BEGIN
DotNetSmtpMessage.FromAddress := FromName;
END;
The Zip Stream Wrapper Codeunit should be extended with a Encoding Parameter.
If the Zip content includes file names with special characters then you cant store the file name correctly.
To be able to use e specific codepage the OpenZipFromStream Function could look something like that:
variable gSystemTextEncoding = System.Text.Encoding.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
Code:
OpenZipFromStream(pInputStream : InStream;pZipArchiveModeIsUpdate : Boolean;pCodePageNumber : Integer)
CLEAR(gZipTempBlob);
gZipTempBlob.Blob.CREATEOUTSTREAM(OutputStream);
COPYSTREAM(OutputStream,pInputStream);
IF pZipArchiveModeIsUpdate THEN
gZipArchive := gZipArchive.ZipArchive(OutputStream,gZipArchiveMode.Update,FALSE,gSystemTextEncoding.GetEncoding(pCodePageNumber))
ELSE
gZipArchive := gZipArchive.ZipArchive(OutputStream,gZipArchiveMode.Read,FALSE,gSystemTextEncoding.GetEncoding(pCodePageNumber));
For some resons I need the functionallity of XmlDictionaryReader.CreateMtomReader to decompress a response stream from a http-call.
The C/Side method could look like this:
[External] DecompressStreamToXmlStream(VAR CompressedStream : InStream;VAR XmlStream : InStream;ContentType : Text)
GZipStream := GZipStream.GZipStream(CompressedStream, CompressionMode.Decompress);
DotNetArray := DotNetArray.CreateInstance(GETDOTNETTYPE(TextEncoding),1);
DotNetArray.SetValue(TextEncoding.UTF8,0);
XmlDictionaryReader := XmlDictionaryReader.CreateMtomReader(GZipStream,DotNetArray, ContentType, XmlDictionaryReaderQuotas.Max);
XmlDictionaryReader.MoveToContent();
XmlDocument := XmlDocument.XmlDocument();
XmlDocument.PreserveWhitespace := TRUE;
XmlDocument.Load(XmlDictionaryReader);
MemoryStream := MemoryStream.MemoryStream;
XmlDocument.Save(MemoryStream);
MemoryStream.Position := 0;
XmlStream := MemoryStream;
The Microsoft/AL method could be:
local procedure ReadContent(var Response: HttpResponseMessage; var Xml: XmlDocument);
var ContentType: Text;
CU: Codeunit "Stream Management";
HttpStream: InStream;
XmlStream: InStream;
begin
Response.Content.ReadAs(HttpStream);
ContentType := '...';
CU.DecompressStreamToXmlStream(HttpStream, XmlStream, ContentType);
XmlDocument.ReadFrom(XmlStream, Xml);
end;
@JesperSchulz, do you have some recommendations for my questions:
Describe the bug
Hello,
I use the function FromBase64 of the codeunit "Base64 Convert". The following string is my Base64String
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyIgPz4NCjxSZXplcHR1cmF1c3dlcnR1bmcgRXJzdGVsbHQ9IjIwLjAxLjIwMjAgMDk6NDE6MDYiPg0KDQogIDxNYXROcj5QQi1EV0VfRkVfMTAxODwvTWF0TnI+DQoNCiAgPFByb2R1a3RiZXplaWNobnVuZz5GZXJ0aWdlcnpldWduaXM8L1Byb2R1a3RiZXplaWNobnVuZz4NCg0KICA8SW5oYWx0c3N0b2ZmZT4NCiAgICA8SW5oYWx0c3N0b2ZmX0RhdGVuPg0KICAgICAgPFN0b2ZmbnVtbWVyPjwvU3RvZmZudW1tZXI+DQogICAgICA8Q0FTTnI+PC9DQVNOcj4NCiAgICAgIDxFR05yPjwvRUdOcj4NCiAgICAgIDxTdG9mZm5hbWU+PC9TdG9mZm5hbWU+DQogICAgICA8QW50ZWlsPjAuMDAwMDAwDQogICAgICAgIDwhLS1bJV0tLT4NCiAgICAgIDwvQW50ZWlsPg0KICAgICAgPFdHSz48L1dHSz4NCiAgICAgIDxEYW1wZmRydWNrPg0KICAgICAgICA8IS0tW2hQYV0tLT4NCiAgICAgIDwvRGFtcGZkcnVjaz4NCiAgICAgIDxFVVZPQz4/PC9FVVZPQz4NCiAgICAgIDxDSFZPQz5OZWluPC9DSFZPQz4NCiAgICAgIDxSb2hzdG9mZj4NCiAgICAgICAgPFJvaHN0b2ZmbnVtbWVyPjwvUm9oc3RvZmZudW1tZXI+DQogICAgICAgIDxSb2hzdG9mZmFudGVpbD4wLjAwMDAwMA0KICAgICAgICAgIDwhLS1bJV0tLT4NCiAgICAgICAgPC9Sb2hzdG9mZmFudGVpbD4NCiAgICAgIDwvUm9oc3RvZmY+DQogICAgPC9JbmhhbHRzc3RvZmZfRGF0ZW4+DQogICAgPEFudGVpbGVfR2VmYWVocmR1bmc+DQogICAgICA8V0dLMT4wLjAwMDAwMDwvV0dLMT4NCiAgICAgIDxXR0syPjAuMDAwMDAwPC9XR0syPg0KICAgICAgPFdHSzM+MC4wMDAwMDA8L1dHSzM+DQogICAgICA8RVVWT0M+MC4wMDAwMDA8L0VVVk9DPg0KICAgICAgPENIVk9DPjAuMDAwMDAwPC9DSFZPQz4NCiAgICA8L0FudGVpbGVfR2VmYWVocmR1bmc+DQogIDwvSW5oYWx0c3N0b2ZmZT4NCg0KICA8R2VmYWhyc3RvZmZlPg0KICAgIDxHZWZhaHJzdG9mZi1EYXRlbj4NCiAgICAgIDxTdG9mZm51bW1lcj48L1N0b2ZmbnVtbWVyPg0KICAgICAgPENBU05yPjwvQ0FTTnI+DQogICAgICA8RUdOcj48L0VHTnI+DQogICAgICA8U3RvZmZuYW1lPjwvU3RvZmZuYW1lPg0KICAgICAgPEFudGVpbD4wLjAwMDAwMA0KICAgICAgICA8IS0tWyVdLS0+DQogICAgICA8L0FudGVpbD4NCiAgICAgIDxSU2FldHplPjwvUlNhZXR6ZT4NCiAgICAgIDxILUVVSFNhZXR6ZT48L0gtRVVIU2FldHplPg0KICAgIDwvR2VmYWhyc3RvZmYtRGF0ZW4+DQogIDwvR2VmYWhyc3RvZmZlPg0KDQo8L1JlemVwdHVyYXVzd2VydHVuZz4NCg==
the expectet result is a XML file. But the function createt a xml file with a part of the Base64String behinde it. Here is the xml file, and the file should end with .
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<Rezepturauswertung Erstellt="20.01.2020 10:32:12">
<MatNr>PB-DWE_FE_1018</MatNr>
<Produktbezeichnung>Fertigerzeugnis</Produktbezeichnung>
<Inhaltsstoffe>
<Inhaltsstoff_Daten>
<Stoffnummer></Stoffnummer>
<CASNr></CASNr>
<EGNr></EGNr>
<Stoffname></Stoffname>
<Anteil>0.000000
<!--[%]-->
</Anteil>
<WGK></WGK>
<Dampfdruck>
<!--[hPa]-->
</Dampfdruck>
<EUVOC>?</EUVOC>
<CHVOC>Nein</CHVOC>
<Rohstoff>
<Rohstoffnummer></Rohstoffnummer>
<Rohstoffanteil>0.000000
<!--[%]-->
</Rohstoffanteil>
</Rohstoff>
</Inhaltsstoff_Daten>
<Anteile_Gefaehrdung>
<WGK1>0.000000</WGK1>
<WGK2>0.000000</WGK2>
<WGK3>0.000000</WGK3>
<EUVOC>0.000000</EUVOC>
<CHVOC>0.000000</CHVOC>
</Anteile_Gefaehrdung>
</Inhaltsstoffe>
<Gefahrstoffe>
<Gefahrstoff-Daten>
<Stoffnummer></Stoffnummer>
<CASNr></CASNr>
<EGNr></EGNr>
<Stoffname></Stoffname>
<Anteil>0.000000
<!--[%]-->
</Anteil>
<RSaetze></RSaetze>
<H-EUHSaetze></H-EUHSaetze>
</Gefahrstoff-Daten>
</Gefahrstoffe>
</Rezepturauswertung>
g0KICAgIDxHZWZhaHJzdG9mZi1EYXRlbj4NCiAgICAgIDxTdG9mZm51bW1lcj48L1N0b2ZmbnVtbWVyPg0KICAgICAgPENBU05yPjwvQ0FTTnI+DQogICAgICA8RUdOcj48L0VHTnI+DQogICAgICA8U3RvZmZuYW1lPjwvU3RvZmZuYW1lPg0KICAgICAgPEFudGVpbD4wLjAwMDAwMA0KICAgICAgICA8IS0tWyVdLS0+DQogICAgICA8L0FudGVpbD4NCiAgICAgIDxSU2FldHplPjwvUlNhZXR6ZT4NCiAgICAgIDxILUVVSFNhZXR6ZT48L0gtRVVIU2FldHplPg0KICAgIDwvR2VmYWhyc3RvZmYtRGF0ZW4+DQogIDwvR2VmYWhyc3RvZmZlPg0KDQo8L1JlemVwdHVyYXVzd2VydHVuZz4NCg==
5. Versions:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.