Json deserialize returning null - c#

Here is the JSON response
{
"result": [
{
"sys_id": "85071a1347c12200e0ef563dbb9a71c1",
"number": "INC0020001",
"description": ""
}
]
}
Here is my JSON class
public class Result
{
public string sys_id { get; set; }
public string number { get; set; }
public string description { get; set; }
}
public class jsonResult
{
public IList<Result> result { get; set; }
}
Here is what I am doing to deserialize
strReponse = rClient.makeReqest();
Result deserializedProduct = JsonConvert.DeserializeObject<Result>(strReponse);
System.Windows.Forms.MessageBox.Show(deserializedProduct.number);
It looks like it never assigns anything into my JSON class.
This is my first time dealing with JSON and Web calls. What am i missing? The API call does return the correct JSON, and I used json2csharp to make my json class.
Thank you!

You need deserialize full object represented in json string. Which is jsonResult in your case.
After, you will get access to values, you need, through properties of jsonResult
strReponse = rClient.makeReqest();
var deserializedResult = JsonConvert.DeserializeObject<jsonResult>(strReponse);
var number = deserializedResult.result.First().number;
MessageBox.Show(number);
Because jsonResult.result is of type IList will be safer to loop through all possible results
strReponse = rClient.makeReqest();
var deserializedResult = JsonConvert.DeserializeObject<jsonResult>(strReponse);
foreach (var result in deserializedResult.result)
{
MessageBox.Show(result.number);
}

You should deserialize to jsonResult NOT Result.
So try this :
jsonResult deserializedProduct = JsonConvert.DeserializeObject<jsonResult>(strReponse);
Also you may get values of the list like this:
var firstResult = deserializedProduct.result.FirstOrDefault();
var someSpecialResults = deserializedProduct.result.Where(r=>r.number.Contains("123"));
Also :
if (firstResult != null)
System.Windows.Forms.MessageBox.Show(firstResult .number);
Also you may iterate them like this :
deserializedProduct.result.ForEach(r=> System.Windows.Forms.MessageBox.Show(r.number);)
I hope to be helpful for you:)

Related

How to simply parse JSON string from a website to C#

so I have a problem:
The code in JSON that you see there is a response that a webpage gives me. And the thing I want to do is really simple:
I just want to parse for example the "user_id", or "class".
I tried few things on stackoverflow that I found but no one works...
{
"data": {
"user": {
"class": "user",
"user_id": "81046537",
"etp_guid": "76411082-73ab-5aaa-9242-0bb752cf97a4",
},
},
}
Thanks !
There are many ways you can extract the user_id from the json. The most common way is to use Newtonsoft.Json package.
Assuming the json is stored as a string, you can call JObject.Parse().
var data = "{'data': {'user': {'class': 'user','user_id': '81046537','etp_guid': '76411082-73ab-5aaa-9242-0bb752cf97a4'} } }";
JObject jObject = JObject.Parse(data);
var userId = jObject["data"]["user"]["user_id"];
Console.WriteLine($"User id {userId}");
If your json is stored as a n object, then call JObject jObject = new JObject(data)
A preferred way is to serialise your json using business object. Simply create classes to match the json structure. e.g:
public class Response
{
public Data Data { get; set; }
}
public class Data
{
public User User { get; set; }
}
public class User
{
public string Class { get; set; }
public string User_id { get; set; }
public string Etp_guid { get; set; }
}
Then deserialize your object. e.g:
var response = JsonConvert.DeserializeObject<Response>(data);
Console.WriteLine($"User id {response.Data.User.User_id}");

Extract data from json C#

I have a a api response from Azure Ml which returns the follow json bellow:
responseApi content
{ "Results": { "id_unidade_negocio": [ { "msgSucesso": "Processamento concluído com sucesso" } ] } }
I would like to extract only the "msgSucesso": "Processamento concluído com sucesso"
I try the code below, however didn't work.
var obj = JObject.Parse(responseApi);
var msg = (string)obj.SelectToken("Results.msgSucesso");
I didin't try to deserialize the json to a object class, because I don't know the right format class to create it to be compatible with output json.
Whats is the best way to extract this info from json response?
Or How can I create a class that fit in this json output in other to convert the json to object?
https://stackoverflow.com/a/24233127/2906166
check above link
public class IdUnidadeNegocio
{
public string msgSucesso { get; set; }
}
public class Results
{
public List<IdUnidadeNegocio> id_unidade_negocio { get; set; }
}
public class RootObject
{
public Results Results { get; set; }
}
var obj = JsonConvert.DeserializeObject<RootObject>(responseApi);
Console.WriteLine(obj.Results.First().msgSucesso);

Deserialize dynamic json into generic .NET object

What is the best way to deserialize the following JSON response into a generic object? For example I would like to access the response message and a the list of errors (and accessing the field name and error message of it).
{
"message": "The given data was invalid.",
"errors": {
"name": [
"Name is required."
],
"gender": [
"Gender is required."
],
"date_of_birth": [
"Date of birth is required."
]
}
}
Edit:
I would like to access the JSON object in a way something like this
string message = genericObject.message
foreach (error errorElement in genericObject.errors)
{
string errorField = errorElement.fieldName;
string errorDescription = errorElement.errorMessage;
}
Edit 2:
I don't know the possible error fields beforehand.
Since you mention that you do not know which "error fields" will be present, a dictionary is the best way to go.
Here's a simple example:
void Main()
{
string json = File.ReadAllText(#"d:\temp\test.json");
var response = JsonConvert.DeserializeObject<Response>(json);
response.Dump();
}
public class Response
{
public string Message { get; set; }
public Dictionary<string, List<string>> Errors { get; }
= new Dictionary<string, List<string>>();
}
When executing this in LINQPad, I get this output:
You can even add your own code from your question:
string json = File.ReadAllText(#"d:\temp\test.json");
var genericObject = JsonConvert.DeserializeObject<Response>(json);
string message = genericObject.Message;
foreach (var errorElement in genericObject.Errors) // see note about var below
{
string errorField = errorElement.Key;
string errorDescription = errorElement.Value.FirstOrDefault(); // see below
}
Note 1: The result of iterating a dictionary is a KeyValuePair<TKey, TValue>, in this case it would be a KeyValuePair<string, List<string>>.
Note 2: You've shown JSON having an array for each field, so errorElement.errorMessage isn't going to work properly since you may have multiple error messages.
You can nest some loops, however, to process them all:
string message = genericObject.Message;
foreach (var errorElement in genericObject.Errors) // see note about var below
{
string errorField = errorElement.Key;
foreach (string errorDescription in errorElement.Value)
{
// process errorField + errorDescription here
}
}
There are many ways to do this.
The System.Web.Helpers assembly contains the Json class which you can do:
dynamic decodedObject = Json.Decode(json);
Another way would be to use the Newtonsoft.Json nuget package:
var deserializedObject = JsonConvert.DeserializeObject<dynamic>(json);
If you are willing to use Newtonsoft.Json you can use:
var json = JsonConvert.DeserializeObject<dynamic>(originalJson);
you would have to create the following classes:
RootObject.cs containing the following properties:
public class RootObject
{
[JsonProperty("message")]
public string Message { get; set; }
[JsonProperty("errors")]
public Errors Errors { get; set; }
}
Errors.cs, containing the following properties:
public class Errors
{
[JsonProperty("name")]
public string[] Name { get; set; }
[JsonProperty("gender")]
public string[] Gender { get; set; }
[JsonProperty("date_of_birth")]
public string[] DateOfBirth { get; set; }
}
And then you read the whole thing like this:
var inputObj = JsonConvert.DeserializeObject<RootObject>(json);
Where inputObj will be of type RootObject and json is the JSON you are receiving.
If you have implemented this correctly, use it like this:
var message = inputObj.Message;
var nameErrors = inputObj.Errors;
var firstNameError = inputObj.Errors.Name[0];
Here is a visual:
Showing the whole object, filled with the properties:
The "main" error:
If you have any questions feel free to ask.

Convert complex JSON to Generic List using Newtonsoft

Below is a Json :
[{
"Result": {
"description": "Application Security Supp Specialist",
"code": "40000003"
}
}, {
"Result": {
"description": "Gvt Cyber Intelligence Specialist",
"code": "40001416"
}
}, {
"Result": {
"description": "Gvt Record Retention Specialist",
"code": "40001428"
}
}]
And below is the class structure which i have created as i need to fill this into a C# object.
I am trying to create a collection of RulesEngineOutput and fill it with the json contents.
public class RulesEngineOutput
{
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("code")]
public string Code { get; set; }
}
public class RulesEngineOutputCollection
{
public IEnumerable<RulesEngineOutput> ProbableRoles { get; set; }
}
I am trying to achieve this using below code :
var bodyJson = JsonConvert.SerializeObject(bodyString);
RulesEngineOutputCollection result = new RulesEngineOutputCollection();
foreach (var item in bodyJson)
{
result = JsonConvert.DeserializeObject<RulesEngineOutputCollection>(item.ToString());
}
But this is throwing exception as the item gets a char, what i am thinkiong is that i need to pass a JSON object in the loop but i am not able to get one.
Everytime i get is a JSON string.
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'RulesEngineOutputCollection' because the type requires a JSON object (e.g. {\"name\":\"value\"}) to deserialize correctly.\r\nTo fix this error either change the JSON to a JSON object (e.g. {\"name\":\"value\"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array.
The problem is that you have an intermediary object between your RulesEngineOutput and your collection. You need to restructure your objects as such:
public class RulesEngineOutput
{
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("code")]
public string Code { get; set; }
}
public class RulesEngineOutputResult
{
public RulesEngineOutput Result { get; set; }
}
public class RulesEngineOutputCollection
{
public IEnumerable<RulesEngineOutputResult> ProbableRoles { get; set; }
}
And then when you have this restructuring done, you can deserialize directly to your RulesEngineOutputCollection instead of to an object and iterating and deserializing again.
result = JsonConvert.DeserializeObject<RulesEngineOutputCollection>(bodyString);
Thanks a lot Max,Nathan and others. So finally i made some changes in code and below is the code which i changed tomake the things work :
var jToken = JObject.Parse(responseContent);
var bodyString = jToken.SelectToken("body");
var bodyJson = JsonConvert.SerializeObject(bodyString);
List<RulesEngineOutput> result = new List<RulesEngineOutput>();
try
{
foreach (var item in bodyString)
{
var formattedItem = item.SelectToken("Result");
var resultItem = JsonConvert.DeserializeObject<RulesEngineOutput>(formattedItem.ToString());
result.Add(resultItem);
}
}
Hope it helps others as well.
As Nathan Werry said, you have an object layered into another object and because of that, you cannot deserialize the data in the way you want it. However, you can work around that if you first create an array of these results and assign it later to your ProbableRoles property:
var rules = new RulesEngineOutputCollection
{
ProbableRoles = JsonConvert.DeserializeObject<Result[]>(bodyString).Select(r => r.Data).ToList()
};
public class Result
{
[JsonProperty("Result")]
public RulesEngineOutput Data { get; set; }
}
Everything else stays the same. You basically create a new list out of your array of results. I could also assign the Select() result directly (without calling .ToList()) but this ensures that the object actually has the data and not just a reference to an enumeration.

ServiceStack.Text json deserialization creates wrong object instead of throwing on invalid json input string

When I try to deserialise this invalid json string ( }] missing in the end) :
[{"ExtId":"2","Name":"VIP sj�lland","Mobiles":["4533333333","4544444444"]
By doing this:
var result = JsonSerializer.DeserializeFromString<T>(str);
The ServiceStack json deserializer accepts the string, but it creates a wrong object, because I end up with a C# object having these values:
ExtId : "2" // ok fine.
Name: "VIP sj�lland" // ok fine
Mobiles: ["4533333333","4544444444", "544444444"]// Aarg! An array with 3 objects ?!?
// There were only two in the JSON string.
In this case it would be much better to have an exception thrown instead of continuing with bad data. Therefore I tried using:
JsConfig.ThrowOnDeserializationError = true;
just before calling DeserializeFromString but no exception was thrown. In January I asked this question Configure ServiceStack.Text to throw on invalid JSON and the answer was that ServiceStack is favoring resilence and that I could make a pull request in GitHub.
Is this still the case? And have anyone done it already, saving me the trouble? Otherwise, I am on a very tight schedule, so if anyone has some code or suggestions for how to create an option-flag for making ServiceStack throw on deserialization errors, please reply here, so that I can get this done faster.
This is resolved in ServiceStack.Text v4+ which by default doesn't populate incomplete collections, e.g:
public class Poco
{
public string ExtId { get; set; }
public string Name { get; set; }
public string[] Mobiles { get; set; }
}
var json = "[{\"ExtId\":\"2\",\"Name\":\"VIP sj�lland\",\"Mobiles\":[\"4533333333\",\"4544444444\"]";
var dto = json.FromJson<Poco[]>();
Assert.That(dto[0].ExtId, Is.EqualTo("2"));
Assert.That(dto[0].Name, Is.EqualTo("VIP sj�lland"));
Assert.That(dto[0].Mobiles, Is.Null);
Or if preferred can throw on Error:
JsConfig.ThrowOnDeserializationError = true;
Assert.Throws<SerializationException>(() =>
json.FromJson<Poco[]>());
C# is a little bit picky when it comes to JSON. Following would be valid! Note i do not have anonymous object array as the default element.
{
"ExtItem": [
{
"ExtId": "2",
"Name": "VIPsj�lland",
"Mobiles": [
"4533333333",
"4544444444"
]
}
]
}
If i generate a POCO from this I get
public class Rootobject
{
public Extitem[] ExtItem { get; set; }
}
public class Extitem
{
public string ExtId { get; set; }
public string Name { get; set; }
public string[] Mobiles { get; set; }
}
I personally use extension method to string
public static class Extensions
{
public static bool DeserializeJson<T>(this String str, out T item)
{
item = default(T);
try
{
item = new JavaScriptSerializer().Deserialize<T>(str);
return true;
}
catch (Exception ex)
{
return false;
}
}
}
This would enable me to write:
Rootobject ext;
const string validJson = #"
{
""ExtItem"": [
{
""ExtId"":""2"",
""Name"":""VIPsj�lland"",
""Mobiles"":[
""4533333333"",
""4544444444""
]
}
]
}";
if (validJson.DeserializeJson(out ext))
{ //valid input
// following would print 2 elements : 4533333333, 4544444444
Console.WriteLine(string.Join(", ", ext.ExtItem.First().Mobiles));
} //invalid input
I tried this an have the exception thrown when I missed the } at the end.
In C#, the format for JSON is {"name", "value"} not [{"name", "value"}].
class M
{
public string ExtId { get; set; }
public string Name { get; set; }
public List<string> Mobiles { get; set; }
}
string str = "{\"ExtId\":\"2\",\"Name\":\"VIP\",\"Mobiles\":[\"4533333333\",\"4544444444\"]";
M m = JsonConvert.DeserializeObject<M>(str);
When run this, you will get error as a } is missing.
Using:
string str = "{\"ExtId\":\"2\",\"Name\":\"VIP\",\"Mobiles\":[\"4533333333\",\"4544444444\"]}";
The object is deserialized fine.
You can see the JSON of this object from:
string s = JsonConvert.SerializeObject(m);
I just use the Newtonsoft.Json T JsonConvert.DeserializeObject<T>(string value) and it throws an exception;
If I use the object JsonConvert.DeserializeObject(string value) this one it creates the correct object by simply placing the missing }]
I found that this is a very reliable and fast library.

Categories

Resources