C# - Json Deserialize doesn't work correctly? - c#

I have an C# program which calls a website API to get a JSON response:
{"success":true, "taskid":"1466687729433", "tasktype":"kkk", "steamid":32323, "value":5.68, "token":"sadsad", "items":[5751210424, 5751210304], "botid":1}
Then I'm using it like this:
public Task checkForTasks()
{
try
{
return JsonConvert.DeserializeObject<Task>(base.Bot.SteamWeb.Fetch("LinkHere", "GET", null, false, ""));
}
catch (Exception)
{
}
return new Task { success = false };
}
But I keep getting error in my output console:
Exception thrown: 'Newtonsoft.Json.JsonReaderException' in
Newtonsoft.Json.dll
What could cause that?

It is not a valid json:
{"success":true, "taskid":"", "tasktype":"", "steamid":, "value":, "token":"", "items":[5751210424, 5751210304], "botid":}
try with something like:
{"success":true, "taskid":"", "tasktype":"", "steamid":, "value":"", "token":"", "items":[5751210424, 5751210304], "botid": 1}
Well I copy your json to my visual studio with special paste it gives me error while generating relevant class

Your JSON is invalid.
{
"success": true,
"taskid": "",
"tasktype": "",
"steamid": ,
"value": ,
"token": "",
"items": [5751210424, 5751210304],
"botid":
}
value and botid are missing. The deserializer cannot deserialize incomplete JSON.

Related

How to access Json (which was a result of HttpMessage) in C#?

I am writing two applications (Web API's) in .NET . From the app A I want to call a method in Controller of app B using Http Request.
Here
using (var askPensionerDetails = new HttpClient())
{
double pensionToDisburse = 0;
askPensionerDetails.BaseAddress = new Uri("http://localhost:55345/api/pensionerdetails/");
var responseTask = askPensionerDetails.GetAsync("getById?pan=" + inputOfPensioner.PAN);
responseTask.Wait();
var result =responseTask.Result ;
if (result.IsSuccessStatusCode)
{
var readTask = result.Content.ReadFromJsonAsync<object>();
readTask.Wait();
return Ok(readTask.Result);
}
}
The output for this in postman is
{
"name": "bunk seenu",
"dateOfBirth": "1990-01-02T00:00:00",
"pan": "ABCD12351E",
"salaryEarned": 45000,
"allowances": 500,
"pensionType": 1,
"bankDetails": {
"bankName": "SBI",
"accountNumber": "SBI00001BS",
"bankType": 0
}
}
That was a desired output. But the problem is how to access the properties like bankdetails,name,pan,salaryEarned.
I have tried using readTask.Result["name"] but it is throwing error.
I have also tried using result.Content.ReadAsStringASync();
But the output in postman is
{
"name": [],
"dateOfBirth": [],
"pan": [],
"salaryEarned": [],
"allowances": [],
"pensionType": [],
"bankDetails": [
[
[]
],
[
[]
],
[
[]
]
]
}
I don't have class associated with the result type of Json for statement readTask = result.Content.ReadFromJsonAsync(); (As per design constraints).
From the docs:
If you have JSON that you want to deserialize, and you don't have the class to deserialize it into, you have options other than manually creating the class that you need:
Deserialize into a JSON DOM (document object model) and extract what you need from the DOM.
The DOM lets you navigate to a subsection of a JSON payload and deserialize a single value, a custom type, or an array. For information about the JsonNode DOM in .NET 6, see Deserialize subsections of a JSON payload. For information about the JsonDocument DOM, see How to search a JsonDocument and JsonElement for sub-elements.
Use the Utf8JsonReader directly.
Use Visual Studio 2019 to automatically generate the class you need:
Copy the JSON that you need to deserialize.
Create a class file and delete the template code.
Choose Edit > Paste Special > Paste JSON as Classes. The result is a class that you can use for your deserialization target.
You can use Newtonsoft.Json
JObject jo = JObject.Parse(readTask.Result);
var name = jo["name"];
if(string.IsNnullOrEmpty(name)){
///some code
}

Parsing JSON Using Newtonsoft.Json Without Knowing the Structure

I'm working on a project that involves automating API calls using a Swagger Definition. I download the swagger.json file. The structure of the JSON Object I need to parse is not consistent. When parsing paths, there are a list of objects, then within that they have the methods that can be used for that specific path. I can retrieve just the path using various string methods but my question was, is there a good way to parse json if the JSON is structured in such a way that it does not have a firm key? Here is an example of what I mean:
{"/user": {
"post": {
"tags": [
"user"
],
"summary": "Create user",
"description": "This can only be done by the logged in user.",
"operationId": "createUser",
"consumes": [
"application/json"
],
"produces": [
"application/json",
"application/xml"
],
"parameters": [
{
"in": "body",
"name": "body",
"description": "Created user object",
"required": true,
"schema": {
"$ref": "#/definitions/User"
}
}
],
"responses": {
"default": {
"description": "successful operation"
}
}
}
}
If I wanted to just parse that path and retrieve the method object how could I go about that considering sometimes the object will be "post" or sometimes it will be "get", "put", etc depending on what is allowable for the path.
JObject jsonResp = swaggerDownload();
JObject paths = (JObject)jsonResp["paths"];
foreach (var i in paths)
{
string pathToString = i.ToString();
var shaveSomethings = pathToString.Substring(1, something.Length - 2);
var pathAndJson = shaveSomethings.Split(new[] { ',' }, 2);
string correctJsonStructure = "{\"" + pathAndJson[0] + "\":" + pathAndJson[1] + "}";
JObject bd = JObject.Parse(correctJsonStructure);
//dynamic pathsTest = JsonConvert.DeserializeObject<dynamic>(correctJsonStructure);
//JObject result = JsonConvert.DeserializeObject<JObject>(correctJsonStructure);
//Console.WriteLine(bd["/user"]);
}
The swagger.json file should have full definition of each entity that endpoints return. You can follow How to create Rest API client to get a working client.
I've dealt with an API where responses didn't always match the definition. I saved all responses to a store/log first and then would try to de-serialize JSON. In case of an exception I would go back to store/log and see what was different and update my code to accommodate for the change. After few iterations there were no new changes and the ordeal was over.
Hope that helps.

Parsing a JSON dictionary that contains the same key with different casing

I have a problem;
I would to know if there is a method to parse json file without having a unique format. So it may have different attributes but all of them contain the attribute Status but it can be in double.
{
"requestid": "1111",
"message": "db",
"status": "OK",
"data": [
{
"Status": "OK", // this one I would to test first to read the other attributes
"fand": "",
"nalDate": "",
"price": 1230000,
"status": 2
}
]
}
With https://www.newtonsoft.com/json
Data data = JsonConvert.DeserializeObject<Data>(json);
And create the class Data with the interesting data inside the json
The defacto standard Json serializer for .NET is Newtonsoft.Json (How to install). You can parse the Json into an object graph and work on that in any order you like:
namespace ConsoleApp3
{
using System;
using Newtonsoft.Json.Linq;
class Program
{
static void Main()
{
var text = #"{
'requestid': '1111',
'message': 'db',
'status': 'OK',
'data': [
{
'Status': 'OK', // this one I would to test first to read the other attributes
'fand': '',
'nalDate': '',
'price': 1230000,
'status': 2
}
]
}";
var json = JObject.Parse(text);
Console.WriteLine(json.SelectToken("data[0].Status").Value<string>());
Console.ReadLine();
}
}
}

Valid JSON string throws Unexpected character encountered error

I'm trying to connect an angular2 client to a C# ASP.net core server. When I'm sending a JSON string using websockets from the client to the server, I get an error:
Unexpected character encountered while parsing value: {. Path 'Argument', line 1, position 39.
The JSON string is as follows (The error seems to originate from the opening bracket after "Argument:"):
{
"MethodName": "CreateUser",
"Argument": {
"User": {
"Attributes": [{
"Name": "age",
"Value": "30",
"Type": 0
}],
"Email": "test#mail.com",
"Name": "Test Name"
},
"Password": "1234"
}
}
The code that throws the error is here:
public string Receive(string input)
{
try
{
Debug.WriteLine(input);
InstructionServer jsonObject = JsonConvert.DeserializeObject<InstructionServer>(input); // This fails
string methodName = jsonObject.MethodName;
string data = jsonObject.Argument;
return methods[methodName](1, data, "", "");
}
catch (Exception e)
{
return "error: " + e.Message;
}
}
I can't seem to figure out what the error is, because when I throw the JSON into an online JSON Formatter, it reports it as valid JSON. Any help would be appreciated.
EDIT: Just to clarify on the valid JSON. I tried printing the json string out before sending it on the client and after receiving it on the server, and it is the same json string as written above.
Argument appears to be expecting a string, but found an object. You'll have to check the format that InstructionServer is expecting and ensure that it will be able to deserialize correctly.
The Receive method expect the string value, this means you have to convert your object to JSON format to be like this:
"{\"MethodName\":\"CreateUser\",\"Argument\":{\"User\":{\"Attributes\":[{\"Name\":\"age\",\"Value\":\"30\",\"Type\":0}],\"Email\":\"test#mail.com\",\"Name\":\"Test Name\"},\"Password\":\"1234\"}}"

Octopus client cannot parse Deployments dict in ReleaseProgressionResource

I am trying to get release progressions for a certain project using the Octopus Client (github source) calling the /api/progression/<project-id> endpoint like this:
// _repository is of type IOctopusRepository
_repository.Client.Get<ProgressionResource>($"/api/progression/{projectId}");
Which is immediately throwing an OctopusDeserializationException saying:
Unable to process response from server: Cannot deserialize the current
JSON object (e.g. {"name":"value"}) into type
'System.Linq.IOrderedEnumerable`1[Octopus.Client.Model.DashboardItemResource]'
because the type requires a JSON array (e.g. [1,2,3]) to deserialize
correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET
type (e.g. not a primitive type like integer, not a collection type
like an array or List) that can be deserialized from a JSON object.
JsonObjectAttribute can also be added to the type to force it to
deserialize from a JSON object.
Path 'Releases[0].Deployments.Environments-1.Id', line 55, position 15.. Response content: {
"Environments": [
{
"Id": "Environments-1",
"Name": "test-environment"
},
In each Release (of type ReleaseProgressionResource) from the Releasesthere is a Deployments prop which is of type Dictionary<string,IOrderedEnumerable<DashboardItemResource>>. However, it seems like the client (that has been made to consume this API) cannot serialize that. From the exception message, it seems like the client is trying to parse that as a JSON array.
Here's a sample Deployments part of the endpoint response in raw JSON (with some dummy data):
"Deployments": {
"Environments-1": {
"Id": "Deployments-12345",
"ProjectId": "Projects-123",
"EnvironmentId": "Environments-1",
"ReleaseId": "Releases-12345",
"DeploymentId": "Deployments-12345",
"TaskId": "ServerTasks-12345",
"ReleaseVersion": "5.4.3",
"Created": "2016-09-22T21:26:38.886+00:00",
"QueueTime": "2016-09-22T21:26:38.855+00:00",
"CompletedTime": "2016-09-22T21:29:48.355+00:00",
"State": "Success",
"HasPendingInterruptions": false,
"HasWarningsOrErrors": false,
"ErrorMessage": "",
"Duration": "3 minutes",
"IsCurrent": true,
"IsPrevious": false,
"IsCompleted": true,
"Links": {
"Self": "/api/deployments/Deployments-12345",
"Release": "/api/releases/Releases-12345",
"Task": "/api/tasks/ServerTasks-12345"
}
}
}
Does anyone have any ideas what might be happening/what I might be doing wrong?
Thanks in advance.
Is that the whole Deployment object? JSON objects need to be enclosed in brackets.
{
"Deployments": {
"Environments-1": {
"Id": "Deployments-12345",
"ProjectId": "Projects-123",
"EnvironmentId": "Environments-1",
"ReleaseId": "Releases-12345",
"DeploymentId": "Deployments-12345",
"TaskId": "ServerTasks-12345",
"ReleaseVersion": "5.4.3",
"Created": "2016-09-22T21:26:38.886+00:00",
"QueueTime": "2016-09-22T21:26:38.855+00:00",
"CompletedTime": "2016-09-22T21:29:48.355+00:00",
"State": "Success",
"HasPendingInterruptions": false,
"HasWarningsOrErrors": false,
"ErrorMessage": "",
"Duration": "3 minutes",
"IsCurrent": true,
"IsPrevious": false,
"IsCompleted": true,
"Links": {
"Self": "/api/deployments/Deployments-12345",
"Release": "/api/releases/Releases-12345",
"Task": "/api/tasks/ServerTasks-12345"
}
}
}
}

Categories

Resources