web-dev-qa-db-fra.com

Erreur d'API Web Asp.Net: le type 'ObjectContent`1' n'a pas réussi à sérialiser le corps de réponse pour le type de contenu 'application / xml; charset = utf-8 '

Exemple le plus simple, j'obtiens une collection et j'essaye de la sortir via l'API Web:

// GET api/items
public IEnumerable<Item> Get()
{
    return MyContext.Items.ToList();
}

Et je reçois l'erreur:

Objet de type
'System.Data.Objects.ObjectQuery`1 [Dcip.Ams.BO.EquipmentWarranty]' ne peut pas être converti en type
'System.Data.Entity.DbSet`1 [Dcip.Ams.BO.EquipmentWarranty]'

Il s'agit d'une erreur assez courante avec les nouveaux proxys, et je sais que je peux la corriger en définissant:

MyContext.Configuration.ProxyCreationEnabled = false;

Mais cela va à l'encontre de l'objectif de beaucoup de ce que j'essaie de faire. Y a-t-il une meilleure façon?

35
naspinski

Je suggérerais de désactiver la création de proxy uniquement à l'endroit où vous n'en avez pas besoin ou qui vous cause des problèmes. Vous n'avez pas à le désactiver globalement, vous pouvez simplement désactiver le contexte DB actuel via le code ...

    [HttpGet]
    [WithDbContextApi]
    public HttpResponseMessage Get(int take = 10, int skip = 0)
    {
        CurrentDbContext.Configuration.ProxyCreationEnabled = false;

        var lista = CurrentDbContext.PaymentTypes
            .OrderByDescending(x => x.Id)
            .Skip(skip)
            .Take(take)
            .ToList();

        var count = CurrentDbContext.PaymentTypes.Count();

        return Request.CreateResponse(HttpStatusCode.OK, new { PaymentTypes = lista, TotalCount = count });
    }

Ici, j'ai uniquement désactivé la ProxyCreation dans cette méthode, car pour chaque demande, un nouveau DBContext est créé et, par conséquent, je n'ai désactivé la ProxyCreation que pour ce cas. J'espère que ça aide

24
visar_uruqi

si vous avez des propriétés de navigation et que vous ne voulez pas les rendre non virtuelles, vous devez utiliser JSON.NET et changer la configuration dans App_Start pour utiliser JSON et non XML!
après avoir installé JSON.NET à partir de NuGet, insérez ce code dans WebApiConfig.cs dans la méthode Register

var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);
25
Mahdi

Si vous avez des propriétés de navigation, rendez-les non virtuelles. Le mappage fonctionne toujours, mais il empêche la création d'entités de proxy dynamique qui ne peuvent pas être sérialisées.]

Ne pas avoir de chargement paresseux est très bien dans un WebApi car vous n'avez pas de connexion persistante et vous avez quand même exécuté un .ToList ().

12
Oliver

Je viens de désactiver les classes proxy selon les besoins:

    // GET: ALL Employee
    public IEnumerable<DimEmployee> Get()
    {
        using (AdventureWorks_MBDEV_DW2008Entities entities = new AdventureWorks_MBDEV_DW2008Entities())
        {
            entities.Configuration.ProxyCreationEnabled = false;
            return entities.DimEmployees.ToList();
        }
    }
7
mbdevlists

Cela m'a aidé:
Ajoutez le code suivant dans Application_Start fonction de Global.asax.cs

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings
    .ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
GlobalConfiguration.Configuration.Formatters
    .Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
4
Adrita Sharma

Dans mon cas, l'objet renvoyé avait une propriété en lui avec un type qui n'avait pas de constructeur sans argument/par défaut. En ajoutant un constructeur à zéro argument à ce type, l'objet a pu être sérialisé avec succès.

3
Josh