webentwicklung-frage-antwort-db.com.de

Die Antwort in der Web-API konnte nicht mit Json serialisiert werden

Ich arbeite mit ASP.NET MVC 5 Web Api. Ich möchte alle meine Benutzer konsultieren.

Ich hab geschrieben api/users und ich erhalte das:

"Der Typ" ObjectContent`1 "konnte den Antworttext für den Inhaltstyp" application/json; charset = utf-8 "nicht serialisieren."

In WebApiConfig habe ich bereits folgende Zeilen hinzugefügt:

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

Aber es geht immer noch nicht.

Meine Funktion für Rückgabedaten ist folgende:

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

Wenn es darum geht, Daten von Web Api (oder einem anderen Webdienst) an den Konsumenten zurückzugeben, empfehle ich dringend, Entitäten, die aus einer Datenbank stammen, nicht zurückzugeben. Es ist viel zuverlässiger und wartbarer, Modelle zu verwenden, in denen Sie die Kontrolle darüber haben, wie die Daten aussehen und nicht die Datenbank. Auf diese Weise müssen Sie nicht so sehr mit den Formatierern in der WebApiConfig herumspielen. Sie können einfach ein UserModel mit untergeordneten Modellen als Eigenschaften erstellen und die Referenzschleifen in den Rückgabeobjekten entfernen. Das macht den Serializer viel glücklicher.

Außerdem ist es normalerweise nicht erforderlich, Formatierer oder unterstützte Medientypen zu entfernen, wenn Sie nur den Header "Akzeptiert" in der Anforderung angeben. Das Herumspielen mit diesen Dingen kann die Dinge manchmal verwirrender machen.

Beispiel:

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

Wenn Sie mit EF arbeiten, fügen Sie zusätzlich den folgenden Code in Global.asax hinzu

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

Vergessen Sie nicht zu importieren

using System.Data.Entity;

Dann können Sie Ihre eigenen EF-Modelle zurückgeben

So einfach ist das!

130
Lucas Roselli

Die richtige Antwort ist eine Möglichkeit, es ist jedoch ein Overkill, wenn Sie es durch eine Konfigurationseinstellung beheben können.

Besser im dbcontext-Konstruktor verwenden

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

Asp.Net Web API-Fehler: Der Typ "ObjectContent`1" konnte den Antworttext für den Inhaltstyp "application/xml; charset = utf-8" nicht serialisieren.

51

Fügen Sie diesen Code zu global.asax Unter Application_Start Hinzu:

Update von .Ignore Auf .Serialize. Es muss funktionieren.

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize;
            GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
32
Bimal Das
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();
    }
}
10
Aykut

Ich mag diesen Code nicht:

foreach(var user in db.Users)

Alternativ könnte man so etwas machen, was für mich funktioniert hat:

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

                         });

return listOfUsers.ToList();

Am Ende habe ich jedoch Lucas Rosellis Lösung verwendet.

pdate: Vereinfacht durch Rückgabe eines anonymen Objekts:

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

return listOfUsers.ToList();
10

Ich habe es mithilfe dieses Codes in der Datei WebApiConfig.cs gelöst

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

Hinzufügen dieses in Ihrer Application_Start() Methode von Global.asax Datei sollte das Problem lösen

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

METHODE 2: [Nicht empfohlen]
Wenn Sie mit EntityFramework arbeiten, können Sie den Proxy in Ihrem DbContext-Klassenkonstruktor deaktivieren. HINWEIS: Dieser Code wird entfernt, wenn Sie das Modell aktualisieren

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

Es gibt auch dieses Szenario, das den gleichen Fehler erzeugt:

Im Falle der Rückkehr ist ein List<dynamic> Web-API-Methode

Beispiel:

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; }
}

Verwenden Sie für dieses Szenario das [KnownTypeAttribute] in der Rückgabeklasse (alle) wie folgt:

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

Das funktioniert bei mir!

6
Alex

Mein persönlicher Favorit: Fügen Sie einfach den folgenden Code zu App_Start/WebApiConfig.cs Hinzu. Dies gibt standardmäßig json anstelle von XML zurück und verhindert auch den Fehler, den Sie hatten. Es ist nicht erforderlich, Global.asax Zu bearbeiten, um XmlFormatter usw. zu entfernen.

Der Typ "ObjectContent`1" konnte den Antworttext für den Inhaltstyp "application/xml" nicht serialisieren. Zeichensatz = utf-8

config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
4
Ogglas

Verwenden Sie den folgenden Namespace:

using System.Web.OData;

Anstatt :

using System.Web.Http.OData;

Es hat bei mir funktioniert

2
Harish K

Lösung, die bei mir funktioniert hat:

  1. Verwenden Sie [DataContract] für Klassen- und [DataMember] -Attribute für jede zu serialisierende Eigenschaft. Dies reicht aus, um das Json-Ergebnis zu erhalten (zum Beispiel vom Fiddler).

  2. Um die XML-Serialisierung zu erhalten, schreiben Sie in Global.asax diesen Code:

    var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter; xml.UseXmlSerializer = true;

  3. Lesen Sie diesen Artikel, es hat mir geholfen, die Serialisierung zu verstehen: https://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization
2

Verwenden Sie AutoMapper ...

public IEnumerable<User> GetAll()
    {
        using (Database db = new Database())
        {
            var users = AutoMapper.Mapper.DynamicMap<List<User>>(db.Users);
            return users;
        }
    }
2
Proximo

Sie müssen Serializer Formatter in der Datei WebApiConfig.cs definieren, die im Ordner App_Start verfügbar ist

Hinzufügen von config.Formatters.Remove (config.Formatters.XmlFormatter); // was Ihnen Daten im JSON-Format liefert

Hinzufügen von config.Formatters.Remove (config.Formatters.JsonFormatter); // was Ihnen Daten im XML-Format liefert

1
Yogesh Dangre

Um zu jensendps Antwort hinzuzufügen:

Ich würde die Entität an ein vom Benutzer erstelltes Modell übergeben und die Werte dieser Entität verwenden, um die Werte in Ihrem neu erstellten Modell festzulegen. Zum Beispiel:

public class UserInformation {
   public string Name { get; set; }
   public int Age { get; set; }

   public UserInformation(UserEntity user) {
      this.Name = user.name;
      this.Age = user.age;
   }
}

Ändern Sie dann Ihren Rückgabetyp in: IEnumerable<UserInformation>

1
Greg A

This is my error

Ich füge im Grunde eine Zeile hinzu, die sie sind

  • entity.Configuration.ProxyCreationEnabled = false;

zu 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);
            }
        }
    }
}

Here is my output:

1

In meinem Fall hatte ich eine ähnliche Fehlermeldung:

Der Typ "ObjectContent`1" konnte den Antworttext für den Inhaltstyp "application/xml" nicht serialisieren. Zeichensatz = utf-8 '.

Aber als ich mich näher damit beschäftigte, war das Problem:

Geben Sie 'name.SomeSubRootType' mit dem Datenvertragsnamen 'SomeSubRootType: //schemas.datacontract.org/2004/07/WhatEverService' ein. Ziehen Sie die Verwendung eines DataContractResolver in Betracht, wenn Sie DataContractSerializer verwenden oder Typen, die statisch nicht bekannt sind, zur Liste der bekannten Typen hinzufügen, z. B. mithilfe des Attributs KnownTypeAttribute oder indem Sie sie zur Liste der bekannten Typen hinzufügen, die an den Serializer übergeben werden.

Wie ich es gelöst habe, indem ich KnownType hinzugefügt habe.

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

Dies wurde gelöst, inspiriert von Antwort .

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

In meinem Fall habe ich die Neuerstellung der Datenbank gelöst. Ich habe einige Änderungen an einem Modell vorgenommen und Update-Database in Package Manager Console gestartet. Ich habe den folgenden Fehler erhalten:

"Die ALTER TABLE-Anweisung ist mit der FOREIGN KEY-Einschränkung" FK_dbo.Activities_dbo.Projects_ProjectId "in Konflikt geraten. Der Konflikt ist in der Datenbank" TrackEmAllContext-20190530144302 ", Tabelle" dbo.Projects ", Spalte 'Id' aufgetreten."

0
Manuel Sansone

Falls: Wenn das Hinzufügen von Code zu WebApiConfig.cs oder Global.asax.cs bei Ihnen nicht funktioniert:

.ToList();

Fügen Sie die Funktion .ToList () hinzu.

Ich habe jede Lösung ausprobiert, aber folgendes hat für mich funktioniert:

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

Ich hoffe, es hilft.

0
Catalyst

Visual Studio 2017 oder 2019 ist diesbezüglich völlig unüberlegt, da Visual Studio selbst die Ausgabe im Format json erfordert, während das Standardformat von Visual Studio "XmlFormat" (config.Formatters.XmlFormatter) lautet ).

Visual Studio sollte dies automatisch tun, anstatt den Entwicklern so viele Probleme zu bereiten.

Wechseln Sie zu der Datei WebApiConfig.cs und fügen Sie hinzu, um dieses Problem zu beheben

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

nach "config.MapHttpAttributeRoutes ();" in der Register (HttpConfiguration config) -Methode. Dies würde es Ihrem Projekt ermöglichen, eine json-Ausgabe zu erzeugen.

0
William Hou

Ein anderer Fall, in dem ich diesen Fehler erhielt, war, als meine Datenbankabfrage einen Nullwert zurückgab, aber mein Benutzer-/Ansichtsmodelltyp als nicht nullwertfähig festgelegt wurde. Beispiel: Ändern des UserModel-Felds von int in int? aufgelöst.

0
marshall

Dies passiert auch, wenn der Antworttyp nicht öffentlich ist! Ich habe eine interne Klasse zurückgegeben, als ich mit Visual Studio den Typ generiert habe.

internal class --> public class
0
Vanice

Fügen Sie die folgende Zeile hinzu

this.Configuration.ProxyCreationEnabled = false;

Zwei Möglichkeiten, ProxyCreationEnabled als false zu verwenden.

  1. Fügen Sie es innerhalb von DBContext Constructor hinzu

    public ProductEntities() : base("name=ProductEntities")
    {
        this.Configuration.ProxyCreationEnabled = false;
    }
    

ODER

  1. Fügen Sie die Zeile innerhalb der Methode Get hinzu

    public IEnumerable<Brand_Details> Get()
    {
        using (ProductEntities obj = new ProductEntities())
        {
            this.Configuration.ProxyCreationEnabled = false;
            return obj.Brand_Details.ToList();
        }
    }
    
0
Sudipta Saha

Während all diese Antworten korrekt sind, kann es sinnvoll sein, die InnerException> ExceptionMessage zu überprüfen.

Wenn es so aussagt: "T Die ObjectContext-Instanz wurde freigegeben und kann nicht mehr für Vorgänge verwendet werden, die eine Verbindung erfordern.". Dies kann ein Problem aufgrund des Standardverhaltens der EF sein.

Durch Zuweisen von LazyLoadingEnabled = false in Ihrem DbContext-Konstruktor wird der Trick ausgeführt.

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

Ausführlichere Informationen zum EagerLoading- und LazyLoading-Verhalten von EF finden Sie hier MSDN-Artikel .

0
Bhramar

Verwenden Sie [Serializable] für die Klasse:

Beispiel:

[Serializable]
public class UserModel {
    public string Name {get;set;}
    public string Age {get;set;}
}

Es hat bei mir funktioniert!

0
Msxmania