1

我试图从MVC 4 web api返回ApiController对象从实体框架4 edmx生成,接受:json /应用程序。实体框架不生成JsonIgnoreAttribute

问题是json格式化程序返回导航属性,我不想返回(我只想返回原始属性)。

所以我查看了实体框架4生成的代码,在导航属性中,只有XmlIgnoreAttribute和SoapIgnoreAttribute,而我需要JsonIgnoreAttribute。

我无法更改生成的代码,因为它会在edmx的下一次更改中被覆盖,因此如何配置使用JsonIgnoreAttribute生成模型代?

谢谢

回答

2

好的,我发现该怎么做。 我们需要这样的定制DefaultContractResolver使用:

public class ExcludeEntityKeyContractResolver : DefaultContractResolver 
{ 
    private static Type mCollectionType = typeof(System.Data.Objects.DataClasses.RelatedEnd); 

    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) 
    { 
     var members = GetSerializableMembers(type); 

     IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization); 
     IList<JsonProperty> serializeProperties = new List<JsonProperty>(); 

     for (int i = 0; i < properties.Count; i++) 
     { 
      var memberInfo = members.Find(p => p.Name == properties[i].PropertyName); 
      if (!memberInfo.GetCustomAttributes(false).Any(a => a is SoapIgnoreAttribute) && properties[i].PropertyType != typeof(System.Data.EntityKey)) 
      { 
       serializeProperties.Add(properties[i]); 
      } 
     } 
     return serializeProperties; 
    } 
} 

,并在Global.asax中:

 JsonSerializerSettings serializerSettings = new JsonSerializerSettings(); 
     serializerSettings.ContractResolver = new ExcludeEntityKeyContractResolver(); 
     var jsonMediaTypeFormatter = new JsonMediaTypeFormatter(); 
     jsonMediaTypeFormatter.SerializerSettings = serializerSettings; 
     GlobalConfiguration.Configuration.Formatters.Insert(0, jsonMediaTypeFormatter); 

,并不必担心性能,CreateProperties仅会被每一个类型称为整个申请期限:)

+0

正是我在找的东西。感谢这个解决方案。对于我的项目而言,在大多数情况下为DTO精心创建模型是浪费时间。 – TaeKwonJoe

3

虽然我不知道这是否是一个错误或不支持的功能,我建议你定义视图模型,有你的API控制器动作返回,而不是你的自动生成的EF域模型视图模型。视图模型显然只包含您想要公开的属性。单视图模型可以表示多个域模型的聚合。所以不要依赖任何XmlIgnore,SoapIgnore,JsonIgnore,...属性。依靠您的视图模型。

+2

是的!实体并不适合序列化和其他类型的传输。 – usr