how to use JsonConvert.DeserializeObject for values without name [duplicate] - c#

This question already has answers here:
How can I parse a JSON string that would cause illegal C# identifiers?
(3 answers)
Deserialize deeply Nested Json having one blank key using c#
(1 answer)
Closed 1 year ago.
I have a json string like this:
{"status":false,"data":{"errors":{"":"error45"}}}
I cant make a class for this json string, because the last part has no name => ""
I test this class:
public class Result
{
public bool status { set; get; }
public ResultDetail data { set; get; }
}
public class ResultDetail
{
public ErrorDetails errors { set; get; }
}
public class ErrorDetails
{
public string abc { set; get; }
}
but abc returns null !!!!

You can use the Dictionary<string, string> for the errors.
public class Result
{
public bool status { set; get; }
public ResultDetail data { set; get; }
}
public class ResultDetail
{
public Dictionary<string, string> errors { set; get; }
}
and use the following to deserialize and access the dictionary.
var result = JsonConvert.DeserializeObject<Result>(json);
Console.WriteLine(result.data.errors.Values.FirstOrDefault());
Or you can assign the value to a variable
obj.data.errors.TryGetValue("", out string error);
Console.WriteLine(error);
I will mention this as well that the property names should be Proper names (first letter Capital). To be able to deserialize properly, use the [JsonProperty("corresponding_json_key")] to each of your properties of your classes to conform to C# standards.
public class Result
{
[JsonProperty("status")]
public bool Status { set; get; }
[JsonProperty("data")]
public ResultDetail Data { set; get; }
}

Related

How to cast a Json Object in strongly typed Data Model? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 3 years ago.
Improve this question
Thanks for your help, I am writing a web API (using dotnet core 3) that accepts network errors report :
{
"sampling_fraction": 1.0,
"server_ip": "192.0.2.1",
"protocol": "http/1.1",
"method": "GET",
"request_headers": {
"If-None-Match": ["01234abcd"]
},
"response_headers": {
"ETag": ["01234abcd"]
},
"status_code": 304,
"type": "ok"
}
And trying to get request_headers and response_headers as collections of strings with values coming from HeaderNames class. Roughly
class Data
{ ...
public string Method {get;set;}
public List<string> RequestHeaders {get;set;}
public List<string> ResponseHeaders {get;set;}
}
So far I have created a Model Class to Cast it:
public class ErrorBody
{
public double Sampling_Fraction { get; set; }
public string Server_Ip { get; set; }
public string Protocol { get; set; }
public string Method { get; set; }
public HttpRequestHeader Request_Headers { get; set; }
public HttpResponseHeaders Response_Headers { get; set; }
public int Status_Code { get; set; }
public string Type { get; set; }
}
From Json I am trying to cast "Request_Headers" and "Response_Headers" as a collection of Headers, like:
public HttpRequestHeader Request_Headers { get; set; }
public HttpResponseHeaders Response_Headers { get; set; }
unsing System.Net
But the casting fails with error:
"errors": {
"$.body.request_headers": [
"The JSON value could not be converted to System.Net.HttpRequestHeader. Path: $.body.request_headers | LineNumber: 9 | BytePositionInLine: 24."
]
}
My method looks like:
[HttpPost]
public IActionResult CreateReport(ErrorDto error)
{
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(error));
return Ok();
}
I am trying to cast both objects into a collection of HeaderName
This error is occurring because, as it states, it cannot deserialize the object to type System.Net.HttpRequestHeader. For one, System.Net.HttpRequestHeader is an enum. For two, the key If-None-Match has hyphens, and that can't be deserialized to a C# property because property names don't have hyphens. You would probably want to use a custom type instead.
However, I recommend using a Dictionary because, otherwise, your custom type would have to have a property for every possible header value. So change your Request_Headers and Response_Headers objects to type Dictionary<string, List<string>> and I think that'll take care of it.
If you were able to change data types on your header collections then you could do deserialise them as Dictionaries:
public class ErrorBody
{
public double Sampling_Fraction { get; set; }
public string Server_Ip { get; set; }
public string Protocol { get; set; }
public string Method { get; set; }
public Dictionary<string, List<string>> Request_Headers { get; set; } // change type here
public Dictionary<string, List<string>> Response_Headers { get; set; } // change type here
public int Status_Code { get; set; }
public string Type { get; set; }
}
void Main()
{
var str = "{\"sampling_fraction\":1,\"server_ip\":\"192.0.2.1\",\"protocol\":\"http\\/1.1\",\"method\":\"GET\",\"request_headers\":{\"If-None-Match\":[\"01234abcd\"]},\"response_headers\":{\"ETag\":[\"01234abcd\"]},\"status_code\":304,\"type\":\"ok\"}";
JsonConvert.DeserializeObject<ErrorBody>(str); // this gave me deserialised object
}

Deserialize multiple JSON records in C# [duplicate]

This question already has an answer here:
Deserializing JSON into an object
(1 answer)
Closed 5 years ago.
I have the following string of Json records:
{
"records":[
{
"PK":"1_1_8",
"ID":"8",
"DeviceID":"1",
"RootID":"1",
"CustName":"test1",
"CustSurname":"test2",
"Address":"Nisou 1",
"City":"",
"ZipCode":"",
"PhoneNumber":"45646",
"HomePhoneNumber":"",
"Email":"",
"Notes":"",
"Owner":"1",
"LanguageID":"1",
"LanguagePK":"",
"DeletedFlag":"false",
"created":"2017-10-25 10:15:00",
"modified":"2017-10-25 09:35:43"
},
{
"PK":"1_1_33",
"ID":"33",
"DeviceID":"1",
"RootID":"1",
"CustName":"",
"CustSurname":"",
"Address":"",
"City":"",
"ZipCode":"",
"PhoneNumber":"",
"HomePhoneNumber":"",
"Email":"",
"Notes":"",
"Owner":null,
"LanguageID":"0",
"LanguagePK":"",
"DeletedFlag":"true",
"created":"2017-10-25 10:13:54",
"modified":"2017-10-25 10:13:54"
},
{
"PK":"1_1_16",
"ID":"16",
"DeviceID":"1",
"RootID":"1",
"CustName":"Theodosis",
"CustSurname":"",
"Address":"Dali",
"City":"Nicosia",
"ZipCode":"2540",
"PhoneNumber":"45645",
"HomePhoneNumber":"99123456",
"Email":"theodosis#gmail.com",
"Notes":"",
"Owner":"",
"LanguageID":"1",
"LanguagePK":"",
"DeletedFlag":"false",
"created":"2017-10-25 09:36:22",
"modified":"2017-10-25 09:36:22"
}
]
}
I am using Xamarin PCL in C# trying to parse this string into a list of objects.
I have a Customer class:
public class Customer
{
[PrimaryKey]
public string PK { get; set; }
public int DeviceID { get; set; }
public int ID { get; set; }
public string RootID{ get; set; }
public string CustName { get; set; }
public string CustSurname { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string ZipCode { get; set; }
public string PhoneNumber { get; set; }
public string HomePhoneNumber { get; set; }
public string Email { get; set; }
public string Notes { get; set; }
public bool Owner { get; set; }
public int LanguageID { get; set; }
public string LanguagePK { get; set; }
public bool DeletedFlag { get; set; }
public DateTime created { get; set; }
public DateTime modified { get; set; }
}
I also tried out having a container class with a list of Customer objects.
public class DataContainer
{
public List<Customer> customers { get; set; }
}
I have seen quite a few of examples online on how to parse this into a list or any workable type but nothing seems to be working for me.
I have tried the following (JsonResults holds the string of Json records):
var observation = JsonConvert.DeserializeObject<DataContainer>(JsonResults);
From other posts, I am not able to access JavaScriptSerializer class from my code, perhaps because of the Xamarin PCL Framework I am using.
Any ideas would be very welcome, as I said I do not mind the format I parse the string into, as long as it's workable.
Thank you.
You would have to make the following changes to your code to make this work.
First and most importantly, you don't have a property customers, you have records, so either rename it
public class DataContainer {
public List<Customer> records { get; set; }
}
or add a JsonProperty attribute
[JsonProperty(PropertyName = "records")]
Secondly, your Owner is a bool in C# and a nullable int (int?) in Json. So either change it in your C# class
public int? Owner { get; set; }
or write a converter to do that (e.g. like here)
[JsonConverter(typeof(NullableIntToBooleanConverter))]
public bool Owner { get; set; }
Here is a working .NetFiddle
The JSON string you provided is a JSON object, which contains a single property called records. records property is a List<Customer>. You can not deserialize the given string directly into DataContainer class that you provided because the property names do not match.
In the Class that your provided it is called customers
public class DataContainer {
public List<Customer> customers { get; set; } //records
}
Or please have a look at the attribute for a bit of advanced mapping
[JsonProperty]
JSON you provided is of the form:
{"records":[{Customer},{Customer},{Customer}]}
But Owner property is "1", null or "". Therefore I would suggest redefining Owner as int? (nullable)
Your string shows one object with a property named records that contains a list of other objects. Your code is trying to deserialize this into an object that doesn't have such a property.
Furthermore, the string contains objects with a property Owner that may be missing or have a numeric value. It's definitely not a bool.
You'll have to change Owner to :
public int? Owner { get; set; }
To deserialize the string, you need an object with a records property:
public class DataContainer
{
public Customer[] records { get; set; }
}
var data=JsonConvert.DeserializeObject<DataContainer>(json);
Debug.Assert(data.records.Length == 3);

JsonConvert.DeserializeObject with folding [duplicate]

This question already has answers here:
Deserializing nested JSON structure to a flattened class with Json.NET using annotations
(3 answers)
Closed 6 years ago.
How can I specify folding?
Here's my json:
{
"result":
{
"code": "123",
"version": "1.2.3"
},
"error": null
}
And here's my class I want to deserialize:
public class Info
{
[JsonProperty("code")]
public string Code { get; set; }
[JsonProperty("version")]
public string Version { get; set; }
[JsonProperty("error")]
public string Error { get; set; }
}
Invoking like this:
var info = JsonConvert.DeserializeObject<Info>(json);
So, is there anyway I can specify, that code and version under result section? I believe I need to use JsonSerializeSettings or something like that.
If you are able to modify your class, then you could create a second class which contains your subproperties:
public class Info
{
[JsonProperty("result")]
public Result Result { get; set; }
[JsonProperty("error")]
public string Error { get; set; }
}
public class Result
{
[JsonProperty("code")]
public string Code { get; set; }
[JsonProperty("version")]
public string Version { get; set; }
}

How to Deserialize the json object in windows phone 8.1?

I want to bind json obect to my properties When I deserialize the json object and bind into the properties ,properties shows null values,please some one help me to resolve this.
this is my code
string s = "{\"response\":{\"status\":\"fail\",\"content\":{\"user_id\":\"56\",\"first\":\"kiran\",\"last\":\"kumar\",\"username\":\"kirankumar\"},\"msg\":\"shggh\"}}";
var jsonObj = JObject.Parse(s);
response myDeserializedObj = (response)Newtonsoft.Json.JsonConvert.DeserializeObject(jsonObj.ToString(), typeof(response));
this is properties
public class response
{
public string status { get; set; }
public content content { get; set; }
}
public class content
{
public string user_id { get; set; }
public string first { get; set; }
public string last { get; set; }
public string username { set; get; }
}
Thanks,
karthik
I copied you code and tested it in my machine and I could solve your problem
here is the solution
add the following class
public class ResponseWrapper
{
public response response { get; set; }
}
replace your code with the following
string s = "{\"response\":{\"status\":\"fail\",\"content\":{\"user_id\":\"56\",\"first\":\"kiran\",\"last\":\"kumar\",\"username\":\"kirankumar\"},\"msg\":\"shggh\"}}";
response my = JsonConvert.DeserializeObject<ResponseWrapper>(s).response;
I am sure this will work.
UPDATE
Another solution (Which is tested also) and better than the first one
because it is more clean, and in this way you have not to create new wrapper class.
the solution is replace your string with the following string.
and all of your previous code will stay the same
here is the correct JSON string
string s = "{\"status\":\"fail\",\"content\":{\"user_id\":\"56\",\"first\":\"kiran\",\"last\":\"kumar\",\"username\":\"kirankumar\"},\"msg\":\"shggh\"}";
UPDATE 2
in the comments below of this answer you asked a completely a new question.
here is your new question (I copied this from your comments)
public class responseWraper
{
public response response { get; set; }
}
public class response
{
public string status { get; set; }
public content content { get; set; }
}
public class content
{
public Employees Employees { get; set; }
}
public class Employees
{
public string Employee_id { get; set; }
public string Employee_name { get; set; }
public string status { get; set; }
}
and here is how you are trying to deserialize this (also this copied from your comments)
string s = "{\"response\":{\"status\":\"success\",\"content\":{\"Employees\":[{\"Employee_i‌​d\":\"1\",\"Employee_name\":\"Sravan\",\"status\":\"1\"},}]}}}";
response my = Newtonsoft.Json.JsonConvert.DeserializeObject<responseWraper>(s).response;
ANSWER
your code has two problem
the first is you are using the Employees as array in the JSON string, but the type of the Employees property is not an array
the second problem that the JSON string itself is not valid. it has an errors
there is 4 { character but you have 5 } character inside it.
so you have to fix those two problem as the following
public class content
{
public List<Employees> Employees { get; set; }
}
and the string is
string s = "{\"response\":{\"status\":\"success\",\"content\":{\"Employees\":[{\"Employee_id\":\"1\",\"Employee_name\":\"Sravan\",\"status\":\"1\"},]}}}";
and if you have any other question , I will be happy to help you :)
Try your JSON with http://json2csharp.com/.
Your current code would deserialize the following JSON:
{
"status":"fail",
"content":{
"user_id":"56",
"first":"kiran",
"last":"kumar",
"username":"kirankumar"
},
"msg":"shggh"
}
You are missing a root class with a single Property "response" with the type "Response"

Deserialize JSON with variable name arrays

I am getting JSON that is being returned from a REST web service for survey responses. It has arrays for the name portion of some of the name value pairs. Additionally the names will be variable depending on the type of questions asked. I'm using JSON.net and trying to deserialize the returned value into some type of object tree that I can walk but can't figure out what structure to use to have it filled in.
I tested the following snippet in LinqPad and fields is always empty. Is there someway to easily read in the variable data or do I have to parse it in code?
void Main() {
string json = #"{
'result_ok':true,
'total_count':'51',
'data':[{
'id':'1',
'status':'Deleted',
'datesubmitted':'2015-01-12 10:43:47',
'[question(3)]':'Red',
'[question(4)]':'Blue',
'[question(18)]':12,
'[variable(\'STANDARD_IP\')]':'127.0.0.1',
'[variable(\'STANDARD_GEOCOUNTRY\')]':'United States'
}]
}";
var responses = JsonConvert.DeserializeObject<RootObject>(json);
responses.Dump();
}
public class RootObject {
public bool result_ok { get; set; }
public string total_count { get; set; }
public List<Response> data { get; set; }
}
public class Response {
public string id { get; set; }
public string status { get; set; }
public string datesubmitted { get; set; }
public List<object> fields = new List<object>();
}
Change the fields property in your Response class to be a Dictionary<string, object>, then mark it with a [JsonExtensionData] attribute like this:
public class Response
{
public string id { get; set; }
public string status { get; set; }
public string datesubmitted { get; set; }
[JsonExtensionData]
public Dictionary<string, object> fields { get; set; }
}
All of the fields with the strange property names will then be placed into the dictionary where you can access them as normal. No extra code is required.
Here is a demo: https://dotnetfiddle.net/1rQUXT

Categories