2011-07-27 5 views
2

私のモデルを生成するためにEntity Frameworkを使用しています。私はこれらのモデルのいくつかをJSON経由で伝えたいと思います。問題は、EFがモデルに直列化されるもの(EntityKey、EntityState、およびすべてのEntityCollectionのプロパティ)を望まないということです。属性を含まないjsonにシリアル化するときのプロパティを無視する方法

EFはこれらのモデルを生成するため、ScriptIgnoreなどでプロパティを修飾します実際には実現可能ではありません。

jsonシリアライザでオブジェクトをシリアル化し、モデルのソースを変更する必要のないフィールドを無視する方法はありますか?

答えて

0

DataContractJsonSerializerを使用してJSONにシリアル化すると、[DataMember]属性を持つプロパティのみがシリアル化されます。これは、モデルに追加することができます(部分的なクラスとして宣言されているためです)。

もう1つの選択肢として、JSONで公開したいデータ用に別のDTOオブジェクトを用意することが考えられます。そのオブジェクトはエンティティモデルから構築されます。このアプローチの利点は、データコントラクトを定義する明示的なクラスのDTOがあり、それが基礎となるエンティティモデルから切り離されていることです。

+0

DataMember属性の問題は、ScriptIgnore属性と同じ問題があることがわかります。第二に、私はこれらの事柄に対して明白なDTOを作らなければならないと思っています。なぜなら、余分なEFの外では、それらは完全に輸送に適しており、デカップリングは本当に私の心配ではないからです。 –

0

JayRockには、独自のIExporterを作成できます。 (;コンストラクタで、具体的な形を取る例えば、特定の名前を持つすべてのプロパティを無視する)

class FooExporter : IExporter 
{ 
    public void Export(ExportContext context, object value, JsonWriter writer) 
    { 
     var properties = value.GetType().GetProperties(); 

     writer.WriteStartObject(); 

     foreach (var property in properties) 
     { 
      var propertyValue = property.GetValue(value, null); 
      if (!JsonNull.LogicallyEquals(propertyValue)) 
      { 
       writer.WriteMember(property.Name); 
       context.Export(propertyValue, writer); 
      } 
     } 

     writer.WriteEndObject(); 
    } 

    public Type InputType 
    { 
     get { return typeof(Foo); } 
    } 
} 

あなたはあなたが望むこの任意の方法を変更することができます。基本的な形は、次のようになります。次に、このようにそれを使用することができます:

var context = JsonConvert.CurrentExportContextFactory(); 
context.Register(new FooExporter()); 
// always use this context 
JsonConvert.CurrentExportContextFactory =() => context; 
string json = JsonConvert.ExportToString(new Foo { … }); 

別のオプションは、あなたのエンティティでIJsonExportableを実装することです。それは上記の方法に非常に似ているExport()メソッドを持っています。

1

私はちょうどそれは私がいうだけの設定多くのではなく、内とデータベースから連載ずっといただきたいSQLモデルへのLINQのカスタムオブジェクトのプロパティです。この場合には、同様の問題に直面してきてきました余分なフィールドと余分なコンストラクタ。私はこのことがあなたの状況にどれほど緊密に適合しているのかは分かりませんが、適応可能でなければなりません。私が見てきた

ほとんどのソリューションが欲しかったのどちらか(による自動コード生成のために可能ではない)含まれる属性または(あなたがなどをネストされたオブジェクトをキャプチャしたい場合は特に、過剰)カスタムコンバータをローリングしています。

LinqToSqlのために私が望まないすべてのプロパティが既に属性として与えられているので、それらを直列化しようとするプロパティを手動で取得するのではなく、最初に直列化してからDeSerializeします。これにより、作業がはるかに簡単で、すべてのネスティングが完了したオブジェクトグラフが得られます。

次は、望ましくないメンバー名を取得します。あなたは、これらはあなた次第です取得する方法、それも、あなたはMVCで結合モデルから除外していたものと同じ方法で、手動でそれに名前を与える場合があります。私の場合、少しのLinqと少しのリフレクションはLinqがSQLから生成するすべてのプロパティの名前を取得します。私たちのオブジェクトとして

は、我々の不要なメンバーを反復処理し、辞書からそれらを削除する簡単なDictonaryです。

最後に、再度辞書を逐次化してください。

public string JsonMinusProperties(object toSerialize) 
    { 
     //Replace this with your preferred way of getting your unwanted properties 
     var LinqMemberNames = toSerialize.GetType().GetProperties().Where(y=> 
      y.GetCustomAttributes(true).Any(x => 
       x.GetType().Namespace == "System.Data.Linq.Mapping" 
      ) 
     ).Select(x=>x.Name); 

     JavaScriptSerializer js = new JavaScriptSerializer(); 
     string json = js.Serialize(toSerialize); 
     var tempobj = js.DeserializeObject(json) as Dictionary<string, object>; 
     foreach (string linqMember in LinqMemberNames) 
     { 
      tempobj.Remove(linqMember); 
     } 
     return js.Serialize(tempobj); 
    } 

深いプロパティを削除するために必要な場合には元本に辞書を歩きやすいべきであるが、これは、最初のレベルから削除されます。

関連する問題