Can't deserialize json properly - c#

I have this json:
[{"trace":{"details":{"date":"[28-02-2016 11:04:26.856573]","type":"[info]","message":"[system done.]"},"context":{"context":[[{"ID":"john dillinger"}]]}}},{"trace":{"details":{"date":"[28-02-2016 11:04:26.856728]","type":"[info]","message":"[trace done.]"},"context":{"context":[[{"ID":"john dillinger"}]]}}}]
Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type, because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
I've created this class for deserialize it:
public class Testing
{
public string date { get; set; }
public string type { get; set; }
public string message { get; set; }
public string context { get; set; }
}
and this is the code for deserialize the content:
string responseText = "json above";
var obj = JsonConvert.DeserializeObject<Testing>(responseText); //on this line the problem
in the obj line I get the exception. I'm a bit rusty with c# so I don't know exactly what am I doing wrong. Someone could enlighten me?

Your json is not a flat data as your Testing class is. Try using following
public class Details
{
public string date { get; set; }
public string type { get; set; }
public string message { get; set; }
}
public class Context
{
public List<List<ContextElement>> context { get; set; }
}
public class Trace
{
public Details details { get; set; }
public Context context { get; set; }
}
public class RootObject
{
public Trace trace { get; set; }
}
Just hit your json to http://json2csharp.com/ and it seems you need to add this type for the ID part of the context and modify the result so context uses this in the list.
public class ContextElement
{
public string ID { get; set; }
}
Your parsed json is of format
Check this with https://jsonformatter.curiousconcept.com/ yourself. Then you just need to make a C# classes to match that structure.

You need to deserialize a collection of Trace - like List<Trace>:
var obj = JsonConvert.DeserializeObject<List<Trace>>(responseText);
Assuming that you have the following DTOs:
public class Trace
{
public TraceValue trace;
}
public class TraceValue
{
public Details details;
public Context context;
}
public class Details
{
public String date;
public String type;
public String message;
}
public class Context
{
public List<List<IdItem>> context;
}
public class IdItem
{
public String ID;
}
Proof (response is just a line provided by you, but with escaped quotes, so that it can be put directly into the code):
var response =
"[{ \"trace\":{ \"details\":{ \"date\":\"[28-02-2016 11:04:26.856573]\",\"type\":\"[info]\",\"message\":\"[system done.]\"},\"context\":{ \"context\":[[{\"ID\":\"john dillinger\"}]]}}},{\"trace\":{\"details\":{\"date\":\"[28-02-2016 11:04:26.856728]\",\"type\":\"[info]\",\"message\":\"[trace done.]\"},\"context\":{\"context\":[[{\"ID\":\"john dillinger\"}]]}}}]";
var obj = JsonConvert.DeserializeObject<List<Trace>>(response);

I think you should use JavaScripSerializer
JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
you can try
var obj = jsSerializer.Deserialize<Testing>(responseText);
I am not sure about this solution, may be it will work or not in your case.
But you can deserialize json string into string array of any dimension as:
var obj = jsSerializer.Deserialize<string[]>(responseText);
var obj = jsSerializer.Deserialize<string[][]>(responseText);

Related

C# Web Api - NUnit Testing - Newtonsoft.Json.JsonSerializationException

I need to deserialize the following JSON string.
{"status":"success","data":[{"id":4,"domainTitle":"Java","isDeleted":true},{"id":5,"domainTitle":"PHP","isDeleted":true},{"id":6,"domainTitle":"Angular","isDeleted":true}]}
The test code for the same is:
[Test]
public async Task TestGetDeletedDomainsAsync_UserDomains_StatusCodeOK()
{
using (var adminController = new AdminController(_adminService.Object))
{
//act
var response = _adminController.GetDeletedDomainsAsync();
var successStatus = await response.Content.ReadAsAsync<SuccessStatus>();
var returnData = JsonConvert.DeserializeObject<List<Domain>>(successStatus.Data.ToString());
// assert
Assert.Multiple(() =>
{
Assert.That(response, Is.TypeOf<HttpResponseMessage>());
Assert.That(returnData, Is.TypeOf<List<Domain>>());
Assert.AreEqual(response.StatusCode, HttpStatusCode.OK);
Assert.IsNotNull(successStatus);
Assert.AreEqual("success", successStatus.Status);
Assert.IsNotNull(returnData);
//checking if same object goes to service and also if that service is called once
_adminService.Verify(s => s.GetDeletedDomains(), Times.Once);
});
}
}
But when I try using the de-serializer, it gives an exception.
Newtonsoft.Json.JsonSerializationException : Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[IMS_NL.Models.Domain]' 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.
The line that displays the above error is --
var returnData = JsonConvert.DeserializeObject<List<Domain>>(successStatus.Data.ToString());
Help me with a solution. Thanks in advance.
You need to make a class which correspond your JSON string
public class Answer
{
public string Status { get; set; }
public List<Domain> Data { get; set; }
}
public class Domain
{
public int Id { get; set; }
public string DomainTitle { get; set; }
public bool IsDeleted { get; set; }
}
Then use
var returnData = JsonConvert.DeserializeObject<Answer>(successStatus.Data.ToString());
I think that your problem resides in the declaration of Domain class. You should define the below classes, according to the JSON you have posted:
public class Domain
{
public int id { get; set; }
public string domainTitle { get; set; }
public bool isDeleted { get; set; }
}
public class Result
{
public string status { get; set; }
public List<Domain> data { get; set; }
}
var returnData = JsonConvert.DeserializeObject<Result>(...);
You should replace the ... with the JSON you get from that you call.
Optionally, you could rename the above classes as you think that would be more suitable.

One or more errors occurred. (Cannot deserialize the current JSON object (e.g))

Trying to deserialize an array of book objects from the GoogleBook API.
Models: https://pastebin.com/24S16hZc
Confirmed API respons: https://pastebin.com/2q0aFGnf
Booking Page:
public BookingPage()
{
this.InitializeComponent();
ResizeWindow();
UpdateListView();
}
private void UpdateListView()
{
UserList_List.Items.Clear();
foreach (HelperLibrary.UserObject L in App.GlobalUserList)
{
UserList_List.Items.Add($" { L.FirstName } { L.LastName }");
}
//Prepare task
Task<HelperLibrary.Models.GoogleBook.RootObject[] > GetBooksTask = HelperLibrary.Helpers.APIHelper.SearchBooks("Hacker");
GetBooksTask.Wait();
HelperLibrary.Models.GoogleBook.RootObject[] Books = GetBooksTask.Result;
foreach(HelperLibrary.Models.GoogleBook.RootObject P in Books)
{
BookList_list.Items.Add(P.volumeInfo.title);
}
}
API Helper task
public class APIHelper
{
private static string BaseURL = "https://www.googleapis.com/books/v1/volumes";
public static async Task<HelperLibrary.Models.GoogleBook.RootObject[] > SearchBooks(string term)
{
using (var WebClient = new HttpClient { BaseAddress = new Uri(BaseURL) })
{
var ResponseHandler = WebClient.GetAsync($"?q= { term } ");
if (ResponseHandler.Result.IsSuccessStatusCode)
{
string x = await ResponseHandler.Result.Content.ReadAsStringAsync();
Debug.WriteLine(x);
Models.GoogleBook.RootObject[] items = JsonConvert.DeserializeObject<Models.GoogleBook.RootObject[]>(await ResponseHandler.Result.Content.ReadAsStringAsync());
return items;
}
else
{
return null;
}
}
}
}
Full error:
JsonSerializationException: Cannot deserialize the current JSON object
(e.g. {"name":"value"}) into type
'System.Collections.Generic.List`1[HelperLibrary.Models.GoogleBook+RootObject]'
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 'kind', line 2, position 8.
I'm already trying to declare it to an array, not a List?
Been trough most other threads about this, can't seem to find a situation similar to mine.
You seem to have misunderstood what is the RootObject. What you have defined as such is actually the inner object inside your RootObject.
I suggest you do this;
1) Rename your RootObject to Item
public class Item
{
public string kind { get; set; }
public string id { get; set; }
public string etag { get; set; }
public string selfLink { get; set; }
public VolumeInfo volumeInfo { get; set; }
public LayerInfo layerInfo { get; set; }
public SaleInfo saleInfo { get; set; }
public AccessInfo accessInfo { get; set; }
}
2) Create a new RootObject
public class RootObject
{
public string kind { get; set; }
public int totalItems { get; set; }
public List<Item> items { get; set; }
}
Then your Deserialize should look like this;
Models.GoogleBook.RootObject root =
JsonConvert.DeserializeObject<Models.GoogleBook.RootObject>(await ResponseHandler.Result.Content.ReadAsStringAsync());
Checking the structure of the json, i think what you are trying to get is the item array of the json if i am not mistaken. What you can do is Try to create a parent class containing the array Root Object something like this:
Public class RootParent
{
public string kind {get; set;}
public int totalItems {get;set;}
public List<RootObject> items {get; set;}
}

How Can I Deserialize JSON Data Using C#?

I have seen some other questions like this, but those are quite complex JSON data's that have objects within objects. Although the JSON I'm working with is never static, I doubt it's as complex as those. Also, it's my first time using JSON with C# so I'm a little clueless.
What I'm trying to achieve is to separate the data that is received from an API that I prompt using WebRequest in C#.
{
"johhny.debt": {
"id":35187540,
"name":"johnny.debt",
"profileIconId":786,
"Level":30,
"revisionDate":1428019045000
}
}
The returned JSON data is in a fashion like thereof.
I want to be able to access all of the properties of the above string in the following manner:
ID :
Name:
~~
~~
~~
... and so forth.
I'm assuming some type of class has to be made for this?
All help is appreciated, thank you all in advance.
Install Json.Net from Nuget
Install-Package Newtonsoft.Json
https://www.nuget.org/packages/Newtonsoft.Json/
Declare class for inner object ({"id":..., "name": ... }):
public class InnerObject
{
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("name")]
public string Username { get; set; }
[JsonProperty("profileIconId")]
public int ProfileIconId { get; set; }
[JsonProperty("level")]
public int Level { get; set; }
[JsonProperty("revisionDate")]
public string RevisionDate { get; set; }
}
As you can see you can specify rename mapping from json fields to .Net object properties using JsonPropertyAttribute.
Read your json to Dictionary<string,InnerObject> and get value of "johhny.debt" key:
var dict = JsonConvert.DeserializeObject<Dictionary<string, InnerObject>>(jsonText);
var johhny = dict["johhny.debt"];
Or if your need always to parse exact json property 'johhny.debt', you could create root object class:
public class RootObject
{
[JsonProperty("johhny.debt")]
public InnerObject JohhnyDept { get; set; }
}
And deserialize it:
var root = JsonConvert.DeserializeObject<RootObject>(jsonText);
var johhny = root.JohhnyDebt;
Just Create a class like this
public class RootObject
{
public int Id { get; set; }
public string name { get; set; }
public int profileIconId { get; set; }
public int Level { get; set; }
public string revisionDate { get; set; }
}
then install json.Net and this code to your main method
var jsonObject=JsonConvert.DeserializeObject<RootObject>(jsonText);
That's all
Update
var obj = JObject.Parse(json);
var RootObject = new RootObject()
{
Id = (int)obj["johhny.debt"]["id"],
Level = (int)obj["johhny.debt"]["Level"],
name = (string)obj["johhny.debt"]["name"],
profileIconId = (int)obj["johhny.debt"]["profileIconId"],
revisionDate = (string)obj["johhny.debt"]["revisionDate"]
};

JSON Deserialize Error: Parameter cannot be null

Couldn't find an answer from the other Json Serialization issue questions, so maybe someone can help me:
I'm getting a JSON object from a REST api and attempting to Deserialize it to an object. Below is the JSON Object I receive:
{"id":"6wVcZ9ZF67ECUQ8xuIjFT2",
"userId":"83ca0ab5-3b7c-48fe-8019-000320081b00",
"authorizations":["employee","API","trainer","queueAdmin","supervisor","workflowAdmin","realtimeManager","forecastAnalyst","qualityEvaluator","contactCenterManager","teamLead","personnelAdmin","telephonyAdmin","qualityAdmin","businessAdmin","businessUser","accountAdmin","dialerAdmin","contentManagementUser","contentManagementAdmin","admin","api","scriptDesigner","agent","user"],
"primaryAuthorization":"employee",
"thirdPartyOrgName":"in",
"username":"somebody",
"selfUri":"https://blahblahblah.com/api/v1/auth/sessions/6wVcZ9ZF67ECUQ8xuIjFT2"}
And my object I'm attempting to DeSerialize to:
[Serializable]
public class Session : BaseRequest, ISession
{
public Session(string url) : base(url)
{
}
#region Members
[JsonProperty(PropertyName = "userId")]
public string UserId { get; set; }
[JsonProperty(PropertyName = "authorizations")]
public object[] Authorizations { get; set; }
[JsonProperty(PropertyName = "primaryAuthorization")]
public string PrimaryAuthorization { get; set; }
[JsonProperty(PropertyName = "thirdPartyOrgName")]
public string ThirdPartyOrgName { get; set; }
[JsonProperty(PropertyName = "username")]
public string Username { get; set; }
[JsonProperty(PropertyName = "id")]
public string Id { get; set; }
[JsonProperty(PropertyName = "selfUri")]
public string SelfUri { get; set; }
#endregion
}
I simply make the web request and get the response stream using a stream reader and return the string. Pretty standard.
However, when I attempt to Deserialize into my Session object it always throws an error: Value Cannot be Null
var serializer = new JsonSerializer();
response = MakePostRequest(true);
var obj = serializer.Deserialize<Session>(new JsonTextReader(new StringReader(response)));
The response is the JSON string I get back from the web request and is exact to what I specified above.
I've done this before but normally I've been the one that designed the REST api. Not the case this time but I can't for the life of my figure out why this won't deserialize? I've specified the JSonProperty PropertyName to avoid issues with proper casing, is this not working right maybe? Any help is appreciated!
UDPATE
I think I found part of the problem. It is attempting to deserialize my base class which consists of :
public abstract class BaseRequest
{
protected BaseRequest(string apiUrl)
{
ApiUrl = apiUrl;
Request = (HttpWebRequest)WebRequest.Create(apiUrl);
}
public string ApiUrl { get; set; }
public string JsonPayload { get; set; }
public HttpWebRequest Request { get; private set; }
}
Is there any directive I can give to prevent it from doing so? Or will I need to refactor around this?
Below code works (using Json.Net):
var session = JsonConvert.DeserializeObject<Session>(json);
public class Session
{
public string Id { get; set; }
public string UserId { get; set; }
public List<string> Authorizations { get; set; }
public string PrimaryAuthorization { get; set; }
public string ThirdPartyOrgName { get; set; }
public string Username { get; set; }
public string SelfUri { get; set; }
}
EDIT
How should I tell it to ignore the base class?
var session = (Session)System.Runtime.Serialization.FormatterServices.GetSafeUninitializedObject(typeof(Session));
JsonConvert.PopulateObject(DATA, session);
But I don't think this is a nice way of doing it. Changing your design may be a better solution.
I've tested your code and it works fine, only change I made was removing the constructor, I take it that the serializer can't create an instance on the object for some reason, can you remove
public Session(string url) : base(url)
{
}
Your code works just fine for me but I haven't the BaseRequest source code so I made class with empty constructor.
IMO the exception is coming exactly from there. In the Session constructor the url parameter is null because your JSON object doesn't have url property. May be in the BaseRequest class you use this url param and you receive the Value Can't be Null error.
You can change just the name of parameter if this is the issue:
public Session(string selfUri ) : base(selfUri)
{
}
Check also if the 'response' variable is null. StringReader can throw this exception if you pass null to its constructor.

How to parse JSON object in C#

I am getting following JSON data
[{"id":"1","text":"System Admin","target":{"jQuery1710835279177001846":12},"checked":true,"state":"open"},
{"id":"2","text":"HRMS","target":{"jQuery1710835279177001846":34},"checked":false,"state":"open"},
{"id":"3","text":"SDBMS","target":{"jQuery1710835279177001846":42},"checked":false},
{"id":"8","text":"Admin","target":{"jQuery1710835279177001846":43},"checked":false},
{"id":"9","text":"My test Admin","target":{"jQuery1710835279177001846":44},"checked":false,"state":"open"},
{"id":"24","text":"ModuleName","target":{"jQuery1710835279177001846":46},"checked":false,"state":"open"}]
which try to parsed using Json.Net using strongly type
this are my property class
public class testclass
{
public string id { get; set; }
public string text { get; set; }
public string #checked { get; set; }
public string state { get; set; }
public target jQuery1710835279177001846 { get; set; }
}
public class testclass2
{
public List<testclass> testclass1 { get; set; }
}
public class target
{
public string jQuery1710835279177001846 { get; set; }
}
and here i am trying to access the data i am getting exception
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'QuexstERP.Web.UI.Areas.SysAdmin.Controllers.testclass' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
My controller code look like
public void Test(string Name, object modeldata)
{
var obj = JsonConvert.DeserializeObject<testclass>(Name);
}
Any idea how to solve this issue in C#
Your Json string looks to have serialized array object in it because it contains [ ]. It means you have a Json string which is formed after serialization of array object. So you need to deserialized into array object, so try this
var obj = JsonConvert.DeserializeObject<List<testclass>>(jsonString);
you have Array of TestClass. so it should be like this.
var model= JsonConvert.DeserializeObject<List<testclass>>(Name);
why you are using JSonConvert ? in MVC3 you can do like this
return Json(yourmodel,JsonRequestBehavior.AllowGet);
Your json objects are like this
{
"id":"1",
"text":"System Admin",
"target":{
"jQuery1710835279177001846":12
},
"checked":true,
"state":"open"
}
It should be like this I guess
{
"id":"1",
"text":"System Admin",
"jQuery1710835279177001846":12,
"checked":true,
"state":"open"
}

Categories

Resources