Search code examples
c#jsonxamarindeserializationviewmodel

How to solve "Cannot deserialize the current JSON array into type because the type requires a JSON object to deserialize correctly."


I'm pretty new into the Xamarin and Web Services world, I´ve been trying to solve a deserialization issue trying but keep getting the error above, please find down below the JSON response, model and view model code. I've been trying several solutions but nothing helps. I think it migth be something on my model but I'm not completely sure. Any help would be really appreciated.

JSON Response

{
    "$id": "1",
    "$values": [
        {
            "$id": "2",
            "Contrato_Id": "FRANOPRA",
            "Emision_Id": "BANME  0159755",
            "Tipo_Custodia_Id": 100,
            "Institucion_Deposito_Id": 5,
            "Portafolio_Tit_Imp": 94768.0,
            "Portafolio_Costo_Promedio": 17.895753297132128,
            "Portafolio_Comprometido": 0.0,
            "Portafolio_TIR": 0.0,
            "Portafolio_Plazo": 0.0,
            "Contrato": null
        },
        {
            "$id": "3",
            "Contrato_Id": "FRANOPRA",
            "Emision_Id": "DOIXCB 15U",
            "Tipo_Custodia_Id": 100,
            "Institucion_Deposito_Id": 5,
            "Portafolio_Tit_Imp": 13000.0,
            "Portafolio_Costo_Promedio": 13.0,
            "Portafolio_Comprometido": 0.0,
            "Portafolio_TIR": 0.0,
            "Portafolio_Plazo": 0.0,
            "Contrato": null
        },
        {
            "$id": "4",
            "Contrato_Id": "FRANOPRA",
            "Emision_Id": "EFECTIVO",
            "Tipo_Custodia_Id": 5,
            "Institucion_Deposito_Id": 5,
            "Portafolio_Tit_Imp": 1.1271450007334352,
            "Portafolio_Costo_Promedio": 1.0,
            "Portafolio_Comprometido": 0.0,
            "Portafolio_TIR": 0.0,
            "Portafolio_Plazo": 0.0,
            "Contrato": null
        },
        {
            "$id": "5",
            "Contrato_Id": "FRANOPRA",
            "Emision_Id": "FT-LIQUA",
            "Tipo_Custodia_Id": 100,
            "Institucion_Deposito_Id": 5,
            "Portafolio_Tit_Imp": 692631.0,
            "Portafolio_Costo_Promedio": 1.007334,
            "Portafolio_Comprometido": 692631.0,
            "Portafolio_TIR": 0.0,
            "Portafolio_Plazo": 0.0,
            "Contrato": null
        },
        {
            "$id": "6",
            "Contrato_Id": "FRANOPRA",
            "Emision_Id": "TEMAGIALX",
            "Tipo_Custodia_Id": 100,
            "Institucion_Deposito_Id": 5,
            "Portafolio_Tit_Imp": 456250.0,
            "Portafolio_Costo_Promedio": 456.72739371178523,
            "Portafolio_Comprometido": 0.0,
            "Portafolio_TIR": 0.0,
            "Portafolio_Plazo": 0.0,
            "Contrato": null
        }
    ]
}

Model

public partial class PositionsModel
    {
        [JsonProperty("$id")]
        public long Id { get; set; }

        [JsonProperty("$values")]
        public posicionesInfo[] portafolio { get; set; }
    }

    public partial class posicionesInfo
    {
        [JsonProperty("$id")]
        public long Id { get; set; }

        [JsonProperty("Contrato_Id")]
        public string ContratoId { get; set; }

        [JsonProperty("Emision_Id")]
        public string EmisionId { get; set; }

        [JsonProperty("Tipo_Custodia_Id")]
        public long TipoCustodiaId { get; set; }

        [JsonProperty("Institucion_Deposito_Id")]
        public long InstitucionDepositoId { get; set; }

        [JsonProperty("Portafolio_Tit_Imp")]
        public double PortafolioTitImp { get; set; }

        [JsonProperty("Portafolio_Costo_Promedio")]
        public double PortafolioCostoPromedio { get; set; }

        [JsonProperty("Portafolio_Comprometido")]
        public long PortafolioComprometido { get; set; }

        [JsonProperty("Portafolio_TIR")]
        public long PortafolioTir { get; set; }

        [JsonProperty("Portafolio_Plazo")]
        public long PortafolioPlazo { get; set; }

        [JsonProperty("Contrato")]
        public object Contrato { get; set; }
    }

ViewModel

private async void GetDataAsync()
        {
            HttpClient httpClient = new HttpClient();
            var response = await httpClient.GetAsync("http://192.168.1.69/ApiTest/Api/Portafolio/FRANOPRA");

            if (response.IsSuccessStatusCode)
            {
                var content = await response.Content.ReadAsStringAsync();
                //Error on deserializer
                var positions = JsonConvert.DeserializeObject<PositionsModel>(content);
                portafolioInfo = new List<PositionsModel>((IEnumerable<PositionsModel>)positions);
            }
        }

Solution

  • The problem is $ in keys, because it's indicates metadata, not an actual data field, so you need to ignore it, to get the expected result, like the following code :

    JsonSerializerSettings settings = new JsonSerializerSettings
    {
        MetadataPropertyHandling = MetadataPropertyHandling.Ignore
    };
    
    var position = JsonConvert.DeserializeObject<PositionsModel>(json, settings);
    List<PositionsModel> portafolioInfo = new List<PositionsModel> { position };
    

    Fiddle : https://dotnetfiddle.net/oVtjDa

    I hope you find this helpful.