JSON return with WEBAPI

Asked

Viewed 342 times

0

I’m creating a WebApi where his return and the following.

[{
    "$id": "1",
    "Operadora": {
        "$id": "2",
        "Contato": [{
            "$ref": "1"
        }, {
            "$id": "3",
            "Operadora": {
                "$ref": "2"
            },
            "id": 5,
            "telefone": "99999-9999          ",
            "cor": "yeloow              ",
            "data": "2017-01-23T00:00:00",
            "id_operadora": 1,
            "nome": "Fernando                                          "
        }],
        "id": 1,
        "nome": "Vivo                ",
        "codigo": 15,
        "categoria": "Movel                         ",
        "preco": "1         "
    },
    "id": 1,
    "telefone": "99999-9999          ",
    "cor": "blue                ",
    "data": "2017-01-23T00:00:00",
    "id_operadora": 1,
    "nome": "Jose                                              "
}, {
    "$ref": "3"
}, {
    "$id": "4",
    "Operadora": {
        "$id": "5",
        "Contato": [{
            "$ref": "4"
        }],
        "id": 3,
        "nome": "CLARO               ",
        "codigo": 21,
        "categoria": "Movel                         ",
        "preco": "1         "
    },
    "id": 6,
    "telefone": "99999-9999          ",
    "cor": "yeloow              ",
    "data": "2017-01-23T00:00:00",
    "id_operadora": 3,
    "nome": "Carlos                                            "
}]

am using WebAPI with Entity Framework from database.

These are automatically generated classes .

{
using System;
using System.Collections.Generic;

public partial class Contato
{
    public int id { get; set; }
    public string telefone { get; set; }
    public string cor { get; set; }
    public Nullable<System.DateTime> data { get; set; }
    public int id_operadora { get; set; }
    public string nome { get; set; }

    public virtual Operadora Operadora { get; set; }
  }
}

using System;
using System.Collections.Generic;

public partial class Operadora
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public Operadora()
    {
        this.Contato = new HashSet<Contato>();
    }

    public int id { get; set; }
    public string nome { get; set; }
    public Nullable<int> codigo { get; set; }
    public string categoria { get; set; }
    public string preco { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<Contato> Contato { get; set; }
 }
}

My problem and the next one, foreign key for Operadora, when in the contact’s registration I put the same id_operadora the JSON returns all who are with the same id_operadora all in the same NO.

anyone knows , how could solve this ? each registration in your NO ?

1 answer

1

What is happening is that you have a cyclic reference in your mapping (1 contact has an operator and an operator has a contact number).

Basically, you can solve it in two ways:

The first and most appropriate is to use the attribute JsonIgnore in Collection within the contact class and where else you wish it to be ignored by the JSON serializer.

using System;
using System.Collections.Generic;
using Newtonsoft.Json;

public partial class Operadora
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public Operadora()
    {
        this.Contato = new HashSet<Contato>();
    }

    public int id { get; set; }
    public string nome { get; set; }
    public Nullable<int> codigo { get; set; }
    public string categoria { get; set; }
    public string preco { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    [JsonIgnore]
    public virtual ICollection<Contato> Contato { get; set; }
 }
}

The second that is also useful most do not recommend, is divided into two steps:

Configure your Dbcontext to not create proxy classes.

DbContext.Configuration.ProxyCreationEnabled = false;

And configure the JSON serializer to ignore cyclic references:

public static void ConfigWebApi(HttpConfiguration config)
{
    var formatters = config.Formatters;
    formatters.Remove(formatters.XmlFormatter);

    var jsonSettings = formatters.JsonFormatter.SerializerSettings;
    jsonSettings.Formatting = Formatting.None;
    jsonSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

    formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.None;
    formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
 }

As it stands, in addition to generating unnecessary feedback from JSON, you can create a bottleneck in your Web API, I strongly recommend reading the Free Red Gate e-book featuring 25 tips to improve the performance of ASP.NET applications.

Browser other questions tagged

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