'passing using the same uri paramater, getting two different outcomes
I am trying to get a list of 100 help desk tickets from an API. the url is below.
https://sdpondemand.manageengine.com/app/itdesk/api/v3/requests?input_data={"list_Info":{"row_count":100,"start_index":101}}
I am able to produce successful results, meaning it brings back 100 rows starting at index 101, when I put the uri into a string like this:
string extra = "app/itdesk/api/v3/requests?input_data={\"list_info\":{\"row_count\":100,\"start_index\":101}}";
but if I try to put the json into classes, then serialize it with the Json.Net library, it will fail, meaning it brings back just 10 rows on index 1.
private class input_data
{
public list_info list_Info = new list_info();
}
private class list_info
{
public int row_count = 100;
public int start_index = 101;
}
input_data input = new input_data();
string json = Newtonsoft.Json.JsonConvert.SerializeObject(input);
string extra1 ="app/itdesk/api/v3/requests?input_data="+json;
I look at both of the request coming out an there exactly the same. what am I doing wrong?
what the vars look like in the code
extra: app/itdesk/api/v3/requests?input_data={"list_info":{"row_count":100,"start_index":101}}
extra1: app/itdesk/api/v3/requests?input_data={"list_Info":{"row_count":100,"start_index":101}}
Solution 1:[1]
Passing serialized DTO object in the Get request is not the proper way of implementing an API. Get request supposed to be having params rather than a serialize object. If you wish to do so and have to send an object then why not using a post request.
The sample implementation for a rest api could be as:
Via GET
[Route("{rowCount}/{startIndex}"), HttpGet]
public IHttpActionResult Get(int rowCount, int startIndex)
{
//Your logic Implementation
}
calling would be like
www.xyz.com/controllerName/100/101
This is the rest implementation of the request
Via POST
[Route(""), HttpPost]
public IHttpActionResult Post([FromBody]YourDTOClass obj)
{
//Your logic Implementation
}
For example you have the DTO class
//In C# the class name should be capital
private class ListInfo
{
//In c# the property name should be Capital
public int RowCount {get; set;} = 100;
public int StartIndex {get; set;}= 101;
}
So your Post method would look like
//Route attribute is for configuring the custom route
//It is a feature in MVC 5
//FromBody attribute will search for data in the request body
[Route(""), HttpPost]
public IHttpActionResult Post([FromBody]ListInfo info)
{
//Your logic Implementation
}
If you are using the C# for calling the API too, then you could use HttpClient where passing the json object of your class a data.
Edited: As you are using a third party API, therefore you need to correct the calling.
using (var client = new HttpClient())
{
//Setting the base address of the server
client.BaseAddress = new Uri("https://sdpondemand.manageengine.com");
//creating an anonymous object
var jsonObject = new {
input_data = new {
row_count = 100,
start_index = 101
}
};
//Converting into the content string
var content = new StringContent(JsonConvert.SerializeObject(jsonObject), Encoding.UTF8, "application/json");
//waiting for the post request to complete
var result = await client.PostAsync("app/itdesk/api/v3/requests", content);
//reading the response string
string resultContent = await result.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
//Deserialize your string into custom object here
var obj = JsonConvert.DeserializeObject<YourDTO>(resultContent);
}
else
{
//Todo: Log the Exception here
throw new Exception(contentString);
}
}
Solution 2:[2]
extra : app/itdesk/api/v3/requests?input_data={"list_info"{"row_count":100,"start_index":101}} extra1:app/itdesk/api/v3/requests?input_data={"list_Info":{"row_count":100,"start_index":101}}
messed up the list info
extra : app/itdesk/api/v3/requests?input_data={"list_info"{"row_count":100,"start_index":101}} extra1:app/itdesk/api/v3/requests?input_data={"list_info":{"row_count":100,"start_index":101}}
[shrug emoji]
Solution 3:[3]
Adding comments to this to clear up confusion. ManageEngine Service Desk Plus API is not a properly/typically implemented API. Basically you have to URL encode JSON and pass it in either the URL as a param or in the form as a application/x-www-form-urlencoded
example:
json:
{
"request": {
"subject": "testing subject",
"description": "I am a test. Delete me.",
"requester": {
"id": "4817"
},
"subcategory": {
"name": "Errors/Problems Using SalesForce",
"id": "2406"
},
"category": {
"name": "SalesForce",
"id": "608"
}
}
}
becomes:
input_data='%7B%0A++%22request%22%3A+%7B%0A++++%22subject%22%3A+%22testing+subject%22%2C%0A++++%22description%22%3A+%22I+am+a+test.+Delete+me.%22%2C%0A++++%22requester%22%3A+%7B%0A++++++%22id%22%3A+%224817%22%0A++++%7D%2C%0A++++%22subcategory%22%3A+%7B%0A++++%22name%22%3A+%22Errors%2FProblems+Using+SalesForce%22%2C%0A++++%22id%22%3A+%222406%22%0A++++%7D%2C%0A++++%22category%22%3A+%7B%0A++++%22name%22%3A+%22SalesForce%22%2C%0A++++%22id%22%3A+%22608%22%0A++++%7D%0A++%7D%0A%7D'
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Franco Pettigrosso |
| Solution 3 | Tyler Raber |
