Kan het antwoord in Web API niet serialiseren met Json

Ik werk met ASP.NET MVC 5 Web Api. Ik wil al mijn gebruikers raadplegen.

Ik heb api/usersgeschreven en ik ontvang dit:

“Het type ‘ObjectContent`1’ kan de antwoordtekst voor inhoudstype ‘application/json; charset=utf-8’ niet serialiseren”

In WebApiConfig heb ik deze regels al toegevoegd:

HttpConfiguration config = new HttpConfiguration();
config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; 

Maar het werkt nog steeds niet.

Mijn functie voor het retourneren van gegevens is deze:

public IEnumerable<User> GetAll()
{
    using (Database db = new Database())
    {
        return db.Users.ToList();
    }
}

Antwoord 1, autoriteit 100%

Als je met EF werkt, voeg dan de onderstaande code toe op Global.asax

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

Vergeet niet te importeren

using System.Data.Entity;

Dan kun je je eigen EF-modellen retourneren

Zo simpel is het!


Antwoord 2, autoriteit 52%

Als het gaat om het terugsturen van gegevens naar de consument van Web Api (of welke andere webservice dan ook), raad ik ten zeerste aan geen entiteiten terug te geven die uit een database komen. Het is veel betrouwbaarder en onderhoudbaarder om modellen te gebruiken waarin u controle heeft over hoe de gegevens eruit zien en niet de database. Op die manier hoef je niet zo veel te rommelen met de formatters in de WebApiConfig. U kunt gewoon een UserModel maken met onderliggende modellen als eigenschappen en de referentielussen in de retourobjecten verwijderen. Dat maakt de serializer veel gelukkiger.

Het is ook niet nodig om formatters of ondersteunde mediatypen te verwijderen, meestal als u alleen de “Accepts”-header in het verzoek opgeeft. Met dat soort dingen spelen kan de dingen soms verwarrender maken.

Voorbeeld:

public class UserModel {
    public string Name {get;set;}
    public string Age {get;set;}
    // Other properties here that do not reference another UserModel class.
}

Antwoord 3, autoriteit 35%

Het juiste antwoord geven is een manier om te gaan, maar het is een overkill als je het kunt oplossen met één configuratie-instellingen.

Het is beter om het te gebruiken in de dbcontext-constructor

public DbContext() // dbcontext constructor
            : base("name=ConnectionStringNameFromWebConfig")
{
     this.Configuration.LazyLoadingEnabled = false;
     this.Configuration.ProxyCreationEnabled = false;
}

Asp.Net Web API-fout: het type ‘ObjectContent’1’ kan de antwoordtekst voor inhoudstype ‘application/xml; charset=utf-8’


Antwoord 4, autoriteit 25%

Voeg deze code toe aan Global.asaxhieronder op Application_Start:

Update van .Ignorenaar .Serialize. Het moet werken.

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize;
            GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);

Antwoord 5, autoriteit 7%

public class UserController : ApiController
{
   Database db = new Database();
   // construction
   public UserController()
   {
      // Add the following code
      // problem will be solved
      db.Configuration.ProxyCreationEnabled = false;
   }
   public IEnumerable<User> GetAll()
    {
            return db.Users.ToList();
    }
}

Antwoord 6, autoriteit 7%

Ik heb het opgelost met behulp van deze code naar het bestand WebApiConfig.cs

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

Antwoord 7, autoriteit 6%

Ik vind deze code niet leuk:

foreach(var user in db.Users)

Als alternatief zou je zoiets als dit kunnen doen, wat voor mij werkte:

var listOfUsers = db.Users.Select(r => new UserModel
                         {
                             userModel.FirstName = r.FirstName;
                             userModel.LastName = r.LastName;
                         });
return listOfUsers.ToList();

Echter, ik heb uiteindelijk de oplossing van Lucas Roselli gebruikt.

Update: vereenvoudigd door een anoniem object terug te sturen:

var listOfUsers = db.Users.Select(r => new 
                         {
                             FirstName = r.FirstName;
                             LastName = r.LastName;
                         });
return listOfUsers.ToList();

Antwoord 8, autoriteit 5%

Als u dit toevoegt aan uw Application_Start()-methode van het Global.asax-bestand, zou het probleem moeten worden opgelost

protected void Application_Start()
{
    GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings
        .ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
    GlobalConfiguration.Configuration.Formatters
        .Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter); 
// ...
}

METHODE 2: [Niet aanbevolen]
Als u met EntityFramework werkt, kunt u proxy uitschakelen in uw DbContext-klassenconstructor. OPMERKING: deze code wordt verwijderd als u het model bijwerkt

public class MyDbContext : DbContext
{
  public MyDbContext()
  {
    this.Configuration.ProxyCreationEnabled = false;
  }
}

Antwoord 9, autoriteit 4%

Er is ook dit scenario dat dezelfde fout genereert:

In het geval dat de retour een List<dynamic>-methode is naar web-api

Voorbeeld:

public HttpResponseMessage Get()
{
    var item = new List<dynamic> { new TestClass { Name = "Ale", Age = 30 } };
    return Request.CreateResponse(HttpStatusCode.OK, item);
}
public class TestClass
{
    public string Name { get; set; }
    public int Age { get; set; }
}

Dus, gebruik voor dit scenario het [KnownTypeAttribute] in de return-klasse (allemaal) als volgt:

[KnownTypeAttribute(typeof(TestClass))]
public class TestClass
{
    public string Name { get; set; }
    public int Age { get; set; }
}

Dit werkt voor mij!


Antwoord 10

In mijn geval heb ik een soortgelijke foutmelding gehad:

Het type ‘ObjectContent`1’ kan de antwoordtekst niet serialiseren voor
inhoudstype ‘applicatie/xml; charset=utf-8’.

Maar toen ik er dieper in graaf, was het probleem:

Typ ‘naam.SomeSubRootType’
met datacontractnaam
‘SomeSubRootType://schemas.datacontract.org/2004/07/WhatEverService’
wordt niet verwacht. Overweeg om een ​​DataContractResolver te gebruiken als u:
gebruik DataContractSerializer of voeg typen toe die niet statisch bekend zijn aan
de lijst met bekende typen – bijvoorbeeld door het KnownTypeAttribute . te gebruiken
attribuut of door ze toe te voegen aan de lijst met bekende typen die zijn doorgegeven aan de
serializer.

De manier waarop ik het heb opgelost door KnownTypetoe te voegen.

[KnownType(typeof(SomeSubRootType))]
public partial class SomeRootStructureType

Dit is opgelost op basis van dit antwoord .

Referentie: https://msdn. microsoft.com/en-us/library/ms730167(v=vs.100).aspx


Antwoord 11

Dit is mijn fout

Ik voeg eigenlijk één regel toe en dat zijn ze

  • entities.Configuration.ProxyCreationEnabled = false;

naar UsersController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using UserDataAccess;
namespace SBPMS.Controllers
{
    public class UsersController : ApiController
    {
        public IEnumerable<User> Get() {
            using (SBPMSystemEntities entities = new SBPMSystemEntities()) {
                entities.Configuration.ProxyCreationEnabled = false;
                return entities.Users.ToList();
            }
        }
        public User Get(int id) {
            using (SBPMSystemEntities entities = new SBPMSystemEntities()) {
                entities.Configuration.ProxyCreationEnabled = false;
                return entities.Users.FirstOrDefault(e => e.user_ID == id);
            }
        }
    }
}

Hier is mijn uitvoer:


Antwoord 12

U moet Serializer Formatter definiëren in WebApiConfig.cs beschikbaar in App_Start Folder zoals

Configuratie.Formatters.Remove(config.Formatters.XmlFormatter) toevoegen;
// waarmee u gegevens in JSON-indeling krijgt

Configuratie.Formatters.Remove(config.Formatters.JsonFormatter) toevoegen;
// waarmee u gegevens in XML-indeling krijgt


Antwoord 13

Een ander geval waarin ik deze fout ontving, was toen mijn databasequery een null-waarde retourneerde, maar mijn gebruiker/view-modeltype was ingesteld als niet-nullable. Bijvoorbeeld het wijzigen van mijn UserModel-veld van intin int?opgelost.


Antwoord 14

Dit gebeurt ook als het Response-Type niet openbaar is!
Ik heb een interne klasse geretourneerd omdat ik Visual Studio heb gebruikt om het type te genereren.

internal class --> public class

Antwoord 15

Visual Studio 2017 of 2019 is hier totaal ondoordacht over, omdat Visual Studio zelf vereist dat de uitvoer in de json-indeling is, terwijl de standaardindeling van Visual Studio “XmlFormat” is (config.Formatters .XmlFormatter).

Visual Studio zou dit automatisch moeten doen in plaats van ontwikkelaars zoveel problemen te geven.

Om dit probleem te verhelpen, gaat u naar het bestand WebApiConfig.csen voegt u

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

na “config.MapHttpAttributeRoutes();” in de Register(HttpConfiguration config)methode. Hierdoor kan uw project json-uitvoer produceren.


Antwoord 16

In mijn geval heb ik het opnieuw maken van de database opgelost.
Ik heb enkele wijzigingen aangebracht in een model en bij het starten van Update-Database in Package Manager Console kreeg ik de volgende fout:

“De ALTER TABLE-instructie was in strijd met de FOREIGN KEY-beperking “FK_dbo.Activities_dbo.Projects_ProjectId”. Het conflict deed zich voor in de database “TrackEmAllContext-20190530144302”, tabel “dbo.Projects”, kolom ‘Id’.”


Antwoord 17

In het geval: als het toevoegen van code aan WebApiConfig.csof Global.asax.csniet voor u werkt:

.ToList();

Voeg .ToList() functie toe.

Ik heb elke oplossing uitgeprobeerd, maar het volgende werkte voor mij:

var allShops = context.shops.Where(s => s.city_id == id)**.ToList()**;
return allShops;

Ik hoop dat het helpt.


Antwoord 18

in mijn geval was het opgelost toen ik het virtuele trefwoord verwijderde voor mijn navigatie-eigenschappen,
Ik bedoel de referentietabellen.
dus ik veranderde

public virtual MembershipType MembershipType { get; set; }

naar:

public MembershipType MembershipType { get; set; }

Other episodes