Hello,
I am trying to do a Proof of concept call of RESTful API on our customer DEV server (AX 2012 R3).
Following this suggestion I created a managed DLL to call the web service. I based it on this tutorial, calling a public RESTful API (due to environment I am limited to .Net Framework 4.5)
using System; using System.Collections.Generic; using System.Net; using System.IO; using System.Runtime.Serialization; namespace ConsumeRestApiTest { public class TestWebAPI { public static String request() { ServicePointManager.Expect100Continue = true; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri("https://api.github.com/repos/restsharp/restsharp/releases")); request.Method = "GET"; request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"; request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip; var content = string.Empty; using (var response = (HttpWebResponse)request.GetResponse()) { using (var stream = response.GetResponseStream()) { using (var sr = new StreamReader(stream)) { content = sr.ReadToEnd(); } } } return content; } } }
Now, directly on the server where environment is located, when I call the code, everything works fine, API is called and response is returned. Just for the sake of completeness, here is the code calling .Net DLL from C#.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace TestSuite { class Program { static void Main(string[] args) { String str = ConsumeRestApiTest.SPLTestWebAPI.request(); Console.WriteLine(str); } }
However, when I try to add this DLL to AX and call
request()method I am getting a following error (innermost Exception I was able to dig up):
System.IO.IOException: Authentication failed because the remote party has closed the transport stream.
at System.Net.Security.SslState.StartReadFrame(Byte[ buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[ buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[ incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[ buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.TlsStream.CallProcessAuthentication(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)
at System.Net.TlsStream.Write(Byte[ buffer, Int32 offset, Int32 size)
at System.Net.PooledStream.Write(Byte[ buffer, Int32 offset, Int32 size)
at System.Net.ConnectStream.WriteHeaders(Boolean async)
Here is code calling the DLL:
static void testRestfulApi(Args _args) { CodeAccessPermission permission; System.Collections.IEnumerable ienumerable; ConsumeRestApiTest.SPLTestWebAPI test; System.Exception ex; str rslt; ; permission = new InteropPermission(InteropKind::CLRInterop); permission.assert(); try { rslt = ConsumeRestApiTest.SPLTestWebAPI::request(); } catch(Exception::CLRError) { ex = ClrInterop::getLastException(); if (ex != null) { ex = ex.get_InnerException(); if (ex != null) { error(ex.ToString()); } } } info(rslt); }
From my web search, most suggestions were about TLS/SSL issues, but since my encryption and networking knowledge is limited I cannot say if this is something AX is doing (perhaps I am missing some setup) or if this is something in AX-OS interaction or anything else.
Anyone have any suggestions?