Deserialize JSON

Asked

Viewed 855 times

3

I can do the POST of this information:

{
    "Nritem": 1,
    "Cdprevenda": 3,
    "Cdproduto": 7,
    "Decomplitem": "",
    "Descricao": "Depilação",
    "Dtcadastro": "2015-11-27T13:53:35.120Z",
    "Flsituacao": 1,
    "Md5": "",
    "Qtproduto": 18,
    "Totalizador": "01T1700",
    "Unidade": "UN",
    "Vltabela": 50,
    "Vlunitario": 50,
}

But if you put yourself between [] appears this message:

"itemprevenda":[
  "Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'PreVendaWebAPI.Models.Itemprevenda' because the type requires a JSON object (e.g. {\"name\":\"value\"}) to deserialize correctly.\r\nTo 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.\r\nPath '', line 1, position 1."]

API that makes the POST:

// POST: api/Itemprevendas
    [ResponseType(typeof(Itemprevenda))]
    public async Task<IHttpActionResult> PostItemprevenda(Itemprevenda itemprevenda)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        //  Implementar o Cditemprevenda e o Nritem automaticamente
        decimal cd = await GetMaiorCod();
        decimal nr = await GetMaiorNr(itemprevenda.Cdprevenda);

        itemprevenda.Cditemprevenda = cd;
        itemprevenda.Nritem = nr;
        //  *******************************************************

        db.Itemprevenda.Add(itemprevenda);

        try
        {
            await db.SaveChangesAsync();
        }
        catch (DbUpdateException)
        {
            if (ItemprevendaExists(itemprevenda.Cditemprevenda))
            {
                return Conflict();
            }
            else
            {
                throw;
            }
        }

        return CreatedAtRoute("DefaultApi", new { id = itemprevenda.Cditemprevenda }, itemprevenda);
    }

Committed:

public partial class Itemprevenda
{
    public decimal Cditemprevenda { get; set; }
    public decimal Cdprevenda { get; set; }
    public decimal Cdproduto { get; set; }
    public decimal Nritem { get; set; }
    public decimal Qtproduto { get; set; }
    public decimal Vltabela { get; set; }
    public decimal Vldesconto { get; set; }
    public decimal Vlacrescimo { get; set; }
    public decimal Vlunitario { get; set; }
    public int Flsituacao { get; set; }
    public System.DateTime Dtcadastro { get; set; }
    public string Descricao { get; set; }
    public string Unidade { get; set; }
    public string Totalizador { get; set; }
    public byte[] Md5 { get; set; }
    public string Decomplitem { get; set; }
    public decimal Cdvendedor { get; set; }
    public decimal Vltotal { get; set; }
}

How do I deserialize this JSON?

4 answers

3

Use the Javascriptserializer present in the namespace

System.Web.Script.Serialization;

It has a method called Deserialize where Voce passes the JSON object and the type in which JSON will be converted.

Ex:

JavaScriptSerializer serializer = new JavaScriptSerializer();
meuTipo minhaVariavel = serializer.Deserialize(stringJson, meuTipo);
  • myType would be the kind I’m going through to deserialize: Itemprevenda? And stringJson is the format that will be deserialized?

  • Exactly, the myType would be the Itemprevenda. stringJson is the string that contains the json that Oce wants to deserialize.

  • But you don’t have a string with JSON. What I have is Itemprevenda: PostItemprevenda(Itemprevenda itemprevenda)

  • So Voce wants to serialize the data? What exactly does Voce need?

  • I am passing data in JSON to the API and need to decentralize to do the POST object by object.

  • But isn’t your object already "deserialized"? Explain to me more the flow of your logic (step by step) and the final goal of the whole process, please...

Show 2 more comments

2

Well, I would make a structure like this:

THE JSON:

string seujson=
@"{""data"":[{""Cditemprevenda"":""1"",""Cdproduto"":""8""},{""Cditemprevenda"":""2"",""Cdproduto"":""9""}, {""Cditemprevenda"":""3"",""Cdproduto"":""10""}]}";

The classes:

public class Itemprevenda
{

     public List<Item> Items {get;set;}
}

public class Item
{
    public string Cditemprevenda {get;set;}
    public string Cdproduto {get;set;}
}
Itemprevenda item = new JavaScriptSerializer().Deserialize<Itemprevenda>(seujson);

To recover:

foreach(var json in item.Items)
{
   Console.WriteLine("CdItem: {0}, CdProduto: {1}",json.Cditemprevenda ,json.Cdproduto );
}
  • Only that the JSON will come through the browser URL, I will not set it in the scope of code with string seujson=&#xA;@.... How do I pass this information to the class, within the seujson.

2

EDITION I had not listened to the fact that the deserialization was implicit. to receive more than one object of the type Itemprevenda you must modify the signature of your public async Task<IHttpActionResult> PostItemprevenda(Itemprevenda itemprevenda) for public async Task<IHttpActionResult> PostItemprevenda(Itemprevenda[] itemprevenda). Note that added [] after type Itemprevenda.

Making this modification your JSON should be sent as follows to your API:

"[{
        "Nritem": 1,
        "Cdprevenda": 3,
        "Cdproduto": 7,
        "Decomplitem": "",
        "Descricao": "Depilação",
        "Dtcadastro": "2015-11-27T13:53:35.120Z",
        "Flsituacao": 1,
        "Md5": "",
        "Qtproduto": 18,
        "Totalizador": "01T1700",
        "Unidade": "UN",
        "Vltabela": 50,
        "Vlunitario": 50,
    }, {
        "Nritem": 2,
        "Cdprevenda": 4,
        "Cdproduto": 8,
        "Decomplitem": "",
        "Descricao": "Depilação 2",
        "Dtcadastro": "2015-11-27T13:53:35.120Z",
        "Flsituacao": 1,
        "Md5": "",
        "Qtproduto": 18,
        "Totalizador": "01T1700",
        "Unidade": "UN",
        "Vltabela": 50,
        "Vlunitario": 50,
    }]";

Your JSON should be sent without a label for the array, otherwise an error will occur in the deserialization of the JSON.

Ancient:

The point is that you using without the [] it considers only one item and placing the [] he considers a vector, array item.

To do this your template should contain an array itemprevenda with the same attributes as your JSON.

Try to make your model class similar to this:

///Essa classe será a classe que conterá a sua lista de itens
///de pré venda.
public class Modelo {
    public Itemprevenda[] itemprevenda { get; set; }
}

public partial class Itemprevenda
{
    public decimal Cditemprevenda { get; set; }
    public decimal Cdprevenda { get; set; }
    public decimal Cdproduto { get; set; }
    public decimal Nritem { get; set; }
    public decimal Qtproduto { get; set; }
    public decimal Vltabela { get; set; }
    public decimal Vldesconto { get; set; }
    public decimal Vlacrescimo { get; set; }
    public decimal Vlunitario { get; set; }
    public int Flsituacao { get; set; }
    public System.DateTime Dtcadastro { get; set; }
    public string Descricao { get; set; }
    public string Unidade { get; set; }
    public string Totalizador { get; set; }
    public byte[] Md5 { get; set; }
    public string Decomplitem { get; set; }
    public decimal Cdvendedor { get; set; }
    public decimal Vltotal { get; set; }
}

string seujson = "{
    "itemprevenda": [{
        "Nritem": 1,
        "Cdprevenda": 3,
        "Cdproduto": 7,
        "Decomplitem": "",
        "Descricao": "Depilação",
        "Dtcadastro": "2015-11-27T13:53:35.120Z",
        "Flsituacao": 1,
        "Md5": "",
        "Qtproduto": 18,
        "Totalizador": "01T1700",
        "Unidade": "UN",
        "Vltabela": 50,
        "Vlunitario": 50,
    }]
}";

/*
  Realiza a deserialização do JSON para um objeto do tipo "Modelo"
  que contém o array de Itemprevenda. Modelo com 'M' maiúsculo é a
  classe e com 'm' minúsculo é a variável.
*/
Modelo modelo = new JavaScriptSerializer().Deserialize<Modelo>(seujson);

How you want to receive a series, array, object Itemprevenda you must have a class, in this example the class Modelo, to contain this array.

That should solve your problem.

  • Can you explain what is being done in this implementation? What would be Model and model? And what I have to go through seujson?

  • 1

    @leopiazzoli modified the answer to try to clarify

  • You have to pass a string for seujson right? But the information that is passed to the API is of the Itemprevenda type. PostItemprevenda(Itemprevenda itemprevenda).

  • I had not anticipated it. I have already modified the answer.

0


Correct form:

public async Task<IHttpActionResult> PostItemprevenda(Itemprevenda itemprevenda){}

When Json is between [ ] the API understands that it is a list of objects, then you have to say that Itemprevenda is List this way List<Itemprevenda>. And now just do one foreach and browse the list.

Browser other questions tagged

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