简体   繁体   中英

posting single item in json array to .net object

I have an object in .net that is mostly for the purpose of receiving some json. It generally works very nicely, but when there is a single item in an array of numbers the json library converts this to a single number and not an array with a single item. .net throws this out as an error as it is a single int32 instead of an array of int32s i tried converting to json.net but this had not surprisingly the same error

as far as i can think there is no way to have an alternative definition in my object, is there?

below is the definition of my object

public class EnquiryModel
{
    public string Name;
    public string Email;
    public string Phone;
    public string JobCode;
    public string Message;
    public int ReferralSource;
    public Dictionary<string, int> PickList;
    public int[] Studios;
    public int[] Services;
    public string[] BookingEnquiries;
}

and here is the code i use to populate it

using Newtonsoft.Json;
EnquiryModel enq = JsonConvert.DeserializeObject<EnquiryModel>(json);

previously I used

using System.Web.Script.Serialization;
JavaScriptSerializer j = new JavaScriptSerializer();
EnquiryModel enq = j.Deserialize<EnquiryModel>(json);

they both produce the same error

not sure what the best way to avoid this problem would be

when it is serialised on the client the arrays with a single item are converted to a single number not sure why that is either :) ?

UPDATED AS SOLVED

the answer marked as the solution below worked really well - thank you :)

there was a couple of tiny changes I had to make which I thought were worth sharing

firstly I found it was passed as an Int64 so my check is for both types with an or

also I had some code that used this object and because the public variable was no longer an array but an object I had to add a cast to the usage so:

foreach (int studio in enq.Studios)

had to change to

foreach (int studio in (Int32[])enq.Studios)

this is the full source of the object now it would be good if there were some way to generalise the repeated code to make it easier to read but that may well be gold-plating :)

public class EnquiryModel
{
    public string Name;
    public string Email;
    public string Phone;
    public string JobCode;
    public string Message;
    public int ReferralSource;
    public Dictionary<string, int> PickList;
    //allow the arrays of 1 to many values to be submitted as a single value
    // instead of a single item in an array
    private string[] bookingEnquiries;
    public object BookingEnquiries
    {
        get { return bookingEnquiries; }
        set
        {
            if (value.GetType() == typeof(string))
            {
                bookingEnquiries = new string[] { (string)value };
            }
            else if (value.GetType() == typeof(string[]))
            {
                bookingEnquiries = (string[])value;
            }
        }
    }
    private int[] studios;
    public object Studios
    {
        get { return studios; }
        set
        {
            if (value.GetType() == typeof(Int32) || value.GetType() == typeof(Int64))
            {
                studios = new Int32[] { (Int32)value };
            }
            else if (value.GetType() == typeof(Int32[]))
            {
                studios = (Int32[])value;
            }
        }
    }
    private int[] services;
    public object Services
    {
        get { return services; }
        set
        {
            if (value.GetType() == typeof(Int32) || value.GetType() == typeof(Int64))
            {
                services = new Int32[] { (Int32)value };
            }
            else if (value.GetType() == typeof(Int32[]))
            {
                services = (Int32[])value;
            }
        }
    }

}

I would make the variables p[rivate and expose them through getters and setters. In the setter, you can evaluate the property sent in and set it appropriately.

    private Int32[] numbers;

    public object Numbers
    {
        get { return numbers; }
        set
        {
            if (value.GetType() == typeof(Int32))
            {
                numbers = new Int32[] { (Int32)value };
            }
            else if (value.GetType() == typeof(Int32[]))
            {
                numbers = (Int32[])value;
            }
        }
    }

I feel you will need to write your own wrapper which will check that if a single item of type T exists, it converts it to new T[]{item} . You can use JSON.NET's JObject class.

JObject o = JObject.Parse(response);

and evaluate o for the particular property you are looking for.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM