wrong format of json string in an api call? - c#

I try to bring the pdf file into a standard software, wrote the code, an exception is issued because of wrong format with json although json string corresponds exactly to the specified json of api call of standard software. can you please take a look if I wrote something wrong here or if I forgot something?
I covered some information with a star
Many Thanks
IRestResponse response3;
client = new RestClient("http://***.***.***.*");
client.Authenticator = new HttpBasicAuthenticator("********", "*********");
client.Timeout = -1;
request = new RestRequest("/*****/api/******/*****/***", Method.POST);
request.AddHeader("content-type", "multipart/form-data");
request.AlwaysMultipartFormData = true;
request.AddParameter("Object", "{" +
"\"cabinet\":\"Posteingang\"," +
"\"name\":\"Posteingang\"," +
"\"objectTypeId\":\"2\"," +
"\"fields\":{" +
"\"Datum\":{\"value\":\"" + DateTime.Now.ToString("dd.MM.yyyy") + "\"}" +
"}" +
"}");
request.AddFile("file","C:/Users/*********/Documents/*********/Org.pdf","Org.pdf");
MultipartFormDataContent multipartForm = new MultipartFormDataContent();
byte[] file_bytes = File.ReadAllBytes("C:/Users/********/Documents/********/Org.pdf");
multipartForm.Add(new ByteArrayContent(file_bytes, 0, file_bytes.Length), "profile_pic", "hello1.jpg");
multipartForm.Add(new StringContent("Object"), "{" +
"\"cabinet\":\"Posteingang\"," +
"\"name\":\"Dokument\"," +
"\"objectTypeId\":\"******\"," +
"\"fields\":{" +
"\"Datum\":{\"MAIL_SUBMIT_TIME\":{\"value\":\"" + DateTime.Now.ToString("dd.MM.yyyy") + "\"},\"Typ\":" +
"{\"feld4\":{\"value\": \"Brief\"}},\"Absender\": {\"Mail_FROM\":{\"value\": \"*********\"}}}}}");
response3 = client.Execute(request);
Console.WriteLine(response3.Content);
}
}
}

Related

Empty value returned by RestSharp

The code block below returns me a emtpy value. But when I send a request on the postman side, the data reaches me without any problems. What do you think is the problem? Could you help? Thank you.
Code:
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var client = new RestClient("url");
client.Timeout = -1;
var request = new RestRequest(Method.GET);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Authorization", "Basic mytoken");
var body = #"{" + "\n" +
#" ""size"": 1," + "\n" +
#" ""page"": 1," + "\n" +
#" ""start_date"": ""2022-01-02""," + "\n" +
#" ""end_date"": ""2022-01-03""" + "\n" +
#"}";
request.AddParameter("application/json", body, ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
MessageBox.Show(response.Content);
REST Return Emtpy Value
Try using AddJsonBody(), Instead of AddParameter() with anonymous object
//Kindly check the type of start_date and end_date property.
var body = new { Size = 1, Page = 1, start_date="2022-01-02", end_date="2022-01-03"};
request.AddJsonBody(body);
From Documentation:
AddParameter("application/json", ..., ParameterType.RequestBody) won't work, use AddBody() instead, or better, AddJsonBody

How to generate signature for Oauth1.0 for here api c#

I want to send access token request for bearer token to here api.(https://developer.here.com/tutorials/how-to-authenticate-with-here-oauth/)
They showed example using node. But I tried the same way in c#. But I got 400 bad request. My code is as following:
var url = "https://account.api.here.com/oauth2/token";
String id = "key id";
String secret = "key secret";
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.Method = "POST";
var timeStamp = ((int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds).ToString();
var nonce = Convert.ToBase64String(Encoding.UTF8.GetBytes(timeStamp));
var signatureBaseString = Escape(httpWebRequest.Method.ToUpper()) + "&";
signatureBaseString += url.ToLower() + "&";
signatureBaseString +=
"oauth_consumer_key=" + id + "&" +
"oauth_nonce=" + nonce + "&" +
"oauth_signature_method=" + "HMAC-SHA1" + "&" +
"oauth_timestamp=" + timeStamp + "&" +
"oauth_version=" + "1.0";
var key = secret;
var signatureEncoding = new ASCIIEncoding();
var keyBytes = signatureEncoding.GetBytes(key);
var signatureBaseBytes = signatureEncoding.GetBytes(signatureBaseString);
string signatureString;
using (var hmacsha1 = new HMACSHA1(keyBytes))
{
var hashBytes = hmacsha1.ComputeHash(signatureBaseBytes);
signatureString = Convert.ToBase64String(hashBytes);
}
string SimpleQuote(string s) => '"' + s + '"';
var header =
"Content-Type=application/x-www-form-urlencoded" + "," +
"Authorization=OAuth" + "," +
"oauth_consumer_key=" + SimpleQuote(id) + "," +
"oauth_nonce=" + SimpleQuote(nonce) + "," +
"oauth_signature_method=" + SimpleQuote("HMAC-SHA1") + "," +
"oauth_timestamp=" + SimpleQuote(timeStamp) + "," +
"oauth_version=" + SimpleQuote("1.0") + "," +
"oauth_signature= " + SimpleQuote(signatureString);
httpWebRequest.Headers.Add(HttpRequestHeader.Authorization, header);
string postData = "grant_type=client_credentials";
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] byte1 = encoding.GetBytes(postData);
httpWebRequest.ContentLength = byte1.Length;
var newStream = httpWebRequest.GetRequestStream(); // get a ref to the request body so it can be modified
newStream.Write(byte1, 0, byte1.Length);
newStream.Close();
var response = httpWebRequest.GetResponse();
May be I am generating the signature in wrong way. But I only have key id and secret and I managed to implement this far. Please help me pointing the mistake I made.
Would you please have a look below article?
Getting (401) UnAuthorized error on some requests not all, but most
Try to use different lib such as HttpClient or RestClient.

How can I send or get a file through rest api

How can I move a file (for example: in pdf format) that is in a folder with me locally through an api call in a folder in a document management system?
This is a small cod section of the api call that takes over the task.
client = new RestClient("http://***.***.***.*");
client.Authenticator = new HttpBasicAuthenticator("******", "******");
client.Timeout = -1;
request = new RestRequest("/*****/api/*****/*****/371 ", Method.POST);
request.AddHeader("content-type", "multipart/form-data");
request.AlwaysMultipartFormData = true;
request.AddParameter("Object", "{" +
"\"****\":\"*****\"," +
"\"name\":\"*******\"," +
"\"******\":\"2\"," +
"\"fields\":{" +
"\"*******\":{\"value\":\"" + DateTime.Now.ToString("dd.MM.yyyy") + "\"}" +
"}" +
"}");
request.AddFile("File", "C:/Users/********/Documents/****/*****/pdf.pdf");
response = client.Execute(request);
Console.WriteLine(response.Content);
}
}
}
I would have to obscure a few places with stars
Thank You

Sending a JSON request to ebay API

Ok so I'm having a bit of trouble getting these JSON requests through to the Ebay API.
Here is the json request:
string jsonInventoryRequest = "{" +
"\"requests\": [";
int commaCount = 1;
foreach (var ep in productsToProcess)
{
jsonInventoryRequest += "{\"offers\": [{" +
"\"availableQuantity\":" + ep.EbayProductStockQuantity + "," +
"\"offerId\":\"" + ep.EbayID.ToString() + "\"," +
"\"price\": {" +
"\"currency\": \"AUD\"," +
"\"value\":\"" + ep.EbayProductPrice.ToString() + "\"" +
"}" +
"}],";
jsonInventoryRequest += "\"shipToLocationAvailability\": " + "{" +
"\"quantity\":" + ep.EbayProductStockQuantity +
"},";
jsonInventoryRequest += "\"sku\": " + ep.EbayProductSKU.ToString() + "}";
if (commaCount < productsToProcess.Count())
jsonInventoryRequest += ",";
commaCount++;
sendEbayApiRequest = true;
}
jsonInventoryRequest +=
"]" +
"}";
And the Debug.WriteLine() output of the above JSON request is :
json string = {"requests": [{"offers": [{"availableQuantity":0,"offerId":"098772298312","price": {"currency": "AUD","value":"148.39"}}],"shipToLocationAvailability": {"quantity":0},"sku": 135779},{"offers": [{"availableQuantity":1,"offerId":"044211823133","price": {"currency": "AUD","value":"148.39"}}],"shipToLocationAvailability": {"quantity":1},"sku": 133607}]}
Here is the code in C# to send the request:
var ebayAppIdSetting = _settingService.GetSettingByKey(
"ebaysetting.appid", "");
var ebayCertIdSetting = _settingService.GetSettingByKey(
"ebaysetting.certid", "");
var ebayRuNameSetting = _settingService.GetSettingByKey(
"ebaysetting.appid", "");
var stringToEncode = ebayAppIdSetting + ":" + ebayCertIdSetting;
HttpClient client = new HttpClient();
byte[] bytes = Encoding.UTF8.GetBytes(stringToEncode);
var base64string = "Basic " + System.Convert.ToBase64String(bytes);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Authorization", base64string);
var stringContent = "?grant_type=client_credentials&" + "redirect_uri=" + ebayRuNameSetting + "&scope=https://api.sandbox.ebay.com/oauth/api_scope";
var requestBody = new StringContent(stringContent.ToString(), Encoding.UTF8, "application/json");
requestBody.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
var response = client.PostAsync("https://api.sandbox.ebay.com/identity/v1/oauth2/token", requestBody);
The output I get when I do Debug.WriteLine("response.Content = " + response.Result); is:
response.Content = StatusCode: 401, ReasonPhrase: 'Unauthorized',
Version: 1.1, Content: System.Net.Http.StreamContent, Headers: {
RlogId:
t6ldssk%28ciudbq%60anng%7Fu2h%3F%3Cwk%7Difvqn*14%3F0513%29pqtfwpu%29pdhcaj%7E%29fgg%7E%606%28dlh-1613f3af633-0xbd
X-EBAY-C-REQUEST-ID: ri=HNOZE3cmCr94,rci=6kMHBw5dW0vMDp8A
X-EBAY-C-VERSION: 1.0.0 X-EBAY-REQUEST-ID:
1613f3af62e.a096c6b.25e7e.ffa2b377!/identity/v1/oauth2/!10.9.108.107!r1esbngcos[]!token.unknown_grant!10.9.107.168!r1oauth-envadvcdhidzs5k[]
Connection: keep-alive Date: Mon, 29 Jan 2018 00:04:44 GMT
Set-Cookie: ebay=%5Esbf%3D%23%5E;Domain=.ebay.com;Path=/
WWW-Authenticate: Basic Content-Length: 77 Content-Type:
application/json }
Can anyone see where I'm going wrong. Cheers
Ok so the authentication was failing because I was sending wrong authentication token. Needed to get oauth token from application tokens.
So instead of base64 encoding token like this:
var base64string = "Basic " + System.Convert.ToBase64String(bytes);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Authorization", base64string);
I needed to do the following:
url = "https://api.sandbox.ebay.com/sell/inventory/v1/bulk_update_price_quantity";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
//request.ContentType = "application/json; charset=utf-8";
request.Headers.Add("Authorization", "Bearer **OAUTH TOKEN GOES HERE WITHOUT ASTERIKS**");
// Send the request
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write(jsonInventoryRequest);
streamWriter.Flush();
streamWriter.Close();
}
// Get the response
HttpWebResponse response = (HttpWebResponse) request.GetResponse();
if (response != null)
{
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
// Parse the JSON response
var result = streamReader.ReadToEnd();
}
}

How to send ONVIF request to web camera with authorization, using SOAP action and HttpClient

I'm working on project for discovering and controlling web cameras in local network. I'm a C++ programmer, so I'm not good in .NET but this project we write on C# and I have some problems. I'm using DiscoveryClient for discovering all devices in local network. Next, I get camera address, creating HttpClient and trying to send SOAP action. ONVIF specifications: http://www.onvif.org/onvif/ver10/device/wsdl/devicemgmt.wsdl. Some actions (e.g. GetServiceCapabilities) returns responses, but most actions returnes this error:
<env:Body><env:Fault><env:Code><env:Value>env:Sender</env:Value>
<env:Subcode><env:Value>ter:NotAuthorized</env:Value>
</env:Subcode>
</env:Code>
<env:Reason><env:Text xml:lang="en">The action requested requires authorization and the sender is not authorized</env:Text>
</env:Reason>
</env:Fault>
</env:Body>
I'm creating SOAP request like in official ONVIF documentation (pages 35-36). http://www.onvif.org/Portals/0/documents/WhitePapers/ONVIF_WG-APG-Application_Programmer's_Guide.pdf. "admin" and "12345" - are login and password from our test web cam.
It's my code where I try to send request down below:
HttpClient httpClient = new HttpClient();
var byteArray = Encoding.UTF8.GetBytes("admin:12345");
var request = requestStructure.CreateSoapRequest();
httpClient.DefaultRequestHeaders.Add("SOAPACTION", "\"" + requestStructure.actionNamespace + "#" + requestStructure.actionName + "\"");
httpClient.DefaultRequestHeaders.Add("Authorization", "Digest " + Convert.ToBase64String(byteArray));
var resp = await httpClient.PostAsync(requestedUri, new StringContent(request, UnicodeEncoding.UTF8));
var respString = await resp.Content.ReadAsStringAsync();
It's my SOAP request that created and returned by CreateSoapRequest():
public string CreateSoapRequest()
{
var nonce64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(this.nonce.ToString()));
var date64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(this.dateCreated));
var password64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(this.password));
SHA1 sha = new SHA1CryptoServiceProvider();
var passwordDigest = sha.ComputeHash(Encoding.UTF8.GetBytes(nonce64 + date64 + password64));
password64 = Convert.ToBase64String(passwordDigest);
this.requestBodyString =
"<soap:Envelope "
+ "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" "
+ "soap:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
+ "<soap:Header>"
+ "<Security s:mustUnderstand=\"1\" xmlns:w=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\">"
+ "<UsernameToken>"
+ "<Username>" + this.login + "</Username>"
+ "<Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest\">" + password64 + "</Password>"
+ "<Nonce EncodingType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary\">" + nonce64 + "</Nonce>"
+ "<Created xmlns=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\">" + this.dateCreated + "</Created>"
+ "</UsernameToken>"
+ "</Security>"
+ "</soap:Header>"
+ "<soap:Body>"
+ "<u:" + this.actionName + " "
+ "xmlns:u=\"" + this.actionNamespace + "\">"
+ this.actionParameters
+ "</u:" + this.actionName + ">"
+ "</soap:Body>" +
"</soap:Envelope>\r\n\r\n";
return this.requestBodyString;
}
Thanks for any help!
I have been dealing with this for a long time and here is the function I used to get all the authentication stuff:
static void GetPasswordDigest()
{
//Get nonce
Random rnd = new Random();
Byte[] nonce_b = new Byte[16];
rnd.NextBytes(nonce_b);
nonce64 = Convert.ToBase64String(nonce_b);
Console.WriteLine("Nonce: " + nonce64);
//Get timestamp
DateTime created = DateTime.Now;
creationtime = created.ToString("yyyy-MM-ddTHH:mm:ssZ");
Byte[] creationtime_b = Encoding.ASCII.GetBytes(creationtime);
Console.WriteLine("Timestamp: " + creationtime);
//Convert the plain password to bytes
Byte[] password_b = Encoding.ASCII.GetBytes(ONVIFPassword);
//Concatenate nonce_b + creationtime_b + password_b
Byte[] concatenation_b = new byte[nonce_b.Length + creationtime_b.Length + password_b.Length];
System.Buffer.BlockCopy(nonce_b, 0, concatenation_b, 0, nonce_b.Length);
System.Buffer.BlockCopy(creationtime_b, 0, concatenation_b, nonce_b.Length, creationtime_b.Length);
System.Buffer.BlockCopy(password_b, 0, concatenation_b, nonce_b.Length + creationtime_b.Length, password_b.Length);
//Apply SHA1 on the concatenation
SHA1 sha = new SHA1CryptoServiceProvider();
Byte[] pdresult = sha.ComputeHash(concatenation_b);
passworddigest = Convert.ToBase64String(pdresult);
Console.WriteLine("Password digest: " + passworddigest);
}
I hope this hepls.
I've been doing a lot of Onvif stuff recently and found that setting up the security credentials is quite fiddly.
First I would say make sure your date format is like the following:
var now = DateTime.Now.ToUniversalTime().ToString("yyyy-MM-ddThh:mm:ss.fffZ");
The only other difference with mine ( which works fine) is that I have an extra line in the header:
string xml = string.Format(#"<?xml version='1.0' encoding='UTF-8'?>"+
"<s:Envelope xmlns:s='http://www.w3.org/2003/05/soap-envelope'>" +
"<s:Header>" +
"<Security s:mustUnderstand='1' xmlns='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd'>" +
"<UsernameToken>" +
"<Username>{0}</Username>" +
"<Password Type='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest'>" +
"{1}" +
"</Password>" +
"<Nonce EncodingType='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary'>" +
"{2}" +
"</Nonce>" +
"<Created xmlns='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd'>" +
"{3}" +
"</Created>" +
"</UsernameToken>" +
"</Security>" +
"</s:Header>", user, credentials[0], b64Nonce, credentials[2]);
Hope this helps!

Categories

Resources