web-dev-qa-db-ja.com

Web APIで応答をシリアル化できませんでした

私はASP.NET MVC Web APIで作業していましたが、このエラーが発生しています:

'ObjectContent`1'タイプは、コンテンツタイプ 'application/xmlの応答本文のシリアル化に失敗しました。 charset = utf-8 '。

私のコントローラーは:

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

このエラーが発生するのはなぜですか?

84
Tamal kanti Dey

私にとって、これは循環参照の問題でした。

受け入れられた答えは、JSONフォーマッターの動作を変更するだけなので、うまくいきませんでしたが、ブラウザーからサービスを呼び出したときにXMLを取得していました。

これを修正するために、XMLをオフにし、JSONのみを強制的に返しました。

Global.asaxファイルで、Application_Startメソッドの先頭に次の行を追加します。

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

これで、JSONの結果のみが返されます。 XMLの結果が必要な場合は、別のソリューションを見つける必要があります。

118
Zane

global.asaxファイルのApplication_start()メソッドに次の行を追加します。

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

お役に立てばと思います!

43

同じ問題が発生しました。そして、私はそれを解決しました。デフォルトのコンストラクターをDTOクラスに配置します。

例:

public class User
{
    public User()
    {
    }
}

それがあなたとうまくいくことを願っています!

29
taynguyen

これをコンストラクターに入れます。これが問題を解決することを願っています:

    public MyController()
    {

        db.Configuration.ProxyCreationEnabled = false;
    }
21
Sadjad Khazaie

これには2つの解決策が見つかりました。最初に実装する最も簡単な方法は、IEnumerables、ICollectionsをList型に変更することです。 WebAPIはこのオブジェクトをシリアル化できますが、インターフェイスタイプをシリアル化することはできません。

public class Store
{

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

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

他のオプションは、ネイティブJSONシリアライザーを使用せず、WebApi ConfigのRegisterメソッドでこのオーバーライドを実行することです。

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

解決策は簡単です。

LINQクエリの後に.ToList()(または必要に応じてToDictionary)を追加します。

データの遅延読み込みよりも積極的な読み込みを行います

7
om471987

Global.asaxに以下のコードを追加する以外に、EFで作業している場合

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

インポートすることを忘れないでください

using System.Data.Entity;

その後、独自のEFモデルを返すことができます

4
Lucas Roselli

**このバグは、リクエストWeb API/WCF/...からクライアント側から呼び出すときに発生しますが、副作用として、includeキーワードで依存関係を含める必要があります。 **

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

Entity FrameworkでWeb APIを使用する場合、ソリューションは JsonでWeb APIの応答をシリアル化できませんでした

基本的に、各EFモデルに対応するモデルを作成する必要があります。これにより、クラス間の依存関係がなくなり、簡単なシリアル化が可能になります。

コード:(参照リンクから取得)

UserModelを作成する

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

メソッド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;
    }
}
3
Tung Nguyen

この問題については、Web APIドキュメントを確認してください。 円形オブジェクト参照の処理

よろしく

3

うーん、以下が役立つかもしれません。

私は同じ例外を受け取っていましたが、私の場合、最初にエンティティコード用に作成された実際のpocoエンティティを渡していました。他のエンティティとの関係が含まれているので、その上に返すためにviewmapper/dtoエンティティを作成しました。

今は正常に動作します。

Pocoエンティティ:

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;}
}
1
aamir sajjad

しかし、他のエンティティ/クラスでこの問題を見つけた場合は、各クラスに新しいDTOを作成する必要があり、それらが多数ある場合は問題を見つけることができます。また、この問題を解決するためだけにDTOを作成すると思います最善の方法ではありません...

これを試しましたか?

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

よろしく

1

デフォルトエンティティ6はXMLを使用 APIに、プロジェクト内でファイルを見つけます"Global.asax" Fileそしてこの行を追加します:

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

この行は、XML Formatterを削除します。

1
Roberth Solís

あなたの質問は私の質問とよく似ています。データベースから直接データを返さないでください。このためには、モデルを作成し、表示するデータを関連付ける必要があります。

私の例では、Jsonがシリアル化できなかったUserに関するデータがあり、userModelを作成し、APIでデータベースからUserの代わりにuserModelを返します。

UserとUserModel間のデータの変換または関連付けのロジックは、APIに含まれている必要があります。

Jsonを使用したWeb APIでの応答のシリアル化に失敗しました

0
CampDev

これは、odata Web API呼び出しから返された特定のエラーです。

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

最後に、dbContextクラスに不完全にフォーマットされたテーブル名がonModelCreatingで割り当てられていることがわかりました。そのため、SqlClientは私のデータベースに存在しなかったテーブル !!

0
bkwdesign