2

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?

15
  • try changing "field" to "numbers" in your json Commented Jul 8, 2016 at 13:45
  • What are you using to deserialize the JSON? If you are using Newtonsoft, you can use property annotations to map properties with keys. If you don't it is assumed that the name of the property is the same as the name of the key in the JSON. Commented Jul 8, 2016 at 13:47
  • @Khanh TO, I can't I have to use the original tag names in JSON, I don't have control over that string Commented Jul 8, 2016 at 13:59
  • @AmateurProgrammer, I don't deserialize, MVC takes care of it Commented Jul 8, 2016 at 14:00
  • @Billy Blaze: well, then use public object field and change private List<Field> field; to something else. Example: private List<Field> f; Commented Jul 8, 2016 at 14:00

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.