RESTFul API help

Bigbacon

Fully [H]
Joined
Jul 12, 2007
Messages
21,249
I am trying to use Ocacle's Financial REST API and I'm having trouble making it work in C# in VS2019.

I can confirm the restful call works using Postman, so I know my credentials are fine but I must be missing something trying this with in code.

So URL is like so: http://MYCLOUDDOMAIN/fscmRestApi/resources/11.13.18.05/ledgerBalances?finder=AccountBalanceFinder;accountCombination=3312-155100-0000-0000-0000-00000,accountingPeriod=Feb-20,currency=USD,ledgerSetName=Ledger,mode=Detail&fields=LedgerName,PeriodName,Currency,DetailAccountCombination,Scenario,BeginningBalance,PeriodActivity,EndingBalance,AmountType,CurrencyType,ErrorDetail

So I stick that in postman, put in my credentials (basic auth) and it works find. In VS I've tried both the RestSharp way and basic HTTPRequest way as follows:

C#:
HttpWebRequest r = (HttpWebRequest)WebRequest.Create("/fscmRestApi/resources/11.13.18.05/ledgerBalances?finder=AccountBalanceFinder;accountCombination=3312-155100-0000-0000-0000-00000,accountingPeriod=Feb-20,currency=USD,ledgerSetName=Ledger US,mode=Detail&fields=LedgerName,PeriodName,Currency,DetailAccountCombination,Scenario,BeginningBalance,PeriodActivity,EndingBalance,AmountType,CurrencyType,ErrorDetail");

        r.Method = "GET";


        string auth = System.Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes("Username" + ":" + "Password"));

        r.Headers.Add("Authorization", "Basic" + " " + auth);

        r.ContentType = "application/vnd.oracle.adf.resourcecollection+json";


        using (HttpWebResponse resp = (HttpWebResponse)r.GetResponse())

        {

            int b = 0;

        }

RestSharp:


C#:
  var client = new RestClient("http://MYCLOUDDOMAIN/fscmRestApi/resources/11.13.18.05/ledgerBalances?finder=AccountBalanceFinder;accountCombination=3312-155100-0000-0000-0000-00000,accountingPeriod=Feb-20,currency=USD,ledgerSetName=Ledger US,mode=Detail&fields=LedgerName,PeriodName,Currency,DetailAccountCombination,Scenario,BeginningBalance,PeriodActivity,EndingBalance,AmountType,CurrencyType,ErrorDetail");

        client.Authenticator = new RestSharp.Authenticators.HttpBasicAuthenticator("UserName", "Password");


        //Tried authorization this way as well.

        //JObject AuthRequest = new JObject();

        //AuthRequest.Add("Username", "UserName");

        //AuthRequest.Add("Password", "Password");


        var request = new RestRequest();

        request.Method = Method.GET;

        request.RequestFormat = DataFormat.Json;

        //request.AddParameter("text/json", AuthRequest.ToString(), ParameterType.RequestBody);

        request.AddHeader("Content-Type", "application/vnd.oracle.adf.resourcecollection+json");

        request.AddHeader("REST-Framework-Version", "1");

        var response = client.Get(request);


No matter what I try I am always 401 not authorized. I suspect its some kind of header thing? I can't see the raw request header in postman

I am new to REST. I am used to using WSDLs soap services.
 
If you try and hit the API in a browser with your credentials does it pop back an auth token to use in the 'GET'?


In the APIs I typically hit the first is the 'POST' to an access token back, and then add that auth token to the request header for the 'GET'.
 
If you try and hit the API in a browser with your credentials does it pop back an auth token to use in the 'GET'?


In the APIs I typically hit the first is the 'POST' to an access token back, and then add that auth token to the request header for the 'GET'.

nothing in the Oracle docs seem to say you need to do that. Postman doesn't seem to do that either as far as I can tell. This is not tokenized authentication which I think is what you may be asking about.
 
nothing in the Oracle docs seem to say you need to do that. Postman doesn't seem to do that either as far as I can tell. This is not tokenized authentication which I think is what you may be asking about.
Tokenized auth is the way to go these days. So this type of auth is quite archaic by modern standards.

Your URI in the HttpWebRequest example is partial/relative and missing the base URL. Missing code?

That said, it's hard to tell from the code what's wrong without knowing the auth itself. Odds are that if you got it to work in Postman, then it's going to be some silly bug or overlooked step on the C# side.

I've never used either of those libraries in any of my C# apps that consume REST apis. I've always used System.Net.Http, specifically HttpClient or IHttpClientFactory.

Following your current auth strategy, I could do something like this:
Code:
httpClient.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue(
        "Basic", Convert.ToBase64String(
            System.Text.ASCIIEncoding.ASCII.GetBytes(
               $"{username}:{pwd}" ) ) );

Then again, it's possible this is a crap API that likes to return 401 Unauthorized as some catch-all error response.
 
Last edited:
Tokenized auth is the way to go these days. So this type of auth is quite archaic by modern standards.

Your URI in the HttpWebRequest example is partial/relative and missing the base URL. Missing code?

That said, it's hard to tell from the code what's wrong without knowing the auth itself. Odds are that if you got it to work in Postman, then it's going to be some silly bug or overlooked step on the C# side.

I've never used either of those libraries in any of my C# apps that consume REST apis. I've always used System.Net.Http, specifically HttpClient or IHttpClientFactory.

Following your current auth strategy, I could do something like this:
Code:
httpClient.DefaultRequestHeaders.Authorization =
    new AuthenticationHeaderValue(
        "Basic", Convert.ToBase64String(
            System.Text.ASCIIEncoding.ASCII.GetBytes(
               $"{username}:{pwd}" ) ) );

Then again, it's possible this is a crap API that likes to return 401 Unauthorized as some catch-all error response.

what do you mean the URL is partial/relative? I took out the domain aspect of the URL for security reasons (I guess), so yes the URL shown is bad but that isn't what I'm using in real life.

I'll look up the HttpClient option and see what happens. I sometimes hate being someone with a learning disability. I can read papers and book all day long and learn nothing but someone show me the basics it clicks and I can run with it and expand.

At this moment, I really like the 'old' SOAP way with WSDLs. VS just imports the WSDL, I write a few lines of code and I'm done.

EDIT:
Wow...OMG, I see what you mean about the relative path. Yes, in the post it is wrong, in my code it has the full URL. went crazy for a second thinking I did mess that up.
 
Last edited:
At this moment, I really like the 'old' SOAP way with WSDLs. VS just imports the WSDL, I write a few lines of code and I'm done.
REST using HTTP can be really easy though. You've just hit a small bump with the auth part. I think we've all run into that at one time or another. You'll get past that eventually.

To me, you've just kinda picked some lesser known solutions. Maybe a google search isn't turning up much because of that? You could also do this in Python or Javascript, and the procedure is still the same. The language of choice is typically irrelevant. REST over HTTP works with pretty much anything because HTTP has been around forever. So in addition to learning REST, you're learning HTTP too.

Once you get past this little bump, I think you'll see how easy all this can be.
 
Figured jt b out.

Postman worked fine with the url being http, c# would not. Switched it to https and boom...worked fine.
 
Don't set basic auth up yourself, use what's available.
Remove your line for adding the basic auth header and add this instead.

r.Credentials = new NetworkCredential("username", "password");
 
Back
Top