I have a simple GraphQL query that I'm making out to a server, and trying to use GraphQL.Client.Serializer.Newtonsoft to deserialize it. I'm getting a response, but the response does not make the NewtonsoftJsonSerializer happy. It complains:
This converter can only parse when the root element is a JSON Object.
Okay, fair enough. The response must not be what was expected. But how can I view the response to see what may be wrong? The GraphQLHttpClient.SendQueryAsync<>() method requires a type to try to deserialize to...which is the part that is failing. I don't see a way to just get the text response so I can see what is wrong with it.
I've included sample code at the bottom, but the only real line of interest (I believe) is the last one:
var graphQLResponse = await graphQLClient.SendQueryAsync<object>(theRequest);
Is there some way to just get the text of the response?
var graphQLClient = new GraphQLHttpClient("https://<TheDomain>.com/graphql/api/v1", new NewtonsoftJsonSerializer());
graphQLClient.HttpClient.DefaultRequestHeaders.Add("Authorization", "Bearer <MyKey>");
graphQLClient.HttpClient.DefaultRequestHeaders.Add("Accept", "application/json");
var theRequest = new GraphQLRequest
{
Query = "{ __schema { queryType { fields { name } } } }"
};
var graphQLResponse = await graphQLClient.SendQueryAsync<object>(theRequest);
Using Fiddler Everywhere, I was able to pull in the request and response, both of which seem superficially valid (I updated the query in the question to match the current query I'm passing in...a general schema query)
Request:
{
"query": "{ __schema { queryType { fields { name } } } }"
}
Response:
(I've redacted the names of the endpoints and removed much of the repetition from the middle of the response. But the rest is unchanged, and looks superficially okay to me...in particular, it looks like valid JSON, so I'm unclear why the converter is complaining.)
{
"errors": [],
"data": {
"__schema": {
"queryType": {
"fields": [
{
"name": "getData1"
},
{
"name": "getData2"
},
...
<a bunch more here>
...
{
"name": "getData100"
}
]
}
}
},
"extensions": null,
"dataPresent": true
}
After a few hit and trials and discussion with the O.P, it was found that while initializing GraphQLHttpClient with GraphQL.Client.Serializer.Newtonsoft, the serializer is not correctly doing the deserialization of the response despite the response being a valid JSON string.
After switching to GraphQL.Client.Serializer.SystemTextJson, the response is being correctly parsed as expected which suggests that there could be a bug in the GraphQL.Client.Serializer.Newtonsoft serializer
Related
I have a web service that I'm trying to write to, but every time I try to send a PUT request to it I get a 'Bad Request(400)' Error. I'm using the ASP.NET MVC framework and I have everything set up in one of my controllers. I have a model as well that models the data that should be sent to the API. This is how I have everything set up:
PUT FUNCTION
public string putFunction(ItemOject item)
{
// PROVIDED DETAILS
string API_PATH = "API_PATH";
// CONTENT
var content = new StringContent(JsonConvert.SerializeObject(item));
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("Key1", KEY_1);
client.DefaultRequestHeaders.Add("Key2",KEY_2);
client.DefaultRequestHeaders.Add("Key3", KEY_3);
// KEYS and BASE_URL are defined outside the function
var response = client.PutAsync($"{BASE_URL}{API_PATH}", content).Result;
return response.ToString();
}
This is what the param 'item' is getting passed:
ItemObject item = new ItemObject
{
Name = "Test2",
Errors = null,
ID = "8c785cd5-673a-4b3c-b97d-b8446dad401a",
OwnerID = "30e5772a-a11c-4172-96ae-cc850bd6509a"
};
And this is the response I get:
StatusCode: 400, ReasonPhrase: 'Bad Request'
I'm positive all the KEYS are setup correctly and the URL is correct. The endpoint does work because I've tested it in Postman with no issue. The only thing now is that I can't send the HTTP PUT request from this function. I've played around to make sure that the data I'm sending in Postman is almost exactly what I'm sending from this function. I don't know what I'm missing or what more tests I could be trying.
This is my Postman request:
{"Item":
{
"Errors": null,
"ID": "8c785cd5-673a-4b3c-b97d-b8446dad401a",
"Name": "Test1",
"OwnerID": "00000000-0000-0000-0000-000000000000"
}
}
And that works fine in Postman if I were to again send a GET request, it would retieve that said data. But I can't do that within ASP.NET without getting the "Bad Request(400)" Error.
What I've tried so far:
Can't find how to use HttpContent
Send ASP.NET MVC HttpContext to Web Api HttpContext
https://www.c-sharpcorner.com/article/asp-net-web-api-using-mvc-entity-framework-and-httpclient-for-get-and-post-with/
Serializing your current object would result in this:
{
"Errors": null,
"ID": "8c785cd5-673a-4b3c-b97d-b8446dad401a",
"Name": "Test1",
"OwnerID": "00000000-0000-0000-0000-000000000000"
}
But what you are passing into Postman is this:
{
"Item":
{
"Errors": null,
"ID": "8c785cd5-673a-4b3c-b97d-b8446dad401a",
"Name": "Test1",
"OwnerID": "00000000-0000-0000-0000-000000000000"
}
}
So your model should look more like:
ItemObject item = new ItemObject()
{
Item = new ItemSubObject()
{
Name = "Test2",
Errors = null,
ID = "8c785cd5-673a-4b3c-b97d-b8446dad401a",
OwnerID = "30e5772a-a11c-4172-96ae-cc850bd6509a"
}
};
I am trying to create a virtual machine through a post method but I have not been able to create it since I cannot send the json file correctly.
This is my code:
// Create a json object
var deploy = new Deploy
{
name = "RandomName",
folder = "folder_3044",
resource_pool = "resgroup-4035"
};
//Change it into a json file
var deployResult = JsonConvert.SerializeObject(deploy);
//Change this file into a string so we can send it to the post method
var jsonContent = new StringContent(deployResult);
//Make post and send the needed information
var postResponse = await httpClient.PostAsync("URI", jsonContent);
return (content);
When executing my code in Postman it gives me a false positive because it sends something but it seems that it does not send the json as I wanted but the code below:
{
"headers": [
{
"key": "Content-Type",
"value": [
"text/plain; charset=utf-8"
]
},
{
"key": "Content-Length",
"value": [
"97"
]
}
]
}
Can anyone help me with this? I just need to send that json in my post like I do when sending from Postman.
Ps: I use .Net core and I can't change even if I want to.
This is the json that should be sent for it to work:
{
"name": "RandomName",
"placement": {
"folder": "folder_3044",
"resource_pool": "resgroup-4035"
}
}
Thank you to #Peter Csala's comment: When I specified the content-type as you advised, it worked. Just for future references, we need these two lines of code. (Don't forget to include the assembly System.Text on top.)
using System.Text;
new StringContent(deployResult, Encoding.UTF8, "application/json");
What's the correct way of handling a result with possible different types for the same key?
Example HTTP call JSON response:
[
{
"code": 200,
"body": {
"id": "foo",
"status": "paused", ← this is a string
...more properties of MyType (id and status are properties of MyTypem as well)
}
},
{
"code": 404,
"body": {
"id" "bar",
"status": 404, ← this is a number
...more properties of a small but different object
}
}
]
I tried using object or dynamic for either the whole body property or only the status but always had parsing errors when attempting to transform or cast to MyType.
I don't really care about elements with status code other than 200 in the list so I filtering them out with a LINQ Where but I keep getting different type of errors.
This is an example of one of the things I tried:
var response = await client.GetAsync("https://api.com");
try
{
var str = await response.Content.ReadAsStringAsync();
var settings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Ignore
};
var results = JsonConvert.DeserializeObject<List<dynamic>>(str, settings);
return results.Where(x => x.code == 200).Select(x => (MyType)x.body).ToList();
}
catch (Exception ex)
{
Log.Error($"There was an error parsing: {ex}");
}
Is there any correct way of doing this at runtime?
I'm using JObject.Parse and it's not a valid json as it has two {{ in the beginning and two }} at the end instead of only one of each.
Tried catching exception but didn't hit the exception of my try catch.
If I remove the extra { in the beginning and the extra } in the end jsonFormatter/validator webpage says it's okey.
var URL = "https://api.instagram.com................my access token etc";
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(URL);
HttpResponseMessage response = client.GetAsync(URL).Result;
using (HttpContent content = response.Content)
{
Task<string> result = content.ReadAsStringAsync();
JObject json = JObject.Parse(result.Result);
}
So reuslt.Result looks like this: "{\"pagination\": {}, \"data\": [{\"id\".........
and json starts looks like this: {{ "pagination": {}, "data": [ { "id": "20...............
When copying the json into formatter/validator and removing the extra { in the beginning and the extra } in the end everything is okey.
So I expect the output json from JObject.Parse should look like this: { "pagination": {}, "data": [ { "id": "20...............
I can not understand why I'm getting these extra {} things?
I have a Json which is converted to string and then writted in DataBase
function UpdateFilter() {
var filterOption = {
"filterTarget": "Books",
"filters": [
{ "cancelled": $("#showCancelledFilter").is(':checked') },
{ "completed": $("#showAllFilter").is(':checked') }
],
"page": page,
"sorting": sorting
};
var url = "Library/Books/UpdateFilter";
$.post(url, { pageFilters: JSON.stringify(filterOption) }, function (data) { });
}
Up until this point everything seems to be fine.
Issue starts when I am trying to get json from string:
var data = JObject.Parse(jsonString);
return Json(data, JsonRequestBehavior.AllowGet);
Seems fine BUT in:
$.get('Library/Books/GetPageFilters', null, function(data) {
filterOption = data;
}, "json");
I have received a object with 4 arrays (each on each json property, and each array has empty array inside it).
I assume that I am lacking something in converting string to json, but I can't get it.
What am I missing?
I gess your problem situated where you using $.get() jquery method. From documentation of $.get():
dataType Type: String The type of data expected from the server.
Default: Intelligent Guess (xml, json, script, or html).
Seem like Intelligent Guess can't understand what was come from server.
Try $.getJSON() insted.