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


    自己写实体可以完美解决这个问题。(支持时间格式自定义)

    用匿名类型也可以。

    设置上下文方法如下:

    (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数据
  • 相关阅读:
    Nginx Backup配置
    CANas分析软件,DBC文件解析,CAN报文分析,仿CANoe曲线显示
    MySQL 报错:MySQL Illegal mix of collations for operation 'like'
    docker部署rebbitmq
    docker部署kafka
    nodejs 环境配置
    spring是怎么运行的?
    Java发展的时间表
    单例模式(转)
    disable的错误使用
  • 原文地址:https://www.cnblogs.com/gaocong/p/5340676.html
Copyright © 2020-2023  润新知