I have the same issue as this guy posting single item in json array to .net object.
To summarize, I am sending JSON data to an action and getting null when there is only one item passed. But it works when there is more than one item.
I know this has to do with how the JSON string is constructed (list of object vs. single object) but I have no choice; I am using a limited jquery json library (that's another story)
JSON string example with a list of fields
{
"formtemplate":{
"fields":{
"field":[
{
"_class":"form-control text-input",
"_label":"Text Field",
"_name":"text-1467980984393",
"_type":"text",
"_subtype":"text"
},
{
"_class":"form-control text-input",
"_label":"Text Field",
"_name":"text-1467980999418",
"_type":"text",
"_subtype":"text"
}
]
}
}
}
JSON string example with only one field item
{
"formtemplate":{
"fields":{
"field":{
"_class":"form-control text-input",
"_label":"Text Field",
"_name":"text-1467980984393",
"_type":"text",
"_subtype":"text"
}
}
}
}
Model
public class Fields
{
public List<Field> field { get; set; }
}
public class Formtemplate
{
public Fields fields { get; set; }
}
public class CustomFields
{
public Formtemplate formtemplate { get; set; }
}
public class Field
{
public string _label { get; set; }
public string _name { get; set; }
public string _type { get; set; }
public List<Option> option { get; set; }
}
Action
[HttpPost]
public JsonResult saveCustomfields(CustomFields customfields)
{
}
I followed the advice on the link provided but it didn't seem to work, here is what I did
public class Fields
{
private List<Field> field;
public object Numbers
{
get { return field; }
set
{
if (value.GetType() == typeof(Field))
{
field = new List<Field> { (Field)value };
}
else if (value.GetType() == typeof(List<Field>))
{
field = (List<Field>)value;
}
}
}
}
In the action I get both of "Numbers" and "field" as null when there is one item or more. The solution is logical but it didn't work for me.
Update
I researched a bit more and implemented a custom converter from this link How to handle both a single item and an array for the same property using JSON.net. But when I debug; it seems like SingleOrArrayConverter is not even called
public class Fields
{
[JsonProperty("field")]
[JsonConverter(typeof(SingleOrArrayConverter<Field>))]
public List<Field> field { get; set; }
}
public class Formtemplate
{
[JsonProperty("fields")]
public Fields fields { get; set; }
}
public class CustomFields
{
[JsonProperty("formtemplate")]
public Formtemplate formtemplate { get; set; }
}
public class SingleOrArrayConverter<T> : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(List<T>));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken token = JToken.Load(reader);
if (token.Type == JTokenType.Array)
{
return token.ToObject<List<T>>();
}
return new List<T> { token.ToObject<T>() };
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
But still no success, does it have to do with my action?