Browserstack restSharp cURL PUT request conversion - c#

I am trying to convert the following cURL command to C# using restSharp
so that I can mark my automated Browserstack tests passed or failed.
curl -u "user:password" -X PUT -H "Content-Type: application/json" -d "{\"status\":\"<new-status>\", \"reason\":\"<reason text>\"}" https://www.browserstack.com/automate/sessions/<session-id>.json
Please note I am very new to C# I have the following code that currently returns an empty json response, I know I am on the right path as changing the request method to POST returns details (as expected) for my session/test:
private string markTestPassedorFail(string sesID)
{
var Client = new RestClient();
var Request = new RestRequest();
string sResponse = "";
Client.BaseUrl = new Uri(CapConf.BROWSERSTACK_SESSIONS_URL);
Client.Authenticator = new HttpBasicAuthenticator(CapConf.BROWSERSTACK_USER_NAME, CapConf.BROWSERSTACK_KEY_PASS);
Request.Resource = sesID + ".json";
Request.Method = Method.PUT;
Request.AddHeader("Content-Type", "application/json");
Request.AddJsonBody("{\"status\":\"failed\", \"reason\":\"failed\"}");
try
{
IRestResponse response = Client.Execute(Request);
sResponse = response.Content;
}
catch (Exception ex)
{
Console.WriteLine("Error Marking Test Passed or Fail : \n" + ex.Message);
}
return sResponse;
}

Have you tried the sample code snippet shared in their documentation here - https://www.browserstack.com/automate/c-sharp
I just pulled up bits of the code snippet there and was able to setup a sample test run, fetch the session ID and later update the session status via REST API.
Sample test -
https://www.browserstack.com/automate/c-sharp#getting-started
Session ID -
https://www.browserstack.com/automate/c-sharp#session-id
Session status update via REST API -
https://www.browserstack.com/automate/c-sharp#rest-api
Refer to the following gist:
https://gist.github.com/ashwingonsalves/56d7724671054bf623081bdcb30d40b8

Related

RestSharp Post Json Object

I am trying to Post a simple Json object using RestSharp to add a new product. I'm getting an error response from the server
"{"status":400,"error":"There was a problem in the JSON you submitted: unexpected character (after ) at line 1, column 2 [parse.c:724] in '{'product':{'name':'Product name','opt1':'Colour'}}"}"
My code:
////
var json = "{\'product\':{\'name\':\'Product name\',\'opt1\':\'Colour\'}}";
IRestClient restClient = new RestClient();
IRestRequest request = new RestRequest()
{
Resource = "https://api.targetsite.com/products/"
};
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Accept", "application/xml");
request.AddHeader("authorization", "Bearer " + token);
request.RequestFormat = DataFormat.Json;
request.AddJsonBody(json);
IRestResponse response = restClient.Post(request);
////
I managed to achive the result I wanted using a curl statment but I would like to do it using RestSharp.
Curl statment -
curl -X POST -H "Content-type: application/json" -H "Authorization: Bearer <ACCESS_TOKEN>"
https://api.targetsite.com/products/ -d '{"product":{"name":"Product name","opt1":"Colour"}}'
This HttpClient call also works fine
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.targetsite.com/products/"))
{
request.Headers.TryAddWithoutValidation("Authorization", "Bearer <ACCESS_TOKEN>");
request.Content = new StringContent("{\"product\":{\"name\":\"Product name\",\"opt1\":\"Colour\"}}");
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
var response = await httpClient.SendAsync(request);
}
}
It looks like a limitation on the API you are calling.
When you send the json with curl, you're using different delimiters (" instead of ').
My guess is that the API you're calling doesn't properly deserialize the JSON when ' is used.
What you can try is replacing the escaped ' with " or replace this line in your code : request.AddJsonBody(json)
with
request.AddJsonBody(Newtonsoft.Json.JsonConvert.DeserializeObject(json)) provided that you have installed the newtonsoft package.

Upload image from mobile app to API with multipart/form-data

I have this API where I receive an image to save it in a storage server. I've been testing the functionality in postman and works perfectly fine. But when it comes to the mobile app it does not send the image.
here you can see the Postman POST request
the code for the xamarin app is the next
var content = new MultipartFormDataContent();
var stream = File.OpenRead(_mediaFile.Path);
var streamcontent = new StreamContent(stream);
content.Add(streamcontent, "picture");
var client = new HttpClient();
HttpResponseMessage response = await cliente.PostAsync($"http://localhost:200/api/.../picture", content);
string result = response.Content.ReadAsStringAsync().Result;
Response responseData = JsonConvert.DeserializeObject<Response>(result);
if (response.IsSuccessStatusCode)
{
await Application.Current.MainPage.DisplayAlert("Correcto", "Imagen subida Correctamentel!", "OK");
_mediaFile = null;
terminado.IsEnabled = true;
}
else
{
terminado.IsEnabled = true;
await Application.Current.MainPage.DisplayAlert("Error", "Opps algo ocuirrio mal!", "OK"); }
As you can see in the postman the key picture receives the image name. I tried it also with curl and it works:
curl -X POST "http://localhost:200/api/.../picture" -H "accept: application/json" -H "Content-Type: multipart/form-data" -F "picture=#version1.jpeg;type=image/jpeg"
I've managed it to work, but using RestSharp library instead of HttpClient:
var client = new RestClient("192.168.0.2"); //the ip of your REST API
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "multipart/form-data"); // I'm using multipart form data
request.AddHeader("Authorization", "Bearer eyJ0eXAiOiJKV1QiLC"); // using JWT for auth
request.AddFile("pictureField", "/path/to/file"); //the path depends on which device you're using
IRestResponse response = client.Execute(request);
Pretty much straigt forward and works perfectly fine. Also, the "pictureField" depends on the name of the field the API requires, and the path to file should not be hardcoded. It should be given depending on where in the device the choosen image is.

Converting JIRA API cURL to c# http request

I have a cURL with which I connect to Atlassian JIRA API and search an issue with JQL, filtering issues by project name and status.
This is the cURL command, which works pretty well:
curl -u JIRAUSER:JIRATOKEN -X POST --data '{ "jql": "project = \"QA\" AND status=\"To Do\" " }' -H "Content-Type: application/json" https://jiraserver.atlassian.net/rest/api/2/search
I'm trying to re-build it on c# with httpclient POST method. The code is given below:
static async System.Threading.Tasks.Task Main(string[] args)
{
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://jiraserver.atlassian.net/rest/api/2/search"))
{
var base64authorization = Convert.ToBase64String(Encoding.ASCII.GetBytes("JIRAUSER:JIRA TOKEN"));
request.Headers.TryAddWithoutValidation("Authorization", $"Basic {base64authorization}");
request.Content = new StringContent("{ \"jql\": \"project = \"QA\" AND status = \"To Do\" }");
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var response = await httpClient.SendAsync(request);
Console.WriteLine(response);
}
}
}
response returns the following error:
StatusCode: 400, ReasonPhrase: '', Version: 1.1, Content:
System.Net.Http.HttpConnectionResponseContent
And in System.Diagnostics.Debug.Write I get the following error:
error CS0428: Cannot convert method group 'Write' to non-delegate type
'object'. Did you intend to invoke the method?
Please give me some hint or I'm about to hang myself...
I'd suggest using JIRA SDK to interact with your JIRA instance -> https://bitbucket.org/farmas/atlassian.net-sdk/src/master/.
Basically, set of steps are
1) initiate jira client:
var jiraClient = Jira.CreateRestClient(<jiraURL>, <jiraUserName>, <jiraUserPwd>);
2) connect to jira, and pull based on search criteria:
var jql = "project = QA + " AND status in (To Do)";
IEnumerable<Atlassian.Jira.Issue> jiraIssues = AsyncTasker.GetIssuesFromJQL(jiraClient, jql, 999);
3) then, you can enumerate in the pulled issues
...
foreach(var issue in jiraIssues)
{
/*
... for example, some of the available attributes are:
issue.Key.Value
issue.Summary
issue.Description
issue.Updated
String.Format("{0}/browse/{1}", jiraURL.TrimEnd('/') , issue.Key.Value)
...
*/
}
on the side note, it's advisable not to use using(... = new HttpClient()){....}

Curl request written in C# doesn't work

I'm trying to write a specific curl request in C#, and I keep getting a 500 server error response from the server. This curl request essentially makes a post request to an API by the company Highwinds. This request sends json data, and sets the Auth Bearer token header.
This is the curl request that works fine (note that I've replaced my actual bearer token with {token} and my actual account id with {accountId} to obfuscate that info):
curl -H "Authorization: Bearer {token}" -H "Content-Type: application/json" -d "#data.json" "https://striketracker.highwinds.com/api/accounts/{accountId}/purge"
Here's the C# code that gives me a generic 500 server error from the Highwinds API (note that I've replaced my actual bearer token with {token}, my actual account id with {accountId}, and the url in the json string with {url}, in order to obfuscate that personal info):
var accountId = "{accountId}";
var purgeURI = string.Format("https://striketracker.highwinds.com/api/accounts/{0}/purge", {accountId});
var query =
#"{""list"": [{""url"": ""{url}"",""recursive"": true}]}";
var token = {token};
using (var httpClient = new HttpClient())
{
var url = new Uri(purgeURI);
using (var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, url))
{
httpRequestMessage.Headers.Add(System.Net.HttpRequestHeader.Authorization.ToString(),
string.Format("Bearer {0}", token));
httpRequestMessage.Content = new StringContent(query,
Encoding.UTF8,
"application/json");
await httpClient.SendAsync(httpRequestMessage).ContinueWith(task =>
{
var response = task.Result;
var blah = response.Content.ReadAsStringAsync().Result;
Console.WriteLine(response.Content.ReadAsStringAsync().Result);
});
}
}
Thanks!
*Update: The following line of code was added to remove the Expect header that HttpRequest adds to a request by default. After removing this header I was able to get Highwinds API to accept the request without bombing.
"request.ServicePoint.Expect100Continue = false;"
My best recommendation would be to proxy both requests through something like tcpmon http://archive.apache.org/dist/ws/tcpmon/1.0/ (Basically run the server and point to local host and have tcpmon redirect the request to striketracker.highwinds.com). Try it from curl and from your source and you should be able to see what's different between the requests.

RestSharp - value without a name

I am trying to add a watcher to a Jira issue, using the REST API, C# and the RestSharp library.
According to Jira's documentation, the name of the watcher to be added must be in the following format: "username" (just the value within double quotes, no name).
This is apparently not valid Json.
By following this answer, I was able to add a watcher to a Jira issue with Curl:
curl -i -u myusername:mypassword -H "Content-Type: application/json" -H "Accept: application/json" -X POST -d "\"myusername\"" http://my.jira.host/rest/api/2/issue/MYISSUEKEY-1/watchers
However, It doesn't work with RestSharp (Jira answers bad request). Here's my code so far:
private RestRequest CreateRequest(Method method, String path)
{
var request = new RestRequest { Method = method, Resource = path, RequestFormat = DataFormat.Json, };
request.AddHeader("Authorization", "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(String.Format("{0}:{1}", username, password))));
return request;
}
public void AddWatcher(string issueKey, string watcher)
{
try
{
var path = String.Format("issue/{0}/watchers", issueKey);
var request = CreateRequest(Method.POST, path);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Accept", "application/json");
request.AddBody(string.Format("\"{0}\"", watcher));
var response = client.Execute(request);
AssertStatus(response, HttpStatusCode.NoContent);
}
catch (Exception ex)
{
Trace.TraceError("AddWatcher(issue, watcher) error: {0}", ex);
throw new JiraClientException("Could not add watcher", ex);
}
}
I would like to know if it's possible to send that type of POST via RestSharp, even if it's not a name / value pair.
Thanks

Categories

Resources