web
You’re offline. This is a read only version of the page.
close
Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Finance | Project Operations, Human Resources, ...
Answered

Can't get .Net (Http)WebRequest ResponseStream

(1) ShareShare
ReportReport
Posted on by 48

Hello,

I am trying to make some test web requests out of AX 2012 to an open API, as we need to implement parcel carrier API into our system in near future.

As we don't have experience with C# I've only tested this using .Net Framwork directly from X code.

Unfortunately, the HttpWebRequest.GetResponseStream() method doesn't seem to do or return anything. When I debug my class, the programm just stops after executing that method. I've also tried using the WebRequest class, however I get the same result. For better understanding, see my code here:

//Test class for calling an API and printing response
public class IMP_CallRESTfulWebService
{
    System.Net.HttpWebRequest       webReq;
    System.Net.HttpWebResponse      webRes;
    CLRObject                       clrObj;
    System.IO.Stream                stream;
    System.IO.StreamReader          streamReader;
    System.IO.StreamWriter          streamWrite;
}

public void run()
{
    //Give permission to run unmanaged and managed code
    new InteropPermission(InteropKind::ClrInterop).assert();
    
    //Create web request instance
    clrObj = System.Net.WebRequest::Create("https://petstore.swagger.io/v2/pet/09021999");
    webReq = clrObj;

    //Set web request properties
    webReq.set_Method("GET");
    webReq.set_ContentType("application/x-www-form-urlencoded");
    webReq.set_Timeout(10000); //in Miliseconds

    //Get the response object
    webRes = webReq.GetResponse();

    //Print status of response
    info(strFmt("%1",webRes.get_StatusCode()));
    info(strFmt("%1",webRes.get_StatusDescription()));

    //Get content returned by the servers as stream and open that stream using StreamReader for easy access
    streamReader = new System.IO.StreamReader(webRes.GetResponseStream());

    //The read & print the stream content
    info(streamReader.ReadToEnd());

    //Cleanup the streams, response and revert permission assert
    streamReader.Close();
    stream.Close();
    webRes.Close();
    CodeAccessPermission::revertAssert();
}

main() method just runs the class.

Has anyone experienced similar issues? What could be the problem? Also, is there a way to debug the .Net Framwork method?

And finally, as we are completly new to implementing API's into AX:
Is there maybe a better way to implement an API in AX 2012 R3? The API we are going to implement in the future can either use SOAP or REST and will use XML to send and consume data.

Looking forward to hear any advice,

kind regards

I have the same question (0)
  • Verified answer
    Martin Dráb Profile Picture
    237,795 Most Valuable Professional on at

    The program "stops" because it throws a managed exception, which you don't catch. We can just guess what exception it is, therefore let's change your code to handle it better.

    public void run()
    {
        try
    	{	
    		...
    	}
    	catch (Exception::CLRError)
    	{
    		throw error(AifUtil::getClrErrorMessage()));
    	}
    }

    I also see an obvious bug - you're calling stream.Close(), but you've never put anything to stream variable, therefore you would get NullReferenceException (if your code didn't fail earlier).

  • CU28041408-0 Profile Picture
    48 on at

    Hi Martin, thanks for your fast answer.

    I didn't know you could catch exceptions thrown from CLR, thanks. It's my first time using CLRObject in x++.

    Also your're right about the stream.Close() line, I forgot to remove it when I was refactoring my code. Fortunately it didn't affect code to this point.

    The error message on CLR level isn't thrown in English, therefore I translated it:

    The underlying connection has been closed: Unexpected error while sending... No data can be read from the transmission connection: An existing connection was closed by the remote host. An existing connection was closed by the remote host

    This seems to be some security problem...any Idea on that?

  • Martin Dráb Profile Picture
    237,795 Most Valuable Professional on at

    I would think that the Content-Type should be text/xml, but anyway, you code seems to work for me. I don't have any AX 2012 environment, but I tried it in a simple console application written in C#:

    using System;
    using System.Net;
    using System.IO;
    
    class Program
    {
        static void Main(string[] args)
        {
            WebRequest webReq = (HttpWebRequest)WebRequest.Create("https://petstore.swagger.io/v2/pet/09021999");
            webReq.Method = "GET";
            webReq.ContentType = "application/x-www-form-urlencoded";
            webReq.Timeout = 10000;
    
            HttpWebResponse webRes = (HttpWebResponse)webReq.GetResponse();
            Console.WriteLine(webRes.StatusCode);
            Console.WriteLine(webRes.StatusDescription);
    
            using (StreamReader sr = new System.IO.StreamReader(webRes.GetResponseStream()))
            {
                Console.WriteLine(sr.ReadToEnd());
            }
    
            Console.ReadLine();
        }
    }

    Note that it doesn't sounds like a security issue. It looks more like an invalid request, but as I said, it does work for me.

  • ergun sahin Profile Picture
    8,826 Moderator on at

    It could be TLS problem or You are sending malformed data to the application (may be you are sending an HTTPS request to an HTTP server or vice versa)

  • CU28041408-0 Profile Picture
    48 on at

    Hi Ergün,

    thanks for your reply. I've come to the same conclusion. Unfortunately it doesn't seem to be as easy as wrong protocol type, as web request class should be able to handle both (correct me if im wrong?).

    From what I've found online, it might be that our Windows Server (where AX is running on) uses an outdated TLS version as standard, which isn't supported by the API adress anymore. I am not familiar with differnet TLS versions an settings in windows server, but I'll try to get to it and keep this thread updated.

    Feel free to make further suggestions

  • Verified answer
    ergun sahin Profile Picture
    8,826 Moderator on at

    Use SecurityProtocolType (before request)

    System.Net.ServicePointManager::set_SecurityProtocol(System.Net.SecurityProtocolType::Tls12);//SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

  • CU28041408-0 Profile Picture
    48 on at

    Thanks. I found similar code for C# but I probably missed something when converting to x , therefore it wasn't working...

    With TLS set to 1.2 most of my code is working now, thanks a lot! I can't print the repsonse status code & description, somehow but I'll find a way to get it working.

    This is the complete code:

    public void run()
    {
        try
        {
            System.Net.ServicePointManager::set_SecurityProtocol(System.Net.SecurityProtocolType::Tls12);//SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
             //Give permission to run unmanaged and managed code
            new InteropPermission(InteropKind::ClrInterop).assert();
    
            //Create web request instance
            clrObj = System.Net.WebRequest::Create("https://petstore.swagger.io/v2/pet/09021999");
            webReq = clrObj;
    
            //Set web request properties
            webReq.set_Method("GET");
            webReq.set_ContentType("text/xml");
            webReq.set_Timeout(10000); //in Miliseconds
    
            //Get the response object
            webRes = webReq.GetResponse();
    
            //Print status of response
            if(webRes)
            {
                //info(strFmt("%1",webRes.get_StatusCode()));
                //info(strFmt("%1",webRes.get_StatusDescription()));
            }
    
            //Get content returned by the servers as stream and open that stream using StreamReader for easy access
            streamReader = new System.IO.StreamReader(webRes.GetResponseStream());
    
            //The read & print the stream content
            info(streamReader.ReadToEnd());
    
            //Cleanup the streams, response and revert permission assert
            streamReader.Close();
            webRes.Close();
            CodeAccessPermission::revertAssert();
        }
        catch (Exception::CLRError)
        {
            throw error(AifUtil::getClrErrorMessage());
        }
    }

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Neeraj Kumar – Community Spotlight

We are honored to recognize Neeraj Kumar as our Community Spotlight honoree for…

Leaderboard > Finance | Project Operations, Human Resources, AX, GP, SL

#1
Martin Dráb Profile Picture

Martin Dráb 660 Most Valuable Professional

#2
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 549 Super User 2025 Season 2

#3
Sohaib Cheema Profile Picture

Sohaib Cheema 307 User Group Leader

Last 30 days Overall leaderboard

Product updates

Dynamics 365 release plans