Question

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": "alexanrbe@gmail.com",
    "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

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top