Deserializing JSON with indexed array in c# - c#

I'm very new to working with JSON and am dealing wtih a return from an API which I can't change the formatting of. The return example is : (actual urls have been removed)
{
"body":
{
"link":
{"linkurl": ["www.google.com"]}
},
"error": null,
"message": "Data Retrieved successfully",
"status": true
}
I am using the Newtonsoft.Json library with MVC 3, in VS2010.
My class is:
[JsonObject(MemberSerialization.OptIn)]
public class LinksJSON
{
[JsonProperty]
public string link{ get; set; }
[JsonProperty]
public string message { get; set; }
[JsonProperty]
public string error { get; set; }
[JsonProperty]
public bool status { get; set; }
}
I'm deserializing it with :
private static T _download_serialized_json_data<T>(string url) where T : new()
{
using (var w = new WebClient())
{
var json_data = string.Empty;
// attempt to download JSON data as a string
try
{
json_data = w.DownloadString(url);
}
catch (Exception) { }
// if string with JSON data is not empty, deserialize it to class and return its instance
return !string.IsNullOrEmpty(json_data) ? JsonConvert.DeserializeObject<T>(json_data) : new T();
}
}
public string CheckJSONLink()
{
var url = "<api url-removed for security>";
var outObj = _download_serialized_json_data<LinksJSON>(url);
return outObj.Link;
}
However I'm trying to get the value of linkurl, which is an indexed array within Link.
How would I access this information?

You did not setup your class to match the JSON, your class says that link is a simple string, you your example shows it as a complex type.
In order to properly deserialize it as you expect, you will have to modify your class to match the JSON. Specifically link should be an instance of a class.

You should use the following classes:
[JsonObject(MemberSerialization.OptIn)]
public class LinksJSON
{
[JsonProperty]
public body body { get; set; }
[JsonProperty]
public string message { get; set; }
[JsonProperty]
public string error { get; set; }
[JsonProperty]
public bool status { get; set; }
}
[JsonObject(MemberSerialization.OptIn)]
public class body
{
[JsonProperty]
public link link { get; set; }
}
[JsonObject(MemberSerialization.OptIn)]
public class link
{
[JsonProperty]
public string[] linkurl { get; set; }
}

Related

Custom JSON Serialize with custom mapping C#

I want to serialize/deserialize the following JSON:
{
"result": {
"ID": 1,
"TITLE": "Example",
"ARRAY": [
{
"Item1": "Result1",
"Item2": "Result2"
}
]
}
}
I tried with the following class format, but no sucess yet... Can someone help me deserialize it?
public class myClass
{
public string ID { get; set; }
[JsonProperty("TITLE")]
public string Name { get; set; }
}
obs.: Using the namespace Newtonsoft.JSON
In your example class definition above, you have called the class myClass but you would have had to call it result because ID and TITLE are members of the result JSON in the given example. myClass would not resolve to anything.
I don't know why you'd want to have a property called Name that is mapped to TITLE, but ok, if you want to do that you can modify the solution after you get it working.
Still, we're not done yet. You also have a JSON member called ARRAY and you need to define a separate class for that.
And still there is an additional problem: the result JSON is nested inside an implicit base object, so we need to define that as well. Let's call it BaseResult.
public class ARRAY
{
public string Item1 { get; set; }
public string Item2 { get; set; }
}
public class Result
{
public int ID { get; set; }
public string TITLE { get; set; }
public List<ARRAY> ARRAY { get; set; }
}
public class BaseResult
{
public Result result { get; set; }
}
If you are using Visual Studio, you can copy your JSON and paste it in any *.cs file with Edit > Paste Special > Paste JSON as Classes. It will generate POCO objects representing your JSON, which in your case will be this:
public class Rootobject
{
public Result result { get; set; }
}
public class Result
{
public int ID { get; set; }
public string TITLE { get; set; }
public ARRAY[] ARRAY { get; set; }
}
public class ARRAY
{
public string Item1 { get; set; }
public string Item2 { get; set; }
}
Then, asuming that you have your JSON in a string variable named data, you can deserialize it as follows:
var result= JsonConvert.DeserializeObject<Rootobject>(data);

C# Entity Framework Json deserialize String array issues

I have A Json file Which can be used for deserialize to Entity framework. For simplify we can assume the Json like this
{
"stat": "val0",
"results": [
{
"datasets": [
"val1",
"val2"
],
"head": "val3"
},
{
"datasets": [
"val4",
"val5"
],
"head": "val6"
}
]
}
And my Entity Classes like
[Serializable]
public class Root
{
[Key]
public int Id { get; set; }
public int stat { get; set; }
public List<Result> results { get; set; }
}
[Serializable]
public class Result
{
[Key]
public int Id { get; set; }
public List<String> _strings { get; set; }
public List<string> Strings
{
get { return _strings; }
set { _strings = value; }
}
[Required]
public string datasets
{
get { return String.Join(",", _strings); }
set { _strings = value.Split(',').ToList(); }
}
public string head{ get; set; }
public virtual root { get; set; }
}
I know Entity Framework does not support primitive types and I know problem causes from my datasets fields. that I found this way to solve String array deserialize issue here. I have tried
URL = "http://...";//Restful webservice address
WebClient client = new WebClient();
String JSON= client.DownloadString(URL);
var dsobj = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<RootObject>(json);
But I got
System.InvalidOperationException
Then I have decided to use Newtonsoft
URL = "http://...";//Restful webservice address
WebClient client = new WebClient();
String JSON= client.DownloadString(URL);
var dsobj = JsonConvert.DeserializeObject<Root>(json);
Then I got this error
Newtonsoft.Json.JsonReaderException: 'Unexpected character encountered while parsing value: [. Path 'results[0].senses[0].definition', line 1, position...
I found this but I cant figure it out.
How can Fix these isseus. Any help appreciated.
Your json consist of two unwanted commas, try removing those
try
[Serializable]
public class Root
{
[Key]
public int Id { get; set; }
public string stat { get; set; } // changed to a string
public List<Result> results { get; set; }
}
[Serializable]
public class Result
{
[Key]
public int Id { get; set; }
public List<String> _dataSets { get; set; }
public List<string> dataSets // the JSON array will deserialize into this property
{
get { return _dataSets; }
set { _dataSets = value; }
}
[Required]
public string DatasetsAsString
{
get { return String.Join(",", _dataSets); }
set { _dataSets = value.Split(',').ToList(); }
}
public string head{ get; set; }
public virtual root { get; set; }
}
Edit: stat property has to be a string too.

Json.NET failes to deserialize Json to a field-only class

I want to parse a piece of JSON with Newtonsoft Json.NET
JSON:
{
"USER":{
"result_id":"0",
"result_description":"NET Connections",
"cmlog_username":[
"8118236834",
"8118236834",
"8118236834"
],
"caller_id":[
"14cc20f7b05f",
"14cc20f7b05f",
"14cc20f7b05f"
]
}
}
Class
public class USER
{
public string result_id;
public string result_description;
public string[] cmlog_username;
public string[] caller_id;
}//USER
I convert it with below code but all of property value is NULL
USER con = JsonConvert.DeserializeObject<USER>(msg);
Your deserialization class is incorrect. Putting your JSON into json2csharp.com produces:
public class USER
{
public string result_id { get; set; }
public string result_description { get; set; }
public List<string> cmlog_username { get; set; }
public List<string> caller_id { get; set; }
}
public class RootObject
{
public USER USER { get; set; }
}
So you would need to do:
User con = JsonConvert.DeserializeObject<RootObject>(msg);
Your JSON object isn't a USER, it's an object that contains a USER.
It's because the JSON object you are trying to parse into a user is an object that has a property of 'user' that is a user object. That probably didn't make much sense. You could change your json to be
{
"result_id":"0",
"result_description":"NET Connections",
"cmlog_username":[
"8118236834",
"8118236834",
"8118236834"
],
"caller_id":[
"14cc20f7b05f",
"14cc20f7b05f",
"14cc20f7b05f"
]
}
and it will work.
Try adding the get and set to your class
public class USER
{
public string result_id { get; set; }
public string result_description { get; set; }
public string[] cmlog_username { get; set; }
public string[] caller_id { get; set; }
}//USER

Create a JSON string in C#

I'm trying to create an object to be returned as JSON for my REST Web Service.
I wish to get something returned like this:
{
"message": [
{
"name": "whatever.bmp"
}
],
"errors": null,
"FileInflected": 0,
"path": "C:\thepath"
}
So, how can I change the class (eFileOutput) in C#?
How can I change the class I have below?
Currently I'm able to create similar output like this:
{
"message": "Hello World",
"errors": null,
"FileInfected": 0,
"path": "C:\bla bla..."
}
and my C# class is as follows:
[DataContract]
public class eFileOutput
{
[DataMember]
public string message { get; set; }
[DataMember]
public string errors { get; set; }
[DataMember]
public Int32 FileInfected { get; set; }
[DataMember]
public string path { get; set; }
}
Tks
This is the classes that represent the JSON you've stated:
public class Message
{
public string name { get; set; }
}
public class MyObject
{
public List<Message> message { get; set; }
public object errors { get; set; }
public int FileInflected { get; set; }
public string path { get; set; }
}
var json = Newtonsoft.Json.JsonConvert.SerializeObject(new MyObject
{
message = new List<Message>
{
new Message {name = "whatever.bmp"}
},
FileInflected = 0,
path = #"c:\thepath"
});
Edit (thanks to devzero): Then you can serialize using Newtonsoft (my favorite) or JavaScriptSerializer as stated here: Turn C# object into a JSON string in .NET 4
public class MyObject
{
public Message Message { get; set; }
public List<Error> Errors { get; set; }
public int FileInflected { get; set; }
public string Path { get; set; }
}
public class Message
{
public string Name { get; set; }
}
public class Error
{
//Whatever you want
}
and if You want to serialize member as camelCase, describe like this:
var jsonSerializerSettings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() };
var json = JsonConvert.SerializeObject(c, jsonSerializerSettings);

JavaScriptSerializer deserialize multiple JSON arrays in single string

In short, I have a client Windows Forms app that receives a Json string from an API in the following form:
string textResult = "{"Data":[{"ID":"G0000013","M_CurBalanceOutstanding":52408.5}],"DataDetail":[{"ErrorDate":"\/Date(1410179960809+0200)\/","ErrorID":1,"ErrorInfo":"Success"}]}"
or formatted via http://www.jsoneditoronline.org/
{
"Data": [
{
"ID": "G0000013",
"M_CurBalanceOutstanding": 52408.5
}
],
"DataDetail": [
{
"ErrorDate": "/Date(1410164281557+0200)/",
"ErrorID": 1,
"ErrorInfo": "Success"
}
]
}
I am trying to de-serialize it like this:
var deserializer = new JavaScriptSerializer();
List<MatterDetailBalOutstanding> results = deserializer.Deserialize<List<MatterDetailBalOutstanding>>(textResult);
where textresult is my JSon string.
I have the following classes:
[DataContract]
class MatterDetailBalOutstanding
{
[DataMember]
public string ID { get; set; }
[DataMember]
public decimal M_CurBalanceOutstanding { get; set; }
[DataMember]
public List<MatterReturnStatusDetails> ErrorData;
public MatterDetailBalOutstanding(string _ID, decimal _M_CurBalanceOutstanding, List<MatterReturnStatusDetails> _ErrorData)
{
ID = _ID;
M_CurBalanceOutstanding = _M_CurBalanceOutstanding;
ErrorData = _ErrorData;
}
}
and:
[DataContract]
class MatterReturnStatusDetails
{
[DataMember]
public int ID { get; set; }
[DataMember]
public string Info { get; set; }
[DataMember]
public DateTime Date { get; set; }
public MatterReturnStatusDetails(int _ID, string _Info, DateTime _Date)
{
ID = _ID;
Info = _Info;
Date = _Date;
}
}
I just cannot get it to work? To my understanding it is possible to de-serialize a string containing two JSon arrays. I have read a ton of threads, and a lot of them suggest using another serializer. I have to go with JavaScriptSerializer though. Please could someone help with this? What am I doing wrong? Where am I missing something?
Update 1:
When I try:
MatterDetailBalOutstanding results = deserializer.Deserialize<MatterDetailBalOutstanding>(textResult);
I get the below error:
No parameterless constructor defined for type of 'ConsumeTestWCFApp.ConsumeTestWCFApp+MatterDetailBalOutstanding'.
You can use json2csharp to assist you in generating classes suitable for mapping your JSON. Here is the result :
public class Datum
{
public string ID { get; set; }
public double M_CurBalanceOutstanding { get; set; }
}
public class DataDetail
{
public DateTime ErrorDate { get; set; }
public int ErrorID { get; set; }
public string ErrorInfo { get; set; }
}
public class RootObject
{
public List<Datum> Data { get; set; }
public List<DataDetail> DataDetail { get; set; }
}
Then you can annotate and modify the generated classes further as necessary and use it in deserialization :
var result = deserializer.Deserialize<RootObject>(textResult);
This problem:
No parameterless constructor defined for type of
'ConsumeTestWCFApp.ConsumeTestWCFApp+MatterDetailBalOutstanding'.
occurs because your serialized classes do not have a default constructor. By creating a specific constructor like this:
class MatterDetailBalOutstanding
{
public MatterDetailBalOutstanding(string _ID, decimal _M_CurBalanceOutstanding, List<MatterReturnStatusDetails> _ErrorData)
{
...
}
}
you do not get a default constructor and have to add one yourself:
class MatterDetailBalOutstanding
{
public MatterDetailBalOutstanding(string _ID, decimal _M_CurBalanceOutstanding, List<MatterReturnStatusDetails> _ErrorData)
{
...
}
public MatterDetailBalOutstanding()
{
...
}
}
This may not be you biggest problem now, but I didn't see anyone answer that part of the question.

Categories

Resources