Error deserializing Model JSON data

Asked

Viewed 383 times

1

JsonSerializationException: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'SoftluxWebCore.Models.Tabelas.Financeiro.CaixasModel' 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 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. Path '', line 1, position 1.

When I try to deserialize a data json gives me that error above

        CaixasModel Caixas;
        CaixasViewModel CaixasVM = new CaixasViewModel();
        using (HttpClient httpClient = new HttpClient())
        {
            httpClient.BaseAddress = BaseAdress;
            httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", strToken);
            httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("Application/Json"));
            using (HttpResponseMessage response = await httpClient.GetAsync(UrlApi))
            {
                response.EnsureSuccessStatusCode();
                string resul = await response.Content.ReadAsStringAsync();
                Caixas = JsonConvert.DeserializeObject<CaixasModel>(resul);
                CaixasVM.Bcx_codigo = Caixas.Bcx_codigo;
                CaixasVM.Bcx_Nome = Caixas.Bcx_Nome;
                CaixasVM.Cba_Saldo_inicial = Caixas.Cba_Saldo_inicial;
                CaixasVM.Cba_PDV = Caixas.Cba_PDV.Equals(true) ? true : false;
                CaixasVM.Bcx_situacao = Caixas.Bcx_situacao.Equals("A") ? true : false;
            }
        }
        return View(CaixasVM);

Above is my code, I’m deserializing in a model, so I can’t use <List> I use a Webapi that converts the object into json and sends it to my project, I will insert the method further down. JSON Recebido:

[{"Bcx_codigo":1,"Bcx_Nome":"PRINCIPAL","Cba_Saldo_inicial":2000.0,"Bcx_tipo":"C","Cba_PDV":false,"Bcx_situacao":"A","Emp_codigo":1},{"Bcx_codigo":24,"Bcx_Nome":"SECUNDARIO","Cba_Saldo_inicial":null,"Bcx_tipo":"C","Cba_PDV":null,"Bcx_situacao":"A","Emp_codigo":1},{"Bcx_codigo":25,"Bcx_Nome":"asdas","Cba_Saldo_inicial":2312.0,"Bcx_tipo":"C","Cba_PDV":true,"Bcx_situacao":"A","Emp_codigo":1}]

Coffin

namespace SoftluxWebCore.Models.Tabelas.Financeiro
{
public class CaixasModel
{
    public int? Bcx_codigo { get; set; }
    public string Bcx_Nome { get; set; }
    public string Bcx_tipo { get; set; }
    public float? Cba_Saldo_inicial { get; set; }
    public Nullable<int> usr_cod_criacao { get; set; }
    public Nullable<System.DateTime> usr_dt_hr_criacao { get; set; }
    public Nullable<int> usr_cod_alteracao { get; set; }
    public Nullable<System.DateTime> usr_dt_hr_alteracao { get; set; }
    public string Bcx_situacao { get; set; }
    public bool? Cba_PDV { get; set; }
    public Nullable<int> Emp_codigo { get; set; }
}
}

Method in the Webapi

[HttpGet]
    [Route("findAll")]
    public HttpResponseMessage findAll()
    {
        try
        {
            var result = new HttpResponseMessage(HttpStatusCode.OK);

            var caixas = (from bc in bdprincipalEntities.Bancos_Caixas
                          join c in bdprincipalEntities.Contas_Bancarias on bc.Bcx_codigo
                          equals c.Bcx_codigo into c_c
                          from c in c_c.DefaultIfEmpty()
                          select new
                          {
                              Bcx_codigo = bc.Bcx_codigo,
                              Bcx_Nome = bc.Bcx_Nome,
                              Cba_Saldo_inicial = c.Cba_Saldo_inicial,
                              Bcx_tipo = bc.Bcx_tipo,
                              Cba_PDV = c.Cba_PDV,
                              Bcx_situacao = bc.Bcx_situacao.Equals("A") ? "ATIVO" : "DESATIVADO",
                              Emp_codigo = bc.Emp_codigo
                          }).Where(x => x.Bcx_tipo.Equals(TipoBanco)).ToList();

            result.Content = new StringContent(JsonConvert.SerializeObject(caixas));
            result.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
            return result;
        }
        catch (Exception)
        {
            return new HttpResponseMessage(HttpStatusCode.BadRequest);
        }
    }
  • 2

    var boxes is a list... shouldn’t it be like Caixasmodel? Seu Tolist() at the end that seems to be your problem... at the stretch . Where(x => x.Bcx_type.Equals(Typobanco)). Tolist(); should always return only one result?

  • 1

    I didn’t know how to define the type as Caixasmodel in Webapi, but your answer to below fixed, thanks

1 answer

2


Your problem is you’re trying to deserialize a List and actually expects an object Coffin.

Pay attention to this part of Exception:

Cannot deserialize the Current JSON array (e.g. [1,2,3]) into type 'SoftluxWebCore.Models.Tabelas.Financeiro.CaixasModel'

In short, it says exactly what I put in the first paragraph.

Review this snippet of your code:

var caixas = (from bc in bdprincipalEntities.Bancos_Caixas
                    join c in bdprincipalEntities.Contas_Bancarias on bc.Bcx_codigo
                    equals c.Bcx_codigo into c_c
                    from c in c_c.DefaultIfEmpty()
                    select new
                    {
                        Bcx_codigo = bc.Bcx_codigo,
                        Bcx_Nome = bc.Bcx_Nome,
                        Cba_Saldo_inicial = c.Cba_Saldo_inicial,
                        Bcx_tipo = bc.Bcx_tipo,
                        Cba_PDV = c.Cba_PDV,
                        Bcx_situacao = bc.Bcx_situacao.Equals("A") ? "ATIVO" : "DESATIVADO",
                        Emp_codigo = bc.Emp_codigo
                    }).Where(x => x.Bcx_tipo.Equals(TipoBanco)).ToList();

var caixas will be deserialised later, but due to .ToList() she’ll be the type List even if only one value is returned. The correct one to work in this case would be this:

Where(x => x.Bcx_tipo.Equals(TipoBanco)).SingleOrDefault(); 

This way it will return only one value and var boxes will be of the type Coffin.

  • 1

    Great answer, thank you, I had a problem because the search returned me more than one element, so I had to make a small change and was : " }). Where(x => x.Bcx_type.Equals(Typobanco) && x.Bcx_code == Bcx_code). Singleordefault(); "but your reply was great, solved my problem, thank you

Browser other questions tagged

You are not signed in. Login or sign up in order to post.