Empty json list treated as null - c#

I have a problem with empty JSON lists deserializing to null while null values deserializes to an empty list.
Using this test scenario in a completely new MVC project:
public class TestController : Controller
{
public ActionResult Index(ImportObject importObject)
{
return Content("Response");
}
public class ImportObject
{
public List<string> StringListNull { get; set; }
public List<string> StringListEmpty { get; set; }
public List<string> StringListPopulated { get; set; }
}
}
I'm posting the following JSON:
{
"StringListNull": null,
"StringListEmpty": [],
"StringListPopulated": ["one", "two"]
}
And this happens:
The populated string list is expected. But in my mind the null value of StringListNull should result in it being null.
When passing the value [] I'm expecting it being turned into an empty list
Am I missing something trivial? How can I make the null value become a nulled list and the empty list become an empty list?
What controls the default serialization from JSON to the parameter class (ImportObject)?
/K

I tried your code and works absolutely fine, probably you are switching the StringListNull and StringListEmpty.
Here is how I tested it, try it out and see where you are making something wrong:
public class ImportObject
{
public List<string> StringListNull { get; set; }
public List<string> StringListEmpty { get; set; }
public List<string> StringListPopulated { get; set; }
}
class Program
{
static void Main(string[] args)
{
var sb = new StringBuilder();
var line = string.Empty;
while (!string.IsNullOrWhiteSpace((line = Console.ReadLine())))
{
sb.AppendLine(line);
}
var json = sb.ToString().Trim();
var inputObj = JsonConvert.DeserializeObject<ImportObject>(json);
Console.WriteLine();
}
}
This is a simple Console app to test your logic.
Edit:
tested with your input JSON:
{
"StringListNull": null,
"StringListEmpty": [],
"StringListPopulated": ["one", "two"]
}

Well, you can use Newtonsoft.Json or Json.NET for serializing or deserializing the Json. It will give you the required results.
This is the code I tried with it:
static void Convert()
{
string K = #"{ ""StringListNull"": null, ""StringListEmpty"": [], ""StringListPopulated"": [""one"", ""two""]}";
var list= JsonConvert.DeserializeObject<ImportObject>(K);
}
public class ImportObject
{
public List<string> StringListNull { get; set; }
public List<string> StringListEmpty { get; set; }
public List<string> StringListPopulated { get; set; }
}
And in the list object is exactly as you want.

Related

Deserialize issue in C# Json

PageParameters have dynamic values. I tried to add it like below.
{
"Message": [
{
"TextMessage": "Hello World",
"Notification": [{
"Page": "Order",
"OpenPage": true,
"PageParameters":[ {"filedName": "400","filedvalue": "test","test": "444"}]
} ]
}
]
}
C# Code
var notification = notificationRequest?.NotificationMessage[0].ToString();
var NotificationObj = JsonConvert.DeserializeObject<NotificationObj>(notification);
public class NotificationObj
{
public string TextMessage { get; set; }
public string AppName { get; set; }
public List<Notifications> Notification { get; set; }
}
public class Notifications
{
public string PageName { get; set; }
public bool OpenPage { get; set; }
public List<PageParameter> PageParameters { get; set; }
}
public class PageParameter
{
List<string> PageParameters = new List<string>();
}
My PageParameter have dynamic values. Its getting multiple values. So i tried to add it as a List. But its not adding values when Deserialize Json. Other values are adding. Please help to solve this.
Check my answer here. You essentially need to apply that on your PageParameter class
PageParameters is an array of Key-value pairs, which would require the use of a Dictionary in C#.
Update PageParameter to the following and re-run your deserialization:
public class PageParameter
{
Dictionary<string, string> PageParameters = new Dictionary<string, string>();
}

Json.Net Deserializing list of c# objects throwing error

I have a list of objects in below json format. I would like to deserialize using below code. It is throwing unable to convert to object error. I have tried below three options, but didnt help. jsoninput is a IEnumerable<string>converted into json object using ToJson().
Error:
{"Error converting value \"{\"id\":\"11ef2c75-9a6d-4cef-8163-94daad4f8397\",\"name\":\"bracing\",\"lastName\":\"male\",\"profilePictureUrl\":null,\"smallUrl\":null,\"thumbnailUrl\":null,\"country\":null,\"isInvalid\":false,\"userType\":0,\"profilePrivacy\":1,\"chatPrivacy\":1,\"callPrivacy\":0}\" to type 'Api.Models.UserInfo'. Path '[0]', line 1, position 271."}
var requests1 = JsonConvert.DeserializeObject<UsersInfo>(jsoninput);
var requests2 = JsonConvert.DeserializeObject<IEnumerable<UserInfo>>(jsoninput);
var requests3 = JsonConvert.DeserializeObject<List<UserInfo>>(jsoninput);
//Below are my classes,
public class UsersInfo
{
public List<UserInfo> UserInfoList { get; set; }
public UsersInfo()
{
UserInfoList = new List<UserInfo>();
}
}
public class UserInfo
{
public string Id { set; get; }
public string Name { set; get; }
public string LastName { set; get; }
public string ProfilePictureUrl { set; get; }
public string SmallUrl { set; get; }
public string ThumbnailUrl { get; set; }
public string Country { set; get; }
public bool IsInvalid { set; get; }
}
Below is my json object,
["{\"id\":\"11ef2c75-9a6d-4cef-8163-94daad4f8397\",\"name\":\"bracing\",\"lastName\":\"male\",\"profilePictureUrl\":null,\"smallUrl\":null,\"thumbnailUrl\":null,\"country\":null,\"isInvalid\":false}","{\"id\":\"318c0885-2720-472c-ba9e-1d1e120bcf65\",\"name\":\"locomotives\",\"lastName\":\"riddles\",\"profilePictureUrl\":null,\"smallUrl\":null,\"thumbnailUrl\":null,\"country\":null,\"isInvalid\":false}"]
Looping through individual items in json input and if i deserialize it like below, it works fine. But i want to deserialize the list fully. Note: jsoninput was a IEnumerable<string> before i convert in json object.
foreach (var re in jsoninput)
{
var request0 = JsonConvert.DeserializeObject<UserInfo>(re);
}
Please look at this fiddle: https://dotnetfiddle.net/XpjuL4
This is the code:
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
//Below are my classes,
public class UsersInfo
{
public List<UserInfo> UserInfoList { get; set; }
public UsersInfo()
{
UserInfoList = new List<UserInfo>();
}
}
public class UserInfo
{
public string Id { set; get; }
public string Name { set; get; }
public string LastName { set; get; }
public string ProfilePictureUrl { set; get; }
public string SmallUrl { set; get; }
public string ThumbnailUrl { get; set; }
public string Country { set; get; }
public bool IsInvalid { set; get; }
}
public class Program
{
public static void Main()
{
Console.WriteLine("Hello World");
Option1();
Option2();
}
public static void Option1(){
string json = #"{""UserInfoList"":[
{""id"":""11ef2c75 - 9a6d - 4cef - 8163 - 94daad4f8397"",""name"":""bracing"",""lastName"":""male"",""profilePictureUrl"":null,""smallUrl"":null,""thumbnailUrl"":null,""country"":null,""isInvalid"":false},
{ ""id"":""318c0885-2720-472c-ba9e-1d1e120bcf65"",""name"":""locomotives"",""lastName"":""riddles"",""profilePictureUrl"":null,""smallUrl"":null,""thumbnailUrl"":null,""country"":null,""isInvalid"":false}
]}";
var obj = JsonConvert.DeserializeObject<UsersInfo>(json);
obj.UserInfoList.ForEach(e => Console.WriteLine(e.Id));
}
public static void Option2(){
string json = #"[
{""id"":""11ef2c75 - 9a6d - 4cef - 8163 - 94daad4f8397"",""name"":""bracing"",""lastName"":""male"",""profilePictureUrl"":null,""smallUrl"":null,""thumbnailUrl"":null,""country"":null,""isInvalid"":false},
{ ""id"":""318c0885-2720-472c-ba9e-1d1e120bcf65"",""name"":""locomotives"",""lastName"":""riddles"",""profilePictureUrl"":null,""smallUrl"":null,""thumbnailUrl"":null,""country"":null,""isInvalid"":false}
]";
var obj = JsonConvert.DeserializeObject<List<UserInfo>>(json);
obj.ForEach(e => Console.WriteLine(e.Id));
}
}
Both work, and are basically very close to what you are doing. You can either serialize it as a list (based on your json, I think that's the closest to your use case, and that's Option 2).
However, put extra attention to the JSON. I had to re-parse your JSON to make it work (https://jsonformatter.org/json-parser is a nice website to do it). For the sake of explaining the example, in C#, # means raw string, and in raw string, quotes are escaped with double quotes "".
I would expect that the business logic generating this JSON is not correct, if the JSON you pasted is the direct result from it.
EDIT
Given the OP's comment:
Thanks Tu.ma for your thoughts. The other method returns
IEnumerable which is nothing but
Dictionary.Where(x => x.Value == null).Select(x =>
x.Key).ToHashSet(). The values in Dictionary are -> Key
is String, Value is UserInfo object serialized. So, in that case i
should deserialize one by one? If not, i should serialize entire list
in one shot? Am i right? – Raj 12 hours ago
The problem is in the way you are generating the list of UsersInfo. The result from Dictionary<string,string>.Where(x => x.Value == null).Select(x =>
x.Key).ToHashSet() is a bunch of strings, not of objects, so you need to serialize them one by one.
If you are worried about the linearity of the approach, you could consider running through it in parallel. Of course, you need to judge if it fits your application.
var userInfoStrings = Dictionary<string,string>.Where(x => x.Value == null).Select(x => x.Key).ToHashSet();
var UserInfoList = userInfoStrings.AsParallel().Select (u => JsonConvert.DeserializeObject<UsersInfo>(u)).ToList();

How to convert Json array to list in c#

How to convert Json array to list of objects in c#
MY Json array:
{"allAdultFares":["0-5000.00","1-8000.00"],"Flag":"N"},
Class:
public List<Sellrate> allAdultFares { get; set; }
public class Sellrate
{
public string Singe { get; set; }
public string Double { get; set; }
}
I need O/p:
Singe :5000
Double :8000
Here's some simple code to parse your json without creating a proper class to represent its structure like Jon suggested. I might have misunderstood the exact structure of your json so here is the sample json I worked with, perhaps you will need to make small adjustments to it will fit your case:
{
"rateDetails":[
{
"date":"19-9-2015",
"allAdultFares":["0-5000.00","1-8000.00"],
"Flag":"N"
},
{
"date":"20-9-2015",
"allAdultFares":["0-9000.00","1-9000.00"],
"Flag":"N"
}
]
}
I used JSon.Net to parse the file, you can get it from nuget.
var input = JObject.Parse(File.ReadAllText("sample.json"));
var rateDetails = (JArray)input["rateDetails"];
var a = rateDetails
.Select(t => (JArray)t["allAdultFares"])
.Select(t =>
new Sellrate()
{
Singe = t[0].ToString().Split('-')[1].Replace(#"""", ""),
Double = t[1].ToString().Split('-')[1].Replace(#"""", "")
}).ToList();
i changed & getting o/p
public string[] allAdultFares{ get; set; }
Single: { "field1":"value1","field2":"value2" }
Array: [ { "field1":"value1","field2":"value2" }, { "field1":"value1","field2":"value2" } ]
public class Test
{
public string field1 { get; set; }
public string field2 { get; set; }
}
Test myDeserializedObj = (Test)JavaScriptConvert.DeserializeObject(Request["jsonString"], typeof(Test));
List<test> myDeserializedObjList = (List<test>)Newtonsoft.Json.JsonConvert.DeserializeObject(Request["jsonString"], typeof(List<test>));

json newtonsoft : Deserialize Object containing a list of string

I have the following issue with this json :
{
"EVTS": {
"EVT": [
{ "ID": "123456",
"KEY1" : "somekey",
"CATEG": [
"cat1",
"cat2",
"cat3"
]
}
]}
}
and this c# class:
public class myClass{
public string ID { get; set; }
public string KEY1 { get; set; }
public list<string> CATEG { get; set; }
}
public class ESObject1
{
[JsonProperty("EVT")]
public List<myClass> EVT { get; set; }
}
public class ESObject0
{
[JsonProperty("EVTS")]
public ESObject1 EVTS { get; set; }
}
}
here i call the deserializer :
ESObject0 globalobject = JsonConvert.DeserializeObject<ESObject0>(json);
But this last code doesnt work, i throws this exception : System.ArgumentException: Could not cast or convert from System.String to System.Collections.Generic.List1[System.String].`
Instead of list<string> i used string [] and only string nothing seems to work.
how can i deserialize this object correctly please.
Thank you.
There doesn't seem to be any apparent problem wit hyour code as this working example illustrates:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
public class myClass
{
public string ID { get; set; }
public string KEY1 { get; set; }
public List<string> CATEG { get; set; }
}
public class ESObject1
{
[JsonProperty("EVT")]
public List<myClass> EVT { get; set; }
}
public class ESObject0
{
[JsonProperty("EVTS")]
public ESObject1 EVTS { get; set; }
}
class Program
{
static void Main()
{
string json =
#"{
""EVTS"": {
""EVT"": [
{
""ID"": ""123456"",
""KEY1"": ""somekey"",
""CATEG"": [
""cat1"",
""cat2"",
""cat3""
]
}
]
}
}";
ESObject0 globalobject = JsonConvert.DeserializeObject<ESObject0>(json);
foreach (string item in globalobject.EVTS.EVT[0].CATEG)
{
Console.WriteLine(item);
}
}
}
Maybe you just fed a wrong json value to the deserializer which doesn't look like as the one shown in your question. By the way, the one shown i nyour question is invalid JSON as you are missing a , after KEY1 property declaration.
UPDATE:
Now that you have shown your real JSON (coming from http://donnees.ville.quebec.qc.ca/Handler.ashx?id=69&f=JSON) it appears that there's a row where CATEG is not an array of strings but a simple string:
""CATEG"": ""Conférence""
Now that's a pretty bad design because they are mixing arrays and simple properties. I am afraid that in order to deal with this situation you will need to use JObjects and extract the information you need by testing the actual underlying type.
For example:
var obj = JObject.Parse(json);
var events = (JArray)obj["EVTS"]["EVT"];
foreach (JObject evt in events)
{
var categories = evt["CATEG"];
if (categories is JArray)
{
// you've got a list of strings so you can loop through them
string[] cats = ((JArray)categories)
.Select(x => x.Value<string>())
.ToArray();
}
else
{
// you've got a simple string
string cat = categories.Value<string>();
}
}
I have done this many times with many many headaches. My advice is take the json output and use a tool similar to this to write your class for you (http://json2csharp.com/).
Then go over any nullable variables and add nullable type (ex. using int? for int) where needed.

JavaScriptDeseializer : Can not serialize array

My application is asp.net. I have to send some values back to server. For this I create a object serialize it and send it to server. At server I try to de-serialize it
Following is my code
[Serializable]
public class PassData
{
public PassData()
{
}
public List<testWh> SelectedId { get; set; }
public string SelectedControlClientId { get; set; }
public string GroupTypeId { get; set; }
public string SectionTypeId { get; set; }
}
[Serializable]
public class testWh
{
public testWh()
{
}
public string Id { get; set; }
}
JavaScriptSerializer serializer = new JavaScriptSerializer();
//this can not serialize the SelectedId and the count remains 0
PassData data = serializer.Deserialize<PassData>(jsonString);
//this serialize in an anonymous object with key value pair
var data2 = serializer.DeserializeObject(textHiddenArguments.Text);
Following is my Json Serialized String
{
"SelectedId":{"0":"ABCD","1":"JKLM"},
"SelectedControlClientId":"YTUTOOO",
"GroupTypeId":3,
"SectionTypeId":"1"
}
quotes escaped string
"{\"SelectedId\":{\"0\":\"ABCD\",\"1\":\"JKLM\"},\"SelectedControlClientId\":\"YTUTOOO\",\"GroupTypeId\":3,\"SectionTypeId\":\"1\"}"
My Problem is Selected Id is array of testWH object. But when I try to desrialize it, the SelectedId property of PassData which is list does not get serialized and count remains zero.
I tried using array instead of List, which gave an exception "no parameter less constructor..."
Could any one explain the what I am doing wrong here ?
The key problem here is that the JSON doesn't match the objects you have constructed. You can see this by writing the data you want and serializing:
var obj = new PassData
{
SelectedId = new List<testWh>
{
new testWh { Id = "ABCD"},
new testWh { Id = "JKLM"}
},
GroupTypeId = "3",
SectionTypeId = "1",
SelectedControlClientId = "YTUTOOO"
};
string jsonString = serializer.Serialize(obj);
which gives JSON like:
{"SelectedId":[{"Id":"ABCD"},{"Id":"JKLM"}],
"SelectedControlClientId":"YTUTOOO","GroupTypeId":"3","SectionTypeId":"1"}
So now you need to decide which you want to change; the JSON or the classes. The following alternative class works fine with your original JSON, for example:
public class PassData
{
public Dictionary<string,string> SelectedId { get; set; }
public string SelectedControlClientId { get; set; }
public string GroupTypeId { get; set; }
public string SectionTypeId { get; set; }
}

Categories