Cannot deserialize the current JSON array (e.g. [1,2,3]) into type with complex and nested objects

sasha berd picture sasha berd · Jul 21, 2013 · Viewed 9.1k times · Source

I`m trying to build web api for complex object. For this aim I built the custom binder which deserialize this object from JSON.

My Customer Binder looks like:

var paramType = p_BindingContext.ModelType;

    dynamic updatedParam = Activator.CreateInstance(paramType);

    JsonReader reader = new JTokenReader(JObject.Parse
    (p_ActionContext.Request.Content.ReadAsStringAsync().Result));

    JObject jObject = JObject.Load(reader);

    JsonSerializer serializer = new JsonSerializer();

    serializer.Populate(jObject.CreateReader(), updatedParam);//Here the exception thorws

    p_BindingContext.Model = updatedParam; 

The object to serialize is very comlex:

          public class ModelRegisterUserRequest{

              public ModelUser User { get; set; }

    public CampaignItem CampaignWithChosenProposal { get; set; }

    public string ValidationToken { get; set; }

    public string IVRToken { get; set; }

    public string DealerID { get; set; }

    public string SalePersonID { get; set; }
             }

public class CampaignItem
{

    public List<BannerItem> Banners { get; set; }

    public string Code { get; set; }

    public string CustomerInstruction { get; set; }

    public string InfoLink { get; set; }

    public string LobbySubTitle { get; set; }

    public string LobbyTitle { get; set; }

    public string MoreText { get; set; }

    public uint NumOfColumns { get; set; }

    public uint NumOfRows { get; set; }

    public string OriginString { get; set; }
    public int OriginInt { get; set; }

    public List<ProposalItem> Proposals { get; set; }

    public string RegulationsInfoLink { get; set; }

    public string ServiceType { get; set; }

    public string SubTitle { get; set; }

    public string SWDefault { get; set; }

    public string Title { get; set; }   
}

public partial class ProposalItem
{

    public List<string> EquipmentsCode { get; set; }


    public string FeatureCode { get; set; }


    public string InvalidReason { get; set; }


    public bool IsExistsMoreInfo { get; set; }


    public bool IsValid { get; set; }


    public string LeadCode { get; set; }


    public int ParamCombinationCode { get; set; }


    public string ProductCode { get; set; }


    public string ProductCombinationCode { get; set; }


    public string ProposalCode { get; set; }


    public List<ColumnItem> Columns { get; set; }


    public List<MoreInfoItem> MoreInfoList { get; set; }


    public List<string> PricePlans { get; set; }

    public string ProductName { get; set; }    

}

The Json is created with JSON.stringify command from Javascript code and look like :

 {
   "ValidationToken": "1cc6cca8-44d5-4042-af37-de6a0d198d17",
  "AppID": "TST",
  "campaignWithChosenProposal": {
    "Banners": [
      {
        "LocationCodeString": "ManagerTab",
        "LocationCodeInt": 256,
        "MediaUrl": "<a href=\"c:\\\">BANNER 10</a>"
      }
    ],
    "Code": "CAMP221",
    "CustomerInstruction": "-1",
    "InfoLink": "http://test.aspx",
    "LobbySubTitle": "",
    "LobbyTitle": "",
    "MoreText": "",
    "NumOfColumns": 0,
    "NumOfRows": 0,
    "OriginString": "INT",
    "OriginInt": 4,
    "Proposals": [
      [
        {
          "EquipmentsCode": [
            "5455"
          ],
          "FeatureCode": "BE5455",
          "InvalidReason": "",
          "IsExistsMoreInfo": true,
          "IsValid": true,
          "LeadCode": "3792956510",
          "ParamCombinationCode": 0,
          "ProductCode": "OANTIVRP2",
          "ProductCombinationCode": "0",
          "ProposalCode": "291600010201C8F83661D5B82FD5F3603967588B7A72",
          "Columns": [
            {
              "Content": ""
            },
            {
              "Content": ""
            },
            {
              "Content": ""
            },
            {
              "Content": ""
            },
            {
              "Content": ""
            },
            {
              "Content": ""
            }
          ],
          "MoreInfoList": [
            {
              "Content": "3",
              "MoreInfoTypesString": "LicenseFrom",
              "MoreInfoTypesInt": 16
            },
            {
              "Content": "3",
              "MoreInfoTypesString": "LicenseTo",
              "MoreInfoTypesInt": 32
            },
            {
              "Content": "4.3",
              "MoreInfoTypesString": "PricePeriod1",
              "MoreInfoTypesInt": 64
            }
          ],
          "PricePlans": [
            "O2"
          ],
          "ProductName": ""
        }
      ]
    ],
    "RegulationsInfoLink": "http://www.test.aspx",
    "ServiceType": "TST",
    "SubTitle": "",
    "SWDefault": "1",
    "Title": ""
  },
  "User": {
    "CurrentLicenseNumber": 0,
    "CustomerID": "21670106",
    "FirstName": "",
    "LastName": "",
    "RequestedLicenseNumber": "3",
    "SubscriberPhoneNumber": "035448428",
    "IdentityNumber": "058470",
    "Email": "[email protected]",
    "RegistrationStatus": "NOTREGISTERED"
  },
  "SalePersonID": "3178364",
 }

The Exception is thrown on serilization row and looks like:

Cannot deserialize the current JSON array (e.g. [1,2,3]) into type WebAPI.Models.Entities.Campaigns.CampaignObjects.ProposalItem' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.

I spent nights for resolve this exception but did not find any solutions Also the solutions on this site are excisted but not supports such complex problem.

https://stackoverflow.com/questions/11126242/using-jsonconvert-deserializeobject-to-deserialize-json-to-a-c-sharp-poco-class

Cannot deserialize the current JSON array (e.g. [1,2,3]) into type

Somebody met such JSON unexpected behaiviour and could help?

Thanks

Answer

Dimitar Dimitrov picture Dimitar Dimitrov · Jul 21, 2013

According to your JSON data, the objects that you need to map to have to look like this (unless you have your own JsonDeserializer of course):

public class Banner
{
    public string LocationCodeString { get; set; }
    public int LocationCodeInt { get; set; }
    public string MediaUrl { get; set; }
}

public class CampaignWithChosenProposal
{
    public List<Banner> Banners { get; set; }
    public string Code { get; set; }
    public string CustomerInstruction { get; set; }
    public string InfoLink { get; set; }
    public string LobbySubTitle { get; set; }
    public string LobbyTitle { get; set; }
    public string MoreText { get; set; }
    public int NumOfColumns { get; set; }
    public int NumOfRows { get; set; }
    public string OriginString { get; set; }
    public int OriginInt { get; set; }
    public List<List<>> Proposals { get; set; }
    public string RegulationsInfoLink { get; set; }
    public string ServiceType { get; set; }
    public string SubTitle { get; set; }
    public string SWDefault { get; set; }
    public string Title { get; set; }
}

public class User
{
    public int CurrentLicenseNumber { get; set; }
    public string CustomerID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string RequestedLicenseNumber { get; set; }
    public string SubscriberPhoneNumber { get; set; }
    public string IdentityNumber { get; set; }
    public string Email { get; set; }
    public string RegistrationStatus { get; set; }
}

public class RootObject
{
    public string ValidationToken { get; set; }
    public string AppID { get; set; }
    public CampaignWithChosenProposal campaignWithChosenProposal { get; set; }
    public User User { get; set; }
    public string SalePersonID { get; set; }
}

Here is a really cool tool (json2csharp) to help you out.