Return JSON with WEBAPI

0

I'm creating a WebApi where its return is the next.

[{
    "$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                                            "
}]

I am using WebAPI with Entity Framework from database .

These are the 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 is the following, I have a foreign key to Operadora , when in the contact register I put the same id_operadora the JSON returns all that are with the same id_operadora all in the same NO .

Anyone know how to solve this? every record in your NO?

    
asked by anonymous 25.01.2017 / 15:09

1 answer

0

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

Basically, you can solve it in two ways:

The first and most suitable is to use the JsonIgnore attribute in the collection within the class and where else you wish 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 not to 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 is, in addition to generating unnecessary feedback on JSON, you can create a bottleneck in your Web API, I highly recommend reading Red Gate free book that presents 25 tips to improve the performance of ASP.NET applications .

    
25.01.2017 / 15:37