13

EF4 CTP5で返されたオブジェクトをシリアル化しようとすると循環参照に問題があります。私のモデルにはコードの最初のアプローチとシンプルなポコを使っています。MVC3とEF4を使用したJSONシリアライゼーションの循環参照例外CTP5w

オブジェクトへの逆参照を提供するプロパティに[ScriptIgnore]属性を追加しました.Pocoを手動でインスタンス化するとうまくいくように見えます。つまり、JSONの罰金にシリアル化され、scriptignore属性が認識されます。しかし、DALから返されたオブジェクトをシリアル化しようとすると循環参照例外が発生する "循環参照が型 'System.Data.Entity.DynamicProxies.xxxx'のオブジェクトを直列化している間に検出された"

私はいくつか試したデータをretreivingの方法は、それらはすべて、このエラーで立ち往生:

public JsonResult GetTimeSlot(int id) { 
     TimeSlotDao tsDao = new TimeSlotDao(); 
     TimeSlot ts = tsDao.GetById(id); 
     return Json(ts); 
    } 

以下の方法は、円形のrefferenceにその任命オブジェクトを起こし少し良いとしてではなく、タイムスロットの動的プロキシになるオブジェクト動作します。

この問題の解決策はありますか?私は、可能な場合nuget経由Json.Netは、私は私も意図したとおりにそれを使用するのが可能に望んでいるだろう代替としてokですが、箱のシリアライザのうちを使用することを好むだろう

更新 ...

+0

場合、誰かが(ないベストプラクティス)「自動化」望んでいる余分なコードを必要としないこの問題の解決策、このQAをチェックアウト:[JSONで(ServiceStack.Textライブラリ)をEntity Frameworkのクラス参照をシリアライズしない](HTTP ://stackoverflow.com/questions/14998890/do-not-serialize-entity-framework-class-references-in-json-servicestack-text-li/15010306#15010306) – kape123

答えて

4

IISでホストされているWCFサービスで同様の問題が発生し、DataContractJsonSerializerクラスを使用してPOCOオブジェクトをシリアル化しようとしました。組み込みのJSONシリアライザは循環参照をまったく処理していないようです。 JSON.netシリアライザを使用して自分自身でシリアライズを処理し、自分のメソッドからjson文字列を返すだけで、私はそれを回避することができました。 JSON.netシリアライザには、JSON自体がサポートしていないため、循環参照を無視するオプションがあります。

+0

+1すべてのものJSONにNewtonsoftを使用します。ボーナスポイントはMVC3を使ってOPからNuGetを介して依存関係をインストールすることを指します。 –

2

ダイナミックプロキシが何をしっかり止めていたとしても、私はモデル内のすべての循環参照を取り除いていました。それでも問題は解決されませんでした。

私はJson.Netを試しましたが、同じ問題が発生しました。最後に

私は、カスタムコードを実装JavaScriptConverter

http://hellowebapps.com/2010-09-26/producing-json-from-entity-framework-4-0-generated-classes/

の使用についてのポストにつまずいたし、あなたの叔父のすべては、私が外部JSONに頼ることなく、これを解決し

+0

その投稿のコードはコンパイルされていないことがわかりました。コンパイルするのに十分な編集をしても、まだ機能しませんでした。ここに作業用のカスタムJavaScriptConverterクラスを投稿できますか? – codemonkey

+0

上記のリンクはもう動作しません! – TechnicalSmile

+0

@TechnicalSmile json.netを使用すると、この質問が投稿されて以来、多くの変更がありました。mvcスタックのデフォルトのjsonシリアライザであることがわかりました。また、問題の一部はEF4のCTPバージョンでした。プレリリースだった。 – nakchak

1

を働いたボブスシリアライザ。ナットシュートでは、私はオブジェクトのコンテキストのコンストラクタでProxyCreationを無効にしました。

私はこの作品、なぜわからないが、私は、私は次のようContractResolverを使用し、フォローアップの質問here.

+1

これを動作させるために遅延ロードを無効にしたいとは思いませんでした。 Annotingly ScriptIgnore属性は、EF4 CTP5プロキシ生成コードによって選択されていないようです。したがって、シリアライザがプロキシオブジェクトをシリアライズしようとすると、リレーションシップを再試行します。 この問題は、匿名オブジェクトを使用してJSONにシリアライズすることで、ほとんどの問題がオブジェクトグラフを完全に返そうとしたために軽減される可能性があります。 – nakchak

1

を掲載しました。 CamelCaseContractPropertyResolverから継承してその機能を取得することに注意してください。ただし、DefaultContractResolverから直接継承することもできます。

using System; 
using System.Collections.Generic; 
using System.Reflection; 
using Newtonsoft.Json.Serialization; 

namespace MyNamespace 
{ 
    /// <summary> 
    /// This class enables EntityFramework POCO objects to be serialized. In some cases POCO 
    /// objects are subclassed by a proxy which has an additional member _entityWrapper. This 
    /// object prevents serialization (circular references and references to non-serializable types). 
    /// This removes the _entityWrapper from the list of members to be serialized. 
    /// </summary> 
    public class ContractResolver : CamelCasePropertyNamesContractResolver 
    { 
     protected override List<MemberInfo> GetSerializableMembers(Type objectType) 
     { 
      if (objectType.FullName.StartsWith("System.Data.Entity.DynamicProxies.")) 
      { 
       var members = base.GetSerializableMembers(objectType); 
       members.RemoveAll(memberInfo => memberInfo.Name == "_entityWrapper"); 
       return members; 
      } 
      return base.GetSerializableMembers(objectType); 
     } 
    } 
} 

、それを使用するあなたのシリアライザを作成し、このクラスの新しいインスタンスにContractResolverプロパティを設定するには:

var ser = JsonSerializer.Create(sJsonSerializerSettings);    
ser.ContractResolver = new ContractResolver(); 
0

私もこの問題を満たしています。このトピックへの回答には、数値ソリューションが含まれています。 Loop Reference handling in Web API - しかし、説明と異なるケースのための、しかもカスタムのない最高のさまざまなソリューションは、私が紅葉日で記事に発見したシリアル化します。

関連する問題