I'm using the RestSharp API in a C# environment.
I've successfully built code that 1) returns a specific record, and 2) returns the most recent 50 records. As an example, the snippet below is the latter, which is working perfectly:
RestRequest request = new RestRequest();
request.Resource = "/sdpapi/request";
request.AddParameter("OPERATION_NAME", "GET_REQUESTS");
request.AddParameter("INPUT_DATA", #"<operation>
<details>
<from>0</from>
<limit>50</limit>
<filterby>All_Requests</filterby>
</details>
</operation>");
What I would like to do is update a single record on the server. The server's API says I must:
Provide a "request ID", to specify which record we'll be updating
Use an "operation name" of "EDIT_REQUEST"
Provide input data like so:
{
"operation": {
"details": {
"category": "hardware",
"subject": "test"
}
}
Attempt 1:
RestRequest request = new RestRequest();
request.Resource = "/sdpapi/request/{request_id}";
request.AddParameter("request_id", id, ParameterType.UrlSegment);
request.AddParameter("OPERATION_NAME", "EDIT_REQUEST");
request.AddParameter("INPUT_DATA", #"<operation>
<details>
<subject>test</subject>
<category>hardware</category>
</details>
</operation>");
Response comes back saying the connection was successful. Server shows a successful update attempt, however no changes are actually made. It's as if it hears my request, thinks I'm updating 0 variables.
Attempt 2:
Perhaps it is expecting the input data to be JSON.
RestRequest request = new RestRequest();
request.Resource = "/sdpapi/request/{request_id}";
request.AddParameter("request_id", id, ParameterType.UrlSegment);
request.AddParameter("OPERATION_NAME", "EDIT_REQUEST");
request.AddParameter("INPUT_DATA", #"{
""operation"": {
""details"": {
""category"": ""hardware"",
""subject"": ""test""
}
}");
This doesn't run. It comes back saying "Error when performing - EDIT_REQUEST - Content is not allowed in prolog."
Attempt 3:
I try adding the update parameters via the AddParameter() method.
RestRequest request = new RestRequest();
request.Resource = "/sdpapi/request/{request_id}";
request.AddParameter("request_id", id, ParameterType.UrlSegment);
request.AddParameter("OPERATION_NAME", "EDIT_REQUEST");
request.AddParameter("CATEGORY", "hardware");
request.AddParameter("SUBJECT", "test");
Returns the error "Error when parsing input XML elements - null - null".
Attempt 4:
A suggestion I saw online, to specify the content type and serialize my own JSON.
RestRequest request = new RestRequest();
request.AddHeader("Content-type", "application/json");
request.RequestFormat = DataFormat.Json;
request.AddBody(new { category = "hardware", subject = "test" });
request.Resource = "/sdpapi/request/{request_id}";
request.AddParameter("request_id", id, ParameterType.UrlSegment);
request.AddParameter("OPERATION_NAME", "EDIT_REQUEST");
Returns the error "Error when parsing input XML elements - null - null".
Attempt 5:
request.Method = Method.PATCH;
I've tried various combinations using Method.PATCH, however it returns the error "The server does not support the functionality needed to fulfill this request (Method PATCH is not implemented by this servlet for this URI)."
Attempt 6:
request.Resource = "/sdpapi/request/{request_id}/category/hardware";
I've tried a few combinations of different URLs, however it returns the error "Error when validating URL - Invalid URL for the requested operation." Also the in-browser example I have to work with doesn't need to use a fancy URL. While it was a good test, I get the feeling this isn't the right direction.
I feel like I'm really close... but after hours of research, I have failed to resolve the matter.
It seems this instance was a case of using the wrong format. See Caramiriel's comment above, as they deserve all the credit.
Related
I'm trying to do a POST request in C#, using RestSharp, in Visual Studio 2022.
I tested the API using Postman, which was successful. The API requires a 64-bit encoded Basic Auth (which I have), and a unique API key (which I also have). I then looked at the C# Restsharp code provided by Postman, and tried to copy paste it into my VS project, but most of the libraries were deprecated. I then ended up modifying the code so it didn't give me any errors, and the code itself runs, but getting a semantic error: the request returns "Missing or Malformed URL parameters". In the body parameter, I send one parameter in the form
var body = #"{""fieldNameHere"": intHere}";
My full code (redacted):
var options = new RestClientOptions("URLHERE")
{
Timeout = -1
};
var client = new RestClient(options);
var request = new RestRequest
{
Method = Method.Post
};
request.AddHeader("API_KEY", "keyHere");
request.AddHeader("Authorization", "authHere");
request.AddHeader("Content-Type", "application/json");
var body = #"{""fieldNameHere"": intHere}";
request.AddParameter("application/json; charset=utf-8", body, ParameterType.RequestBody);
request.RequestFormat = DataFormat.Json;
RestResponse response = await client.ExecuteAsync(request);
So I tried using a JObject for the parameter, got the same error, this is my code:
JObject jObjectBody = new JObject();
jObjectBody.Add("FieldName", intHere);
request.AddParameter("application/json", jObjectBody, ParameterType.RequestBody);
var clientValue = await client.ExecuteAsync(request);
I also tried using HttpWebRequest, but got an auth error so not sure what was going on there, didn't get that anywhere else. Would prefer to use RestClient anyway. This is the other way I tried to do the body parameter:
string postData = "{\"FieldNameHere\":" + intHere + "}";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
I haven't found anything that works yet. If someone can guide me towards a solution I'd be mad grateful, thanks. It definitely seems to be the body giving me the issue.
Ah! For some reason, phrasing my body like this worked:
var body = new { FieldNameHere = intHere }
request.AddJsonBody(body);
I have no idea why this worked, but it did!
A list of things that DID NOT work:
JObject technique
switching header placement
encoding the auth myself
how the RR instantiation is set up
with and without explicitly saying application/json (also including the charset and excluding)
using HttpWebRequest instead of RestSharp
My goal is to retrieve JSON data from "The virus tracker" API and parse it into a label. This is for my IB personal project so I just started learning c#. Fount this old code and tried fixing it, it worked with basic GET API's but it doesn't work with the one I'm using. (English not my main language)
POSTMAN RESPONSE
{
"results": [
{
"total_cases": 5954607,
"total_recovered": 2622507,
"total_unresolved": 2255875,
"total_deaths": 363208,
"total_new_cases_today": 53700,
"total_new_deaths_today": 1659,
"total_active_cases": 45257,
"total_serious_cases": 2698001,
"total_affected_countries": 213,
"source": {
"url": "https://thevirustracker.com/"
}
}
],
"stat": "ok"
}
C# CODE
//Creating Client connection
RestClient restClient = new RestClient("https://thevirustracker.com/free-api?global=stats");
//Creating request to get data from server
RestRequest restRequest = new RestRequest("total_cases", Method.GET);
// Executing request to server and checking server response to the it
IRestResponse restResponse = restClient.Execute(restRequest);
// Extracting output data from received response
string response = restResponse.Content;
// Parsing JSON content into element-node JObject
var jObject = JObject.Parse(restResponse.Content);
//Extracting Node element using Getvalue method
string cases = jObject.GetValue("total_cases").ToString();
label1.Text = (cases);
ERROR
An unhandled exception of type 'Newtonsoft.Json.JsonReaderException' occurred in Newtonsoft.Json.dll
Unexpected character encountered while parsing value: <. Path '', line 0, position 0.
My final goal with this code is that label1 says "5954607"
Remember that I'm really new to this so if you can explain the changes you made to the code ill really appreciate it.
You're not using RestRequest correctly or initialized the RestClient wrongly.
If that url you used in the RestClient is the whole url then you don't need a "resource" in the RestRequest.
Due to that mistake you got an HTML response indicated by the error
Unexpected character encountered while parsing value: <. Path '', line 0, position 0.
The value of restResponse.Content probably starts with <html and that is not valid JSON.
The Json payload is a bit more complex then you coded for. The results object holds an array with an object that has your stat property.
Putting these fixes together gives you this code.
RestClient restClient = new RestClient("https://thevirustracker.com/free-api?global=stats");
//Creating request to get data from server
RestRequest restRequest = new RestRequest(null, DataFormat.Json);
// Executing request to server and checking server response to the it
IRestResponse restResponse = restClient.Execute(restRequest);
// Extracting output data from received response
string response = restResponse.Content;
// Parsing JSON content into element-node JObject
var jObject = JObject.Parse(restResponse.Content);
//Extracting
// the object has a results property
// that is an array with one item (zero-based)
// on index 0 there is an object
// that has a property total_cases
string cases = (string) jObject["results"][0]["total_cases"];
label1.Text = (cases);
I am attempting to integrate with the Eventbrite API, I am just trying to create an event using RestSharp.
// Request to create an event.
var restClient = new RestClient("https://www.eventbriteapi.com/v3/");
This is the base url I am using {MyOrganiserID} and MyToken to replace my actual token.
var createEventRequest = new RestRequest("organizations/{MyOrganiserID}/events", Method.POST);
createEventRequest.AddHeader("Authorization", "Bearer MyToken");
createEventRequest.AddHeader("content-type", "application/x-www-form-urlencoded");
createEventRequest.AddQueryParameter("event.name.html", "My Event is good mate");
createEventRequest.AddQueryParameter("event.start.utc", "2019-12-12T18:00:00Z");
createEventRequest.AddQueryParameter("event.start.timezone", "Australia/Melbourne");
createEventRequest.AddQueryParameter("event.end.utc", "2019-12-12T20:00:00Z");
createEventRequest.AddQueryParameter("event.end.timezone", "Australia/Melbourne");
createEventRequest.AddQueryParameter("event.currency", "AUD");
IRestResponse createEventRestResponse = restClient.Execute(createEventRequest);
var requestContent = createEventRestResponse.Content;
I have also tried to send the parameters in the requestbody using AddBody and AddXMLBody from the RestSharp API.
createEventRequest.AddBody("event.name.html=<p>A DARQ Room Production Woof Woof</p>&event.start.utc=2019-12-12T18:00:00Z&event.start.timezone=Australia/Melbourne&event.end.utc=2019-12-12T20:00:00Z&event.end.timezone=Australia/Melbourne&event.currency=AUD");
createEventRequest.AddXmlBody("event.name.html=<p>A DARQ Room Production Woof Woof</p>&event.start.utc=2019-12-12T18:00:00Z&event.start.timezone=Australia/Melbourne&event.end.utc=2019-12-12T20:00:00Z&event.end.timezone=Australia/Melbourne&event.currency=AUD");
I've also tried to add the fields via the AddParameters method as well.
createEventRequest.AddParameter("event.name.html", "This is a good event mate");
createEventRequest.AddParameter("event.start.utc", "2019-12-12T18:00:00Z");
createEventRequest.AddParameter("event.start.timezone", "Australia/Melbourne");
createEventRequest.AddParameter("event.end.utc", "2019-12-12T20:00:00Z");
createEventRequest.AddParameter("event.end.timezone", "Australia/Melbourne");
createEventRequest.AddParameter("event.currency", "AUD");
With the AddQueryParameter I get a 401 Unauthorised I have tried putting the token as a query parameter aswell and it still says I'm unauthorized.
And another error I get is
{
"status_code": 403,
"error_description": "You do not have permission to access the resource you requested.",
"error": "NOT_AUTHORIZED"
}
When I send the parameter via the request body.
Any help anyone can provide would be deeply appreciated.
I have this c# method
public void TestMethod1()
{
string login = #"partone\afif#gmail.com" ;
string pwd = "ksLLHddf5El";
var request = new RestRequest("https://secureapp4.idshost.fr/authenticationids/restloginservice.php", Method.POST);
request.RequestFormat = DataFormat.Json;
request.AddHeader("Content-type", "application/json;charset=utf-8");
request.AddBody(new { authentifier = login, password = pwd });
RestClient client = new RestClient();
var response = client.Execute(request);
var data = response.Content;
}
The problem is the special character \ in the login string, it generates invalid authentifier parameter.
So I need to know how can I fix this?
The problem is likely to do with the receiving Rest endpoint.
Having looked through the RestSharp code it serializes the \ character correctly.
So when the JSON is generated it will turn your login into "partone\\afif#gmail.com" with two \\. You need to make sure the endpoint is correctly parsing this back into partone\afif#gmail.com
Its also a bit odd that the error is saying that it is an invalid parameter since you are sending it in the body.
Whats even stranger is that in your sample code you are attempting to post to a WSDL url. WSDL's are for SOAP web services and not restful webservices.
I'm having issues making POST requests with RestSharp. My Hashtable object 'param' contains key-value pairs that must be posted to the server. I've tried several combinations and have gotten weird output on the server-side.
Example 1:
var client = new RestClient();
var request = new RestRequest(url, Method.POST);
request.RequestFormat = DataFormat.Json;
request.AddBody (param);
Output:
Parameters: {"_json"=>[{"Key"=>"customer_subject_id", "Value"=>"300"}, {"Key"=>"client_code", "Value"=>"337"}, {"Key"=>"reservation_id", "Value"=>"9798"}, {"Key"=>"guid", "Value"=>"ODUUME4qhLmAcBVGlT4mrGbaHcbuXZID"}, {"Key"=>"customer_client_subject_id", "Value"=>"300"}, {"Key"=>"exam_code", "Value"=>"300"}, {"Key"=>"signature", "Value"=>"6bcbffb0c8ddcd89f159cf5ddd485d1eed76d1694ba329db5431f883bac3e982"}, {"Key"=>"customer_id", "Value"=>"lol"}, {"Key"=>"session_duration", "Value"=>60}]}
Example 2:
var client = new RestClient();
var request = new RestRequest(url, Method.POST);
foreach(DictionaryEntry entry in param){
request.RequestFormat = DataFormat.Json;
request.AddParameter ((entry.Key.ToString()), entry.Value);
}
Output:
Parameters: {"customer_subject_id"=>"300", "client_code"=>"337", "reservation_id"=>"9798", "guid"=>"o9LJ5e9t52xxFhxhAoHzmYd7AiQ3nu36", "customer_client_subject_id"=>"300", "exam_code"=>"300", "signature"=>"297cd7e871df885393ebe44b262cb40b8c03e55ae1f0567ff708e9811b2aedf8", "customer_id"=>"lol", "session_duration"=>"60"}
The output for #2 seems correct, but I'm getting a 401 on the server-side. Weirdly, the GET output matches that of #2, but the request is made successfully. I think the problem may be that the request, in total, is posting 10 parameters yet it should be posting one JSON formatted string in the body. Typically, I would put a JSON formatted string in the body, but even when I use a standalone JSON serializer to obtain a JSON string of the Hashtable and put in AddBody, I get the following:
Example 3:
var client = new RestClient();
var request = new RestRequest(url, Method.POST);
String paramJson = SimpleJson.SerializeObject (param);
request.RequestFormat = DataFormat.Json;
request.AddBody (paramJson);
Output:
Parameters: {"_json"=>"[{\"Key\":\"customer_subject_id\",\"Value\":\"300\"},{\"Key\":\"client_code\",\"Value\":\"337\"},{\"Key\":\"reservation_id\",\"Value\":\"9798\"},{\"Key\":\"guid\",\"Value\":\"56ZAsFtBx7jhDmdconWTb40qGirNagxK\"},{\"Key\":\"customer_client_subject_id\",\"Value\":\"300\"},{\"Key\":\"exam_code\",\"Value\":\"300\"},{\"Key\":\"signature\",\"Value\":\"57d7c878dec24da98815071d1dc3730873285b3ae65f9d98591da94266b8f7d7\"},{\"Key\":\"customer_id\",\"Value\":\"lol\"},{\"Key\":\"session_duration\",\"Value\":60}]"}
I'm mostly curious as to why the JSON string that RestSharp is creating contains "_json" at the beginning of it.
Thanks,
John
Is your server running Rails? Maybe this is relevant https://groups.google.com/forum/#!topic/rubyonrails-core/ZYBI_XHYpak
If you have control of the server side, might be better to use AddParameter and pass a JSON string, which you can parse on the server side.