2011-07-27 48 views
2

我正在使用Entity Framework来生成我的模型。我想通过JSON来传达一些这些模型。问题是我不希望EF在模型上粘贴的东西被序列化(EntityKey,EntityState和所有EntityCollection属性)如何在序列化为不涉及属性的json时忽略属性

由于EF生成这些模型,使用ScriptIgnore或类似的东西装饰属性并不是真的可行。

有任何JSON序列化的方式来序列化一个对象,并把它忽略了,不需要我改变我的模型源田? (我可以添加到模型,但如果它有帮助,因为它们被声明为部分类)

回答

0

如果您使用DataContractJsonSerializer序列化为JSON,那么它将只序列化具有[DataMember]属性的属性。

另一个值得考虑的选择是对要在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

我刚刚来面对类似的问题,在这种情况下,它是在一个LINQ的自定义对象属性SQL模式,我宁愿只连载中,并从数据库中,而不是大量的设立额外的字段和额外的构造函数。我不确定这与你的情况有多接近,但它应该是适应性的。

我见过

大多数解决方案都希望要么属性被列入(不可能的,因为自动代码生成)或滚动自定义转换器(矫枉过正,特别是如果你想捕捉嵌套对象等)。

我的想法是,我不想要的所有属性都是LinqToSql赋予的属性,所以不是手动获取我想要的属性,然后试图序列化它们,先序列化然后再序列化。这为您提供了更易于使用的对象图,并且您的所有嵌套都已完成。

下一步获取我们不想要的成员名称。你如何得到这些取决于你,它甚至可能是一种手动给它起名字的例子,就像你从MVC中的模型绑定中排除的方式一样。在我的情况下,一些Linq和一些反射使我们获得了Linq to 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); 
    } 

这将只从第一级去除,但在校长如果需要的话,除去更深的性质应该是很容易走的字典。

相关问题