I want to deserilize this Json to Model, this is the
Json: [{"dimensions": [ "www "], "metrics ": [{ "values ": [ "2 " ]},{ "values ": [ "0 "]}]}]
and i create this model to deserialize json to this model:
public class ResultModel
{
public List<string> dimensions { get; set; }
public List<Metric> metrics { get; set; }
}
and
public class Metric
{
public List<string> values { get; set; }
}
and using Newtonsoft for this:
var model = Newtonsoft.Json.JsonConvert.DeserializeObject<ResultModel>(json);
but it doesnot work and give me this error:
'Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'ResultModel' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly'.
What is the problem?
It's easy to miss that your JSON is really array, even if it contains just one object. So you have to deserialize it to array:
var model = Newtonsoft.Json.JsonConvert.DeserializeObject<ResultModel[]>(json);
If you're sure that there will be at most one model, you can do:
var model = JsonConvert.DeserializeObject<IEnumerable<ResultModel>>(json).FirstOrDefault();
Otherwise, you should deserialize it to a collection of models, as suggested in the comments:
// models is an IEnumerable<ResultModel>
var models = JsonConvert.DeserializeObject<IEnumerable<ResultModel>>(json);
Related
I have a C# .Net Core Console Application thats supposed to check different Logfiles if these contain Errors and notifies the right person via Email. The Application has an appsetting.json that looks like this:
{
"Programs": [
{
"name": "program 1",
"LoggingPath": "C:\...",
"Emails": [
"person1#company.com",
"person2#company.com",
"person3#company.com"
]
},
{
"name": "program 2",
"LoggingPath": "C:\...",
"Emails": [
"person1#company.com",
"person2#company.com",
"person3#company.com"
]
}
]
}
Now i want to convert this Json into a C# Object List to iterate through the different Programs and do my Log analyzing etc.
I used https://json2csharp.com to convert the Json into this C# Code:
public class Program
{
public string name { get; set; }
public string LoggingPath { get; set; }
public List<string> Emails { get; set; }
}
public class Root
{
public List<Program> Programs { get; set; }
}
My code to initialize the appsettings.json and deserialization looks like this:
public static void Main(string[] args)
{
IConfiguration configuration;
configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
JToken JtokenConfig = Serialize(configuration);
Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(JtokenConfig.ToString());
}
But when I try this I get the following Error:
Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[LogAnalyzer.Model+Program]' 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.
I can't change the Json to an array (Without the "Programs":) cause the appsettings.json builder requires an object and not an array.
I have also tried to use this Json to get rid of the array and use a dynamic C# property to deserialize the different object names but the deserialization also failed.
{
"Programs": {
"program 1": {
"LoggingPath": "test",
"Emails": [
"person1#company.com",
"person2#company.com",
"person3#company.com"
]
},
"program 2": {
"LoggingPath": "test",
"Emails": [
"person1#company.com",
"person2#company.com",
"person3#company.com"
]
}
}
}
I read countless stackoverflow threads and other websites but wasnt able to convert the Json into a C# List.
I hope someone here can help me or give me a hint.
you can install Microsoft.Extensions.Configuration.Binder Nuget package and try this code
using Microsoft.Extensions.Configuration;
List<Program> programs = configuration.GetSection("Programs").Get<List<Program>>();
Update
the second json you can deserialize to a dictionary
Dictionary<string,Program> programsDict = configuration.GetSection("Programs")
.Get<Dictionary<string,Program>>();
This question already has answers here:
Converting JSON to Object fails - Cannot deserialize the current JSON object into System.Collections.Generic.List
(4 answers)
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1
(6 answers)
Cannot deserialize the current JSON object (e.g. {"name":"value"})
(6 answers)
JSON.Net - cannot deserialize the current json object (e.g. {"name":"value"}) into type 'system.collections.generic.list`1
(2 answers)
Closed 2 years ago.
This is my first time asking a question. I've been trying to get this working for too long. I've looked over some similar posts but just can't quite crack it.
I'm trying to make an API call in c# using flurl. I can make the call, but can't figure out how to store the data.
Here is an example of the response from the call made using powershell:
StatusCode : 200
StatusDescription : OK
Content : {
"result": [
{
"apiUserName": "admin#somedomain.com",
"apiPassword": "dk65dss5s5HH",
"id": "d38a1ea4-46d1-46b7-87a2-46c09da663eb",
"name": "catHotel",
"applUrl": "https://catshotel.somedomain.com/manager/",
"apiUrl": "https://catshotel.somedomain.com/API/",
"stateId": 2,
"databaseName": null,
"databaseServerName": null
},
{
"apiUserName": "admin#somedomain.com",
"apiPassword": "dhh7k33kDDh5g",
"id": "00d5e97b-5ea6-47dd-b920-8678f949c51f",
"name": "possumLodge",
"applUrl": "https://possumlodge.somedomain.com/manager/",
"apiUrl": "https://possumlodge.somedomain.com/API/",
"stateId": 1,
"databaseName": "customer-datab",
"databaseServerName": "customersDBserv.somedomain.com"
}
],
"targetUrl": null,
"success": true,
"error": null,
"unAuthorizedRequest": false,
"__abp": true
}
RawContent : HTTP/1.1 200 OK
Cache-Control: no-store, must-revalidate, no-cache, max-age=0
Request-Context: appId=cid-v1:8cgg58f2-5212-4685-b45f-149104d7a5be
Access-Control-Expose-Headers: Request-Context
X-Fr…
Headers : {[Cache-Control, System.String[]], [Request-Context, System.String[]], [Access-Control-Expose-Headers, System.String[]], [X-Frame-Options, System.String[]]…}
Images : {}
InputFields : {}
Links : {}
RawContentLength : 23638
RelationLink : {}
In c#, I've made a class: -
class Facilities
{
public string Name { get; set; }
}
And then I make the call: -
List<facilities> facilities = await url.WithHeaders(new { Accept = "Application/json", Authorization = token }).GetJsonAsync<List<facilities>>();
But I get errors such as:-
"Message "Cannot deserialize the current JSON object (e.g.
{"name":"value"}) into type
'System.Collections.Generic.List`1[ConsoleApp2.facilities]' because
the type requires a JSON array (e.g. [1,2,3]) to deserialize
correctly.\r\nTo 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.\r\nPath 'result', line 1, position
10." string"
I can't figure out how to store each 'facility' into an array of facilities :(
I'm Not an Expert here and Can't say i know about flurl, so i looked here https://jonathancrozier.com/blog/calling-all-apis-how-to-use-flurl-with-c-sharp
and looked into the error message and as the message say, your strongly-typed model need to match the Json object, so that the deserialization mechanism in flurl can deserialize the Json objects that match your strongly-typed model properties, meaning your class Facilities should look something like this.
class Facilities
{
public string apiUserName { get; set; }
public string apiPassword { get; set; }
public int id { get; set; }
public string name { get; set; }
public string applUrl { get; set; }
public string apiUrl { get; set; }
public int stateId { get; set; }
public string databaseName { get; set; }
public string databaseServerName { get; set; }
}
And try using
var facilities = await url.WithHeaders....
so you can figure out what can of object you are getting.
Note: I mimicked your request code using the Package Flurl.Http v2.4.2, with this code
using Flurl;
using Flurl.Http;
var token = "SomeToken1234";
Url url = "https://jsonplaceholder.typicode.com/todos";
List<Todo> todos = await url.WithHeaders(new { Accept = "application/json", Authorization = token }).GetJsonAsync<List<Todo>>();
this here work, you can test it, maybe it's something regard the version you use.
You can use a System.Dynamic namespace
Then deserialize it like so:
var responseContent = response.Content;
var responseString = responseContent.ReadAsStringAsync().Result;
dynamic projects = JArray.Parse(responseString) as JArray;
the controller action needs to return VIEW(project)
lastly, your View page needs to use #model dynamic
I want to convert json to a specific object.
String : "{\r\n \"Status\": \"PLANNED\"\r\n}"
I tried Newtonsoft Json namespace but it is returning a null value.
var Json= Newtonsoft.Json.JsonConvert.DeserializeObject<Model Class>(String )
I want the result in Json format so that I can extract the value from Json as "PLANNED" but I am getting a null.
PS :The model class contains two properties , Name (type of string), Value(type of Object)
var s = "{\r\n \"Status\": \"PLANNED\"\r\n}";
var obj = Newtonsoft.Json.JsonConvert.DeserializeObject<StatusModel>(s);
The model you have defined is incorrect.
Your model should be like this:
public class StatusModel
{
public string Status { get; set; }
}
Now value will be extracted to this model and you can access the value like:
var value = obj.Status; //"PLANNED"
JSON Definition
JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language.
[Source] https://www.json.org/
JSON Newtonsoft
Json.NET is a popular high-performance JSON framework for .NET .
[Source] https://www.newtonsoft.com/json
Problem :
Your are trying to deserialize a json to an object and it's returning a null.
In our context a Deserialization is process which transform a json to an object .
var Result= Newtonsoft.Json.JsonConvert.DeserializeObject<Model Class>(String);
The reason why you have a Null as result is beacause you are deserializing a json to Model, knowing that you Json does not correspond to the Model , this is why the Json need to correspond to the Model so that it can store the information of the Json.
Your Model :
The model may contain some property that are not in the json and vice versa
public class StatusModel
{
public string Status { get; set; }
}
Best Regards .
You can do it like this (using Newtonsoft Framework)
using System;
using Newtonsoft.Json;
{
public class JsonHandler : IJsonHandler
{
public IJsonModel ReadJson(IJsonModel model, StreamReader reader)
{
try
{
string jsonFromFile;
using (reader))
{
jsonFromFile = reader.ReadToEnd();
}
status = JsonConvert.DeserializeObject<model>(jsonFromFile);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
return status;
}
}
}
I'm using an API that among other things have these two responses:
{
"enrollDeviceErrorResponse": {
"errorCode": "GRX-1056",
"errorMessage": "DEP Reseller ID missing.
Enter a valid DEP Reseller ID and resubmit your request."
}
}
or
{
"enrollDeviceErrorResponse": [
{
"errorCode": "GRX-1056",
"errorMessage": "DEP Reseller ID missing.
Enter a valid DEP Reseller ID and resubmit your request."
},
{
"errorCode": "DEP-ERR-3003",
"errorMessage": "Order information missing. T
he transaction needs to have one or more valid orders.
Enter valid orders and resubmit your request."
},
{
"errorCode": "DEP-ERR-3001",
"errorMessage": "Transaction ID missing.
Enter a valid transaction ID and resubmit your request."
}
]
}
I've created some classes that can deserialize into these responses:
public class EnrollDeviceErrorRoot
{
public EnrollDeviceErrorRoot()
{
this.EnrollDeviceErrorResponse = new EnrollDeviceErrorResponse();
}
public EnrollDeviceErrorResponse EnrollDeviceErrorResponse { get; set; }
}
public class EnrollDeviceErrorRoot
{
public EnrollDeviceErrorRoot()
{
this.EnrollDeviceErrorResponse = new EnrollDeviceErrorResponse();
}
public EnrollDeviceErrorResponse EnrollDeviceErrorResponse { get; set; }
}
public class EnrollDeviceErrorResponse
{
public string ErrorCode { get; set; }
public string ErrorMessage { get; set; }
}
I am having a hard time coming up with a nice way to determine which one of my classes I should use depending on the response. I currently have this failing code:
var multipleErrors = JsonConvert.DeserializeObject<EnrollDeviceErrorsRoot>(response);
if (multipleErrors.EnrollDeviceErrorResponse != null && multipleErrors.EnrollDeviceErrorResponse.Any())
{
this.StatusCode = multipleErrors.EnrollDeviceErrorResponse.Select(x => x.ErrorCode).Aggregate((a, b) => a + ", " + b);
this.StatusMessage = multipleErrors.EnrollDeviceErrorResponse.Select(x => x.ErrorMessage).Aggregate((a, b) => a + Environment.NewLine + b);
this.HasErrors = true;
return;
}
var singleError = JsonConvert.DeserializeObject<EnrollDeviceErrorRoot>(response);
if (!string.IsNullOrEmpty(singleError.EnrollDeviceErrorResponse.ErrorCode))
{
this.StatusCode = singleError.EnrollDeviceErrorResponse.ErrorCode;
this.StatusMessage = singleError.EnrollDeviceErrorResponse.ErrorMessage;
this.HasErrors = true;
return;
}
Error from code above:
Newtonsoft.Json.JsonSerializationException : Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[Atea.Dep.Core.Service.Models.EnrollDeviceErrorResponse]'
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<T>) 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.
How are other people handling this deserializations from responses when they don't know what they are getting back from the server? I could of course just look at the raw response and determine that way but are there other cleaner ways to do this? I Can't change the API, I have no idea why there just couldn't be one response with a list with one or more errors.
You can use
JObject.Parse(response)["enrollDeviceErrorResponse"].Type
to determine the type of the response. In 1st case it will be obect, in 2nd - array. Then it will be easy to continue with proper deserialization.
You can use something like this:
var output;
dynamic jObject = JsonConvert.DeserializeObject (outputAPI);
bool isArray = jObj.enrollDeviceErrorResponse.Type == JTokenType.Array;
bool isObject = jObj.enrollDeviceErrorResponse.Type == JTokenType.Object;
if(isObject)
output = JsonConvert.DeserializeObject<EnrollDeviceErrorResponse>(outputAPI);
//else you will use the other class to deserialize the object
Does anyone know how to convert a string which contains json into a C# array. I have this which reads the text/json from a webBrowser and stores it into a string.
string docText = webBrowser1.Document.Body.InnerText;
Just need to somehow change that json string into an array. Been looking at Json.NET but I'm not sure if that's what I need, as I don't want to change an array into json; but the other way around. Thanks for the help!
just take the string and use the JavaScriptSerializer to deserialize it into a native object. For example, having this json:
string json = "[{Name:'John Simith',Age:35},{Name:'Pablo Perez',Age:34}]";
You'd need to create a C# class called, for example, Person defined as so:
public class Person
{
public int Age {get;set;}
public string Name {get;set;}
}
You can now deserialize the JSON string into an array of Person by doing:
JavaScriptSerializer js = new JavaScriptSerializer();
Person [] persons = js.Deserialize<Person[]>(json);
Here's a link to JavaScriptSerializer documentation.
Note: my code above was not tested but that's the idea Tested it. Unless you are doing something "exotic", you should be fine using the JavascriptSerializer.
using Newtonsoft.Json;
Install this class in package console
This class works fine in all .NET Versions, for example in my project: I have DNX 4.5.1 and DNX CORE 5.0 and everything works.
Firstly before JSON deserialization, you need to declare a class to read normally and store some data somewhere
This is my class:
public class ToDoItem
{
public string text { get; set; }
public string complete { get; set; }
public string delete { get; set; }
public string username { get; set; }
public string user_password { get; set; }
public string eventID { get; set; }
}
In HttpContent section where you requesting data by GET request
for example:
HttpContent content = response.Content;
string mycontent = await content.ReadAsStringAsync();
//deserialization in items
ToDoItem[] items = JsonConvert.DeserializeObject<ToDoItem[]>(mycontent);
Yes, Json.Net is what you need. You basically want to deserialize a Json string into an array of objects.
See their examples:
string myJsonString = #"{
"Name": "Apple",
"Expiry": "\/Date(1230375600000+1300)\/",
"Price": 3.99,
"Sizes": [
"Small",
"Medium",
"Large"
]
}";
// Deserializes the string into a Product object
Product myProduct = JsonConvert.DeserializeObject<Product>(myJsonString);
Old question but worth adding an answer if using .NET Core 3.0 or later. JSON serialization/deserialization is built into the framework (System.Text.Json), so you don't have to use third party libraries any more. Here's an example based off the top answer given by #Icarus
using System;
using System.Collections.Generic;
namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
var json = "[{\"Name\":\"John Smith\", \"Age\":35}, {\"Name\":\"Pablo Perez\", \"Age\":34}]";
// use the built in Json deserializer to convert the string to a list of Person objects
var people = System.Text.Json.JsonSerializer.Deserialize<List<Person>>(json);
foreach (var person in people)
{
Console.WriteLine(person.Name + " is " + person.Age + " years old.");
}
}
public class Person
{
public int Age { get; set; }
public string Name { get; set; }
}
}
}
One Situation that wasn't covered in the other responses is when you don't know the type of what the JSON object contains. That was my case as I needed to be able to NOT type it and leave it dynamic.
var objectWithFields = js.Deserialize<dynamic[]>(json);
Note: it is definitely preferred to have a type, in some cases, it is not possible, that's why I added this answer.