yanıtı Web API'de seri hale getiremedi


86

ASP.NET MVC web API üzerinde çalışıyordum, şu hatayı alıyorum:

'ObjectContent`1' türü, içerik türü 'application / xml için yanıt gövdesini serileştiremedi; karakter kümesi = utf-8 '.

Denetleyicim:

public Employee GetEmployees()
{
    Employee employees = db.Employees.First();
    return employees;
}

neden bu hatayı alıyorum?


6
Gördüğünüz istisna, birçok faktörden kaynaklanabilen genel bir istisnadır. InnerExceptionSerileştirmenin başarısız olmasına tam olarak neyin neden olduğunu bulmak için serileştirme istisnasının özelliğini kontrol edin .
Görünen Ad

Çalışan türünüz için kodu paylaşabilir misiniz? Bunun nedeni Çalışan türünün serileştirilememesi olabilir ...
Maggie Ying


Yanıtlar:


121

Benim için bu döngüsel referansla ilgili bir sorundu.

Kabul edilen yanıt benim için işe yaramadı çünkü yalnızca JSON biçimlendiricinin davranışını değiştirdi, ancak hizmeti tarayıcıdan çağırdığımda XML alıyordum.

Bunu düzeltmek için XML'yi kapattım ve yalnızca JSON'u döndürmeye zorladım.

Global.asax dosyasında, Application_Start yönteminizin en üstüne aşağıdaki satırları koyun:

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

Artık yalnızca JSON sonuçları döndürülecek. XML sonuçlarına ihtiyacınız varsa, farklı bir çözüm bulmanız gerekecektir.


benim için çalıştı. ama mesele şu ki POSTMAN kullanıyorum. bu bir krom uzantısıdır. POSTMAN ile veri gönderdiğimde iyi çalışıyor. ama restsharp kullandığımda bana bu hatayı veriyor. her neyse, çözümünüz sorunumu çözdü
ArgeKumandan

Bu cevap, xml kullanmak için bir çözüm sağlamaz ve onun istediği de budur.
honestduane

Xml'den json'a geçerken benim için çalışıyor.
Sike12

Aslında bu cevap sorunun kökenine iniyor. Aldığım ilk hata dairesel bir referans hatasıydı (JSON'u MVC denetleyicisinden döndürmeye çalışırken). API devralınan bir denetleyiciye geçtiğimde, bunun yerine bu hatayı almaya başladım. Yukarıdaki kodu Global.asax'a eklediğimde hata ortadan kalktı.
Matthew Pitts

43

global.asax dosyanızda, Application_start () yönteminde şu satırı ekleyin:

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;

Umarım bu size yardımcı olur!


3
Application_start nedir ve nerede bulunabilir? Ve bu çizgi tam olarak nereye yerleştirilmelidir?
Ciaran Gallagher

4
Üzgünüm ama bu ifadenin anlamı nedir?
Blaise

5
Eklenen Çizgi Global.asaxs' Application_Start, ancak hiçbir değişiklik.
cheesus

8
Bu hala benim için işe yaramadı. Ancak bu cevaptaki satırdan sonra başka bir satır ekledim ve işe yaradı: GlobalConfiguration.Configuration.Formatters.Remove (GlobalConfiguration.Configuration.Formatters.XmlFormatter); Aşağıda daha eksiksiz bir cevap oluşturdum
Zane

2
Bu yanıt, XmlSerializer ile döngüsel başvuru sorununu ele almak yerine XmlSerializer'ı gerçekten kaldırdığından kabul edilmemelidir.
Believe2014

29

Ben de aynı sorunu yaşıyorum. Ve ben çözdüm. Varsayılan kurucuyu DTO sınıfına koydum.

Ör:

public class User
{
    public User()
    {
    }
}

Umarım sizinle çalışır!


Öneriniz için teşekkürler, bu xml yanıtında bana yardımcı oldu, ancak neden varsayılan bir kurucuya ihtiyaç duyduğunu bilen var mı? Veriler elimizde zaten ...
Ilya Chernomordik

Sanırım bir nesne yanıttan serileştirildiğinde, önce nesnenin örneğini oluşturmak için kurucu çağrıldı, daha sonra verileri nesne örneğine ayarlamak için set yöntemi kullanıldı. Benim tahminim bu.
taynguyen

İhtiyacınız olan iade türleri hakkında herhangi bir varsayımda bulunmadığından, bu aslında seçilen cevap olmalıdır. Bu hem XML hem de JSON için çalışacaktır. Bunu gönderdiğiniz için teşekkürler.
Allen Underwood

22

Bunu yapıcıya koyun. Umarım bu sorunu çözer:

    public MyController()
    {

        db.Configuration.ProxyCreationEnabled = false;
    }

Mükemmel çözüm. Yapıcıya koymam gerekiyor ve işe yaradı.
InsParbo

Bu, GlobalConfiguration ayarlarıyla birlikte benim için çalıştı. Peki bu neden işe yarıyor? Bunun sorunu nasıl çözdüğüne dair herhangi bir açıklama var mı? Ve aslında sorun neydi?
Ciaran Gallagher

Varlık proxy'lerinin ne olduğunu anlamak için: msdn.microsoft.com/en-us/library/jj592886(v=vs.113).aspx ProxyCreationEnabled'ın ne olduğunu anlamak için: stackoverflow.com/questions/7111109/…
Sadjad Khazaie

16

Buna iki çözüm buldum. Uygulanması ilk ve en kolay yöntem, herhangi bir IEnumerables, ICollections'ı bir Liste türüne değiştirmektir. WebAPI bu nesneleri serileştirebilir, ancak arabirim türlerini serileştiremez.

public class Store
{

  [StringLength(5)]
    public string Zip5 { get; set; }

    public virtual List<StoreReport> StoreReports { get; set; }  //use a list here
 }

Diğer seçenek, yerel JSON serileştiriciyi kullanmamak ve bu geçersiz kılmayı WebApi Yapılandırmasının Register yönteminde çalıştırmaktır:

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

1
Listeye geçiş benim için çalıştı, parametresiz bir kurucu eklemek de benim için çalıştı ve IEnumerable <Widget>
Mike Cheel

8

Çözüm basit.

LINQ sorgusundan sonra .ToList () (veya gerekirse ToDictionary) ekleyin.

Verilerin tembel yüklenmesinden daha istekli yükleme yapacak


1
Eylem dönüş türünü olarak değiştirmek ve dönüşe IENumerableeklemek .TiList()benim için çalıştı.
Ricardo Souza

5

** bu hata, istemci tarafından istek web api / wcf / ... 'den çağrılırken ortaya çıkar, ancak yan etki olarak, include anahtar kelimesine göre bağlı ilişkileri eklemeniz gerekecektir. **

public CustomerPortalContext()
            : base("Name=CustomerPortalContext")
        {
            base.Configuration.ProxyCreationEnabled = false;
        }

4

EF ile çalışıyorsanız, aşağıdaki kodu Global.asax'a eklemenin yanı sıra

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

İçe aktarmayı unutma

using System.Data.Entity;

Ardından kendi EF Modellerinizi iade edebilirsiniz



3

Entity Framework ile web api kullanıyorsanız , Json ile Web API'de yanıtı serileştirmek için bir çözüm başarısız olabilir

Temel olarak, her EF modeline karşılık gelen bir model oluşturmanız gerekir; bu, sınıflar arasındaki bağımlılıkları ortadan kaldırır ve kolay serileştirmeye olanak tanır.

Kod: (başvurulan bağlantıdan alınmıştır)

Bir Kullanıcı Modeli Oluşturun

public class UserModel
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

Yöntemimi değiştir GetAll ()

public IEnumerable<UserModel> GetAll()
{
    using (Database db = new Database ())
    {
        List<UserModel> listOfUsers = new List<UserModel>();
        UserModel userModel = new UserModel();
        foreach(var user in db.Users)
        {
           userModel.FirstName = user.FirstName;
           userModel.LastName = user.LastName;
           listOfUsers.Add(userModel);
        }
        IEnumerable<UserModel> users = listOfUsers;

        return users;
    }
}

2

Varsayılan Varlık 6 , projenizde apis için XML kullanır, "Global.asax" Dosyasını bulun ve şu satırı ekleyin:

GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);

Bu satır, XML Biçimlendiriciyi kaldırır.


Merhaba, Web API yanıtı XML ve JSON'da serileştirir, Content-Type: application / json üstbilgisini eklerseniz, yanıt JSON'dadır, bu başlığı tanımlamanız gerekir, tarayıcıda her zaman XML biçiminde görebilirsiniz
Roberth Solís

1

ancak bu problemi diğer varlıklarda / sınıflarda bulduysanız, her sınıf için yeni bir DTO oluşturmanız gerekir ve eğer bunlardan çok varsa bir problem bulabilirsiniz, ayrıca bence sadece bu problemi çözmek için bir DTO yaratın en iyi yol değil ...

Bunu denedin mi

var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = 
Newtonsoft.Json.PreserveReferencesHandling.All;

Saygılarımızla


1

hmmm, Aşağıdakiler yardımcı olabilir.

Ben de aynı istisnayı alıyordum ve benim durumumda ilk önce varlık kodu için oluşturulan gerçek poco varlığını geçiyordum. Diğer varlıklar ile ilişki içerdiğinden, geri dönmek için üstüne viewmapper / dto varlığını oluşturdum.

Şimdi iyi çalışıyor.

Poco Varlığı:

public class Tag
{
public int Id{get;set;}
public string Title{get;set;}
public IList<Location> Locations{get;set;}
}

ViewMapper / Dto

public class TagResultsViewMapper
{
public int Id{get;set;}
public string Title{get;set;}
//just remove the following relationship 
//public IList<Location> Locations{get;set;}
}

0

Sorunuz benimkine oldukça benziyor. Verileri doğrudan veritabanından döndürmemelisiniz. Bunun için Model oluşturmalı ve göstermek istediğiniz verileri ilişkilendirmelisiniz.

Örneğimde, Json'ın serileştiremediği User hakkında veriler var, bir userModel oluşturdum ve API'mde userModel yerine userModel'i veritabanından döndürüyorum.

User ve UserModel arasındaki verileri dönüştürme veya ilişkilendirme mantığı API'de olmalıdır.

Yanıtı Web API'sinde Json ile seri hale getiremedi


0

Bu, odata Web API çağrımdan geri aldığım belirli hataydı:

The 'ObjectContent`1' type failed to serialize the response 
body for content type 'application/json; odata.metadata=minimal'.

Sonunda, dbContext sınıfımın onModelCreating'de atanmış kötü biçimlendirilmiş bir tablo adı olduğunu anladım .. bu yüzden SqlClient, db'mde bulunmayan bir tablo ararken ölüyordu !!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.