EF 序列化实体为Json时的循环引用问题(不用自己写实体,不用匿名类型,不用EF的上下文属性)
2016-03-31 12:16
726 查看
自己写实体可以完美解决这个问题。(支持时间格式自定义)
用匿名类型也可以。
设置上下文方法如下:
(jz为数据库上下文对象)
jz.Configuration.ProxyCreationEnabled = false;
jz.Configuration.LazyLoadingEnabled = false;
不用这个的原因是Virtual属性也会生成。(只是占个位,[]里面没内容,但看着不爽)
我采用的方法是过滤掉Virtual属性的方法:
一个基于Json.net的类
和一个对PropertyInfo的扩展方法
使用方法如下
用匿名类型也可以。
设置上下文方法如下:
(jz为数据库上下文对象)
jz.Configuration.ProxyCreationEnabled = false;
jz.Configuration.LazyLoadingEnabled = false;
不用这个的原因是Virtual属性也会生成。(只是占个位,[]里面没内容,但看着不爽)
我采用的方法是过滤掉Virtual属性的方法:
一个基于Json.net的类
using Newtonsoft.Json; using Newtonsoft.Json.Converters; using Newtonsoft.Json.Serialization; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Web; namespace AceepSystem.Models.Help { public class JsonForEF : DefaultContractResolver { string[] props = null; bool retain; /// <summary> /// 构造函数 /// </summary> /// <param name="props">传入的属性数组</param> /// <param name="retain">true:表示props是需要保留的字段 false:表示props是要排除的字段</param> public JsonForEF(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(); } public static JsonSerializerSettings GetJsonConfig<T>() { JsonSerializerSettings jsetting = new JsonSerializerSettings();//过滤掉ef中的导航属性,无残留... jsetting.ContractResolver = new JsonForEF( JsonForEF.GetVirtualList<T>()//泛型方法传入当前要序列化的类型 , false);//false为要排除的属性,true为要保留的属性(第一个参数为string[]) jsetting.Converters.Add(new MyDateTimeConvertor()); return jsetting; } public class MyDateTimeConvertor : DateTimeConverterBase { public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { return DateTime.Parse(reader.Value.ToString()); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { writer.WriteValue(((DateTime)value).ToString("yyyy/MM/dd HH:mm")); } } } }
和一个对PropertyInfo的扩展方法
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Web; namespace AceepSystem.Models.Help { 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; } } }
使用方法如下
string json = JsonConvert.SerializeObject( list, Formatting.Indented, JsonForEF.GetJsonConfig<dic_attribution>() );//转C#对象为Json数据
相关文章推荐
- JackJSON 读取服务器端 返回的Json对象
- Web报表工具FineReport二次开发JS之字符串
- Web报表工具FineReport二次开发JS之字符串
- 高效解析json例子,Jackson框架
- JavaScript内置对象
- js中数组Array的操作
- javascript替换字符串
- JavaScript简介
- js实现跨域的几种方法的原理详解
- js如何获取一个月的天数 data javascript
- js 无线弹窗
- javascript笔记——jsonp
- 18、bootStap JavaScript插件
- 介绍 JSON
- odoo8.0条形码改为js方式处理
- Json学习一(基础概念知识学习)
- JSP程序设计:Servlet配置问题
- js(头像,图片)上传,如何立即展示?图片详解。
- 礼拜四log~js控制台输出 & c:forEach
- 学习promise编写和使用