I created a restlet and I need to call it from .Ne...
# suitescript
s
I created a restlet and I need to call it from .Net. I went through all the steps in Netsuite, now I'm in .Net. I'm following all instructions in SuiteAnswers 24417 but it's not very obvious. Anyone has an example ?
a
Here is a project in C# that does it.
OauthBase.cs does the heavy lifting and Program.cs makes the request.
Be advised that I am not a C# developer and this project was cobbled together with a lot of beer involved.
s
Sounds good to me. Thank you very much
d
restsharp, dot net fiddle (not mine) ... https://dotnetfiddle.net/4eYdwt
s
I'd like to test it with Javascript, not Netsuite, is it possible to write an example of jsfiddle ?
s
TBH, any authorization testing should be done against NetSuite, as it has a pretty specific implementation of OAuth 1.0 (requiring HMAC-SHA256 and the Realm must be set). It will be hard to replicate NetSuite's behavior in pure JavaScript. I believe their Restlet engine uses Oracle WebLogic to handle the external call, then somehow load the Restlet script and pass the payload or query parameters in to the Restlet's endpoint function. I use a very simple echo Restlet or a Restlet that returns a static JSON object, for testing any new integration and authorization. Helps rule out any script issues and lets' you focus on getting the authorization correct.
s
I agree. I'm using IONIC to create an app. I need to call the restlet from IONIC, I thought that it would be the same as .Net or Javascript. I'm looking at Alan's solution
b
i doubt netsuite uses Oracle WebLogic, it predates it
suitescript 1 suitelets were based on java servets
s
Well, the previous developer used .Net to call Restlet but he left... with the sources...
b
restlets based on suitelets, so id guess its servlets
d
Here is how to do it line by line in powershell with .net namespaces. You should be able to port this assuming there are supporting libs. IMPORTANT - It has to be exact, one character out of place or in the wrong case will make it fail.
cls
Add-Type -AssemblyName System.Web
## USER SETTINGS START ##############################################################################################
$nsUrlInstanceName = "" #example: 12345-SB1
$nsRealm = "" #example: 12345_SB1
$nsDeployId = "" #example: 1
$nsScriptId = "" #example: 123
$oauth_consumer_key = ""
$oauth_consumer_secret = ""
$oauth_token = ""
$oauth_token_secret = ""
## USER SETTINGS END ##############################################################################################
function EncodeToUpper
{
param($value)
return $value.Replace("%2a","%2A").Replace("%2b","%2B").Replace("%2c","%2C").Replace("%2d","%2D").Replace("%2e","%2E").Replace("%2f","%2F").Replace("%3a","%3A").Replace("%3b","%3B").Replace("%3c","%3C").Replace("%3d","%3D").Replace("%3e","%3E").Replace("%3f","%3F")
}
$oauth_nonce = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes([System.DateTime]::Now.Ticks.ToString()))
$oauth_timestamp = [long](([datetime]::UtcNow)-(Get-Date "1970-01-01")).TotalSeconds
$baseUrl = 'https://'+$nsUrlInstanceName+'.<http://restlets.api.netsuite.com/app/site/hosting/restlet.nl|restlets.api.netsuite.com/app/site/hosting/restlet.nl>'
$fullUrl = $baseUrl + '?script='+$nsScriptId+'&deploy='+$nsDeployId
$baseUrlEncoded = [System.Web.HttpUtility]::UrlEncode($baseUrl)
$baseUrlEncoded = EncodeToUpper $baseUrlEncoded
#sort param names lexicographically
$params = "deploy=$nsDeployId&oauth_consumer_key=$oauth_consumer_key&oauth_nonce=$oauth_nonce&oauth_signature_method=HMAC-SHA256&oauth_timestamp=$oauth_timestamp&oauth_token=$oauth_token&oauth_version=1.0&script=$nsScriptId"
$paramsEncoded = [System.Web.HttpUtility]::UrlEncode($params)
$paramsEncoded = EncodeToUpper $paramsEncoded
$message = 'GET&'+$baseUrlEncoded+'&'+$paramsEncoded
$key = $oauth_consumer_secret + "&" + $oauth_token_secret
$hmac = New-Object System.Security.Cryptography.HMACSHA256
$hmac.Key = [System.Text.Encoding]::ASCII.GetBytes($key)
$signature = [System.Convert]::ToBase64String($hmac.ComputeHash([System.Text.Encoding]::ASCII.GetBytes($message)))
$signature = [System.Web.HttpUtility]::UrlEncode($signature)
$signature = EncodeToUpper $signature
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Content-Type", "application/json")
$headers.Add("Authorization", 'OAuth realm="'+$nsRealm+'", oauth_consumer_key="'+$oauth_consumer_key+'", oauth_token="'+$oauth_token+'", oauth_signature_method="HMAC-SHA256", oauth_timestamp="'+$oauth_timestamp+'", oauth_nonce="'+$oauth_nonce+'", oauth_version="1.0", oauth_signature="'+$signature+'"')
$response = Invoke-RestMethod $fullUrl -Method 'GET' -Headers $headers
$response | ConvertTo-Json
s
Excellent. I will "learn" it
s
@battk I am basing that assumption on the specific https headers we get back in response to Reslet calls. I can't remember which, but one of them seems strange, and when I looked it up it was specific to WebLogic. That doesn't mean they always used it, it could be more recent. WebLogic supports servlets, so it might have been an easy migration. I worked at a PCB manufacturer once, moving their custom servlets to WebLogic. Only needed to change a few things (mostly minor tweaks to the Java Bean class definitions) to migrate them.
But, regardless of what Restlet engine they use, I'd still do authorization testing against NetSuite directly, as replicating their specific authorization rules is not worth the time, in my opinion.
s
We did all the authorizations / test in Netsuite and Postman and all is fine. but cannot reuse the "curl" generated from Postman into IONIC. Very strange
s
you'll never be able to re-use a restlet call, as the nonce must be unique each time (or at least can't be re-used within a certain timeframe, often 24 hours or a week for some services)
and since the nonce and timestamp affect the signature, you'll need to generate a new nonce, timestamp, and signature for every call.
s
I know. the nonce is easy to re-create, the hard part is the oauth_signature. I was hoping to find a simple solution somewhere
s
What I usually do is take known values (the same tokens, timestamp, nonce, and realm) that were used in an application that worked and made a successful call (such as Postman), and see if I can get my code to produce the same signature. If you can reliably do that a few time in a row, there is a good chance your signature generation is working correctly.
And, definitely use an OAuth library like RestSharp or similar if you can. Better to use someone else's extensively tested code than your own in this instance.
s
I will look at RestSharp. I want anything that simplify the process.
s
Here's a sample of some C# code for calling a restlet, using RestSharp: