你的位置:首页 > ASP.net教程

[ASP.net教程]EF 序列化实体为Json时的循环引用问题(不用自己写实体,不用匿名类型,不用EF的上下文属性)


自己写实体可以完美解决这个问题。

用匿名类型也可以。

设置上下文方法如下:

(jz为数据库上下文对象)

jz.Configuration.ProxyCreationEnabled = false;
jz.Configuration.LazyLoadingEnabled = false;

不用这个的原因是Virtual属性也会生成。(只是占个位,[]里面没内容,但看着不爽)

我采用的方法是过滤掉Virtual属性的方法:

一个基于Json.net的类

public class LimitPropsContractResolver : DefaultContractResolver  {    string[] props = null;    bool retain;    /// <summary>    /// 构造函数    /// </summary>    /// <param name="props">传入的属性数组</param>    /// <param name="retain">true:表示props是需要保留的字段 false:表示props是要排除的字段</param>    public LimitPropsContractResolver(string[] props, bool retain = true)    {      //指定要序列化属性的清单      this.props = props;      this.retain = retain;    }    protected override IList<JsonProperty> CreateProperties(Type type,    MemberSerialization memberSerialization)    {      IList<JsonProperty> list =      base.CreateProperties(type, memberSerialization);      //只保留清单有列出的属性      return list.Where(p =>      {        if (retain)        {          return props.Contains(p.PropertyName);        }        else        {          return !props.Contains(p.PropertyName);        }      }).ToList();    }    public static string[] GetVirtualList<T>()    {      var stringType = typeof(T);      var props = stringType.GetProperties();      List<string> test = new List<string>();      foreach (var prop in props)      {        if (prop.GetAccessors()[0].IsVirtual)        {          test.Add(prop.Name);        }      }      return test.ToArray();    }  }

 和一个对PropertyInfo的扩展方法

public static class Virtual_Help  {       public static bool? IsVirtual(this PropertyInfo self)    {      if (self == null)        throw new ArgumentNullException("self");      bool? found = null;      foreach (MethodInfo method in self.GetAccessors())      {        if (found.HasValue)        {          if (found.Value != method.IsVirtual)            return null;        }        else        {          found = method.IsVirtual;        }      }      return found;    }      }

 使用方法如下

 JsonSerializerSettings jsetting = new JsonSerializerSettings();      jsetting.ContractResolver = new LimitPropsContractResolver(      LimitPropsContractResolver.GetVirtualList<affairs>(), false);      string json = JsonConvert.SerializeObject(temp, Formatting.Indented, jsetting);