0

Trying to use Oracle Warehouse Cloud REST API through ASP.net C#. API Documentation

When I make a call to the Rest Service to the Object Inquiry API, I'm getting 2 errors:

  • IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
  • SocketException: An existing connection was forcibly closed by the remote host

Oracle Support directed me to Doc ID 967964.1 in their Support Library, which states SendChunked = true; has resolved the error before, but I haven't had luck adding it, nor do I feel it's appropriate for GET REST calls.

Here was the code I started with:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(HTTPsURL);
request.Method = "GET";
request.PreAuthenticate = true;
request.Credentials = cred;
request.ContentType = "application/xml";

using (var response = (HttpWebResponse)request.GetResponse())
using (Stream stream = response.GetResponseStream())
using (var reader = new StreamReader(stream))
{
    var content = reader.ReadToEnd();
    return content;
}

I have been able to get a response back from SOAP UI and Postman. In Both cases I needed to set the Header Content-Type to "application/xml", and supply the authorization preemptively.

In SOAP UI my Request looks like this:

GET {My URL is HERE} HTTP/1.1
Accept-Encoding: gzip,deflate
Authorization: Basic { BASIC KEY }
Content-Type: application/xml
Host: ta3.wms.ocs.oraclecloud.com
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)

When I try watching my .Net code through Fiddler, I'm not seeing the Content-Type being passed from the .Net Application. Is there something I'm missing there? Or is it possible I do need to pass the call in chunks?

When SendChunked = true, I get the error: Content-Length or Chunked Encoding cannot be set for an operation that does not write data

When I try passing data, I get the Error: Cannot send a content-body with this verb-type

A few things I've tried:

  • Modifying AutomaticDecompression
  • Modifying the Security Protocol
  • Transfer Encoding gzip,deflate
  • Enable/Disable Auto Redirect
  • And several variations of: Accept, KeepAlive, UserAgent, CachePolicy, ProtocolVersion

Perhaps It's not possible with the HttpWebRequest. Is there a better method I should try employing?

My Final requirements are to get data back from this call, then kick off other .Net processes.

Joe
  • 2,500
  • 1
  • 14
  • 12
MrMatt
  • 175
  • 2
  • 12
  • What version of .Net are you using? – raterus Oct 19 '18 at 14:31
  • 4.5, but I've also tried it on 4.5.2 – MrMatt Oct 19 '18 at 14:38
  • 4.5.2 is the *earliest* supported version and shouldn't be used anyway since it's quite old. You had to explicitly enable TLS1.2 with `System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;` back then. Starting with 4.6 the OS's best supported option is used. *Supported* Windows OS versions work with TLS1.2 by default. You may need to change some registry settings for older versions – Panagiotis Kanavos Oct 19 '18 at 14:49
  • I had tried: ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; I tried resetting the project to 4.6.1, I'm getting a 403: Forbidden now in .Net. – MrMatt Oct 19 '18 at 14:50
  • @MrMatt, getting a 403 would indicate to me the issue asked in this question is resolved, and you need to fix your authentication – raterus Oct 19 '18 at 15:24
  • @raterus, I am willing to say it's resolved, but I'm using the same credentials that I'm using in Postman. Is there some other credential based setting I need to use? – MrMatt Oct 19 '18 at 15:32

1 Answers1

2

This sounds like a TLS 1.2 issue, especially since it works in Postman, but not in .Net. Older versions of .Net don't automatically use TLS 1.2 and try to authenticate using older protocols and promptly get rejected.

There are lots of fixes for this one, either registry on the server, or app specific, but you should understand what you are doing first so you don't shoot yourself in the foot. I suggest reading this article and trying some of the fixes.

Stack Overflow discussion

raterus
  • 1,980
  • 20
  • 23
  • Thanks, I upgraded to 4.6.1, and had 2 other things to fix. I had to Encode and Cache my user credentials into the request: string encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("UTF-8").GetBytes(UserName + ":" + Password)); request.Headers.Add("Authorization", "Basic " + encoded); System.Net.CredentialCache credentialCache = new System.Net.CredentialCache(); credentialCache.Add( new System.Uri(HTTPsURL), "Basic", new System.Net.NetworkCredential(UserName, Password) ); Setting to TLS 1.2 while on 4.5.1 failed, I had to update to 4.6.1 – MrMatt Oct 19 '18 at 15:43