Esempio n. 1
0
        public static void Serialize(this Utf8JsonWriter writer, object res, WritedObjects objrefs)
        {
            if (res == null || res == DBNull.Value)
            {
                writer.WriteNullValue();
                return;
            }

            //先检查引用类型是否已序列化过
            var  type        = res.GetType();
            bool isRefObject = type.IsClass && type != typeof(string);

            if (isRefObject)
            {
                if (objrefs.TryGetValue(res, out string refID))
                {
                    if (!string.IsNullOrEmpty(refID))
                    {
                        writer.WriteStartObject();
                        writer.WritePropertyName(RefPropertyName);
                        writer.WriteStringValue(refID);
                        writer.WriteEndObject();
                        return;
                    }
                    throw new Exception("Json序列化存在重复引用");
                }
                if (res is Entity entity && !entity.Model.IsDTO)
                {
                    refID = $"{(byte)entity.PersistentState}{entity.ModelId}{entity.Id}";
                }
                objrefs.Add(res, refID);
            }

            if (res is IJsonSerializable serializable)
            {
                //开始写入对象
                if (serializable.JsonPayloadType != PayloadType.JsonResult)
                {
                    writer.WriteStartObject();
                }
                if (serializable.JsonPayloadType != PayloadType.UnknownType && serializable.JsonPayloadType != PayloadType.JsonResult)
                {
                    writer.WritePropertyName(TypePropertyName);             // 写入对象类型
                    if (serializable.JsonPayloadType == PayloadType.Entity) //实体类写入的是持久化状态及模型标识
                    {
                        var entity = (Entity)res;
                        writer.WriteStringValue($"{(byte)entity.PersistentState}{entity.ModelId}");
                        if (entity.Model.SysStoreOptions != null)
                        {
                            writer.WritePropertyName(IdPropertyName); // 写入对象标识
                            writer.WriteStringValue((Guid)entity.Id);
                        }
                        else if (entity.Model.SqlStoreOptions != null)
                        {
                            //TODO:写入$Id标识,从WriteObjectRefs内累加标识计数器
                        }
                    }
                    else if (serializable.JsonPayloadType == PayloadType.ExtKnownType) //扩展类型写入反射信息
                    {
                        writer.WriteStringValue(type.FullName);
                    }
                    else
                    {
                        writer.WriteNumberValue((int)serializable.JsonPayloadType);
                    }
                }

                // 开始调用实现
                serializable.WriteToJson(writer, objrefs);
                //结束写入对象
                if (serializable.JsonPayloadType != PayloadType.JsonResult)
                {
                    writer.WriteEndObject();
                }
            }
            else //----非实现了IJsonSerializable的对象---
            {
                if (type.IsPrimitive || type == typeof(string) || type == typeof(DateTime) ||
                    type == typeof(Guid) || type == typeof(decimal))
                {
                    System.Text.Json.JsonSerializer.Serialize(writer, res, type);
                }
                else if (res is IList) // 优先转换IList集合
                {
                    WriteList(writer, (IList)res, objrefs);
                }
                else if (res is IEnumerable) // 其他集合
                {
                    WriteEnumerable(writer, (IEnumerable)res, objrefs);
                }
                else // 转换其他类型如匿名类和没有继承IJsonSerializable接口的类
                {
                    //todo:***** 暂反射简单实现,另考虑缓存
                    var properties = type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
                    writer.WriteStartObject();
                    for (int i = 0; i < properties.Length; i++)
                    {
                        writer.WritePropertyName(properties[i].Name);
                        writer.Serialize(properties[i].GetValue(res), objrefs);
                    }
                    writer.WriteEndObject();
                }
            }
        }