Skip to main content

Notifications

Announcements

No record found.

Microsoft Dynamics AX forum
Answered

Can't get .Net (Http)WebRequest ResponseStream

Posted on by 20

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

  • erpdell Profile Picture
    erpdell 20 on at
    RE: Can't get .Net (Http)WebRequest ResponseStream

    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());
        }
    }

  • Verified answer
    ergun sahin Profile Picture
    ergun sahin 8,812 Super User on at
    RE: Can't get .Net (Http)WebRequest ResponseStream

    Use SecurityProtocolType (before request)

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

  • erpdell Profile Picture
    erpdell 20 on at
    RE: Can't get .Net (Http)WebRequest ResponseStream

    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

  • ergun sahin Profile Picture
    ergun sahin 8,812 Super User on at
    RE: Can't get .Net (Http)WebRequest ResponseStream

    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)

  • Martin Dráb Profile Picture
    Martin Dráb 225,588 Super User on at
    RE: Can't get .Net (Http)WebRequest ResponseStream

    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.

  • erpdell Profile Picture
    erpdell 20 on at
    RE: Can't get .Net (Http)WebRequest ResponseStream

    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?

  • Verified answer
    Martin Dráb Profile Picture
    Martin Dráb 225,588 Super User on at
    RE: [X++] Can't get .Net (Http)WebRequest ResponseStream

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

Helpful resources

Quick Links

Replay now available! Dynamics 365 Community Call (CRM Edition)

Catch up on the first D365 Community Call held on 7/10

Community Spotlight of the Month

Kudos to Saurav Dhyani!

Congratulations to the June Top 10 community leaders!

These stars go above and beyond . . .

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 287,986 Super User

#2
Martin Dráb Profile Picture

Martin Dráb 225,588 Super User

#3
nmaenpaa Profile Picture

nmaenpaa 101,148

Leaderboard

Featured topics

Product updates

Dynamics 365 release plans