Entity framework serialize POCO to JSON

转载 2012年03月29日 21:36:17

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace Web.Common
{
    /// <summary>
    /// 都是无法序列化JSON序列化 EF的实体对象,
    /// 要么就必须声明什么DataMember??,需要删除实体类的IsRefrence
    /// 太恶心了,网路上找到一个,自己汉化了一下。
    /// </summary>
    public static class JsonHelper
    {
        /// <summary>
        /// 将对象转化为Json字符串
        /// </summary>
        /// <typeparam name="T">源类型</typeparam>
        /// <param name="instance">源类型实例</param>
        /// <returns>Json字符串</returns>
        public static string ToJson(this object obj)
        {
            //string jsonText = JsonConvert.SerializeObject(obj);
            //return jsonText;

            return JsonHelper.JsonSerialize(obj);
        }

        public static string JsonSerialize<T>(T obj) where T : class
        {
            var sb = new StringBuilder("{");

            var parentType = obj.GetType(); // I get type from given object 

            //使用反射来检索该类型的所有属性
            var ms = parentType.GetMembers().Where(v => v.MemberType
                == MemberTypes.Property).ToList<MemberInfo>();

            const string doubleQuote = "\"";
            var counter = 0;
            var stringTypes = new List<String> { "String", "Guid", 
            "Boolean" };

            ///以下类型的使用实体框架。定义忽略的数据类型
            var ignoreEntityTypes = new List<String> { "EntityReference`1", 
            "EntityCollection`1", "EntityState", 
            "EntityKey", "EntitySetName" };

            //开始迭代查找每个属性
            foreach (PropertyInfo p in ms)
            {
                counter++;
                var propertyName = p.Name;
                var propertyType = p.PropertyType;
                var propertyValue = p.GetValue(obj, null);

                //如果属性类型匹配 ignoreTypes,那么进入下一个循环。
                if (ignoreEntityTypes.Contains(propertyType.Name))
                {
                    continue;
                }

                if (stringTypes.Contains(propertyType.Name))
                {
                    if (propertyValue == null)
                    {
                        sb.Append(doubleQuote + propertyName + doubleQuote +
                                  ":" + "null");
                    }

                    else
                    {
                        sb.Append(doubleQuote + propertyName + doubleQuote +
                            ":" + doubleQuote + propertyValue.ToString() + doubleQuote);
                    }
                }

                else if (propertyType != null && propertyType.IsPrimitive)
                {
                    sb.Append(doubleQuote + propertyName + doubleQuote
                        + ":" + propertyValue.ToString());
                }

                //我仍然有疑问如何处理日期和时间,处理日期属性
                else if (propertyType.Name == "DateTime")
                {
                    var dt = (DateTime)propertyValue;
                    sb.Append(doubleQuote + propertyName
                        + doubleQuote + ":"
                        + "new Date(" + dt.Ticks.ToString() + ")");
                }
                else
                {
                    if (propertyValue != null)
                    {
                        sb.Append(doubleQuote + propertyType.Name + doubleQuote + ":");
                        //如果属性值是另一个实体,然后
                        //递归调用的方法。
                        sb.Append(JsonSerialize(propertyValue));
                    }
                    else
                    {
                        continue;
                    }
                }
                //如果不是最后一个属性,然后添加逗号
                if (counter < ms.Count)
                {
                    sb.Append(",");
                }
            }
            sb.Append("}");
            var result = sb.ToString().Replace(",}", "}");
            return result;

        }
    }
}


http://geeks.ms/blogs/fernandezja/archive/2010/05/13/entity-framework-serializar-entidades-con-json-net-error-the-type-entidadxxx-cannot-be-serialized-to-json-because-its-isreference-setting-is-true.aspx


m using Ef 4.1 and I've got a POCO object I'd like to serialize to JSON, I've read there is a problem to do so when using lazy loading but I'm not sure I can because a Message can have a collection ofMessage.

Is there any way to do this? sirialize this kind of object into JSON?

My Message object looks like:

public class Message
{
    [Key]
    public int Id { get; set; }
    public int? ParentId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public DateTime CreatedAt { get; set; }
    public DateTime? LastModified { get; set; }

    public virtual User User { get; set; }

    public virtual Message Parent { get; set; }

    public virtual ICollection<Message> Children { get; set; }
}
link|improve this question

 
feedback

3 Answers

The problem is circular references. An easy way to avoid this is to use Json.Nethttp://james.newtonking.com/projects/json-net.aspx instead of the default MVC json serializer. The latest version of Json.Net will serialize objects with circular references out of the box.http://james.newtonking.com/projects/json/help/PreserveObjectReferences.html for more info on the problem

link|improve this answer
 
Thanks! ReferenceLoopHandling.Ignore and a custom ContractResolver did the trick :-) – CD.. Aug 30 '11 at 6:35
feedback

Eager load it using Include(). Sample linq:

var serializeMe = (from m in MyContext.Message.Include("User") where m.Id == someValue select m).ToList();

That will tell EF to load the User navigation property right away instead of lazy loading it, and the serializer should have no problem with it then.

link|improve this answer
 
Including the related entity solved a problem I was having serializing an EF object graph because I was able to take the virtual keyword off of the offending property in my class. Thanks! – marc Feb 15 at 16:48
feedback

How about this:

  • Mark your class as [Serializable]
  • Use the JsonSerializer to serialize your object to JSON.
  • Perhaps use eager loading on the properties in your EF query?
Message msg = new Message();
var serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(msg.GetType());
MemoryStream ms = new MemoryStream();
serializer.WriteObject(ms, msg);
string json = Encoding.Default.GetString(ms.ToArray());


[Serializable]
public class Message
{
}
link|improve this answer
 
thanks for the detailed answer, but I'm afraid the virtual properties are not loaded this way... – CD.. Aug 29 '11 at 20:51
 
@CD : what am I missing? The virtual property serialized just fine for the collection and the single properties: i.imgur.com/9mkW3.png – p.campbell Aug 29 '11 at 21:03
 
In EF any virtual ICollection will be lazy-loaded.. – CD.. Aug 29 '11 at 21:08
Was this post useful to you?     



javabean规范中要求实现Serializable接口,有什么作用?

javabean规范中要求实现Serializable接口,有什么作用?
  • bz151531223
  • bz151531223
  • 2015年09月28日 23:30
  • 2730

深入浅出MFC 第8章 关于序列化(Serialize)的一些问题

很好的一篇文章,转载自:http://blog.csdn.net/jwj070524/article/details/10263191     不知不觉跟随者侯捷的脚步对着电子书看了将近600页,就...
  • lishuhuakai
  • lishuhuakai
  • 2014年01月13日 10:53
  • 4084

业务实体对象(Business Entity Object)的序列化

业务实体对象(Business Entity Object)的序列化 Written by: Rickie LeeDec. 12, 2004  在分布式应用系统中,层与层之间的数据,如业务实体对象、D...
  • airtl117
  • airtl117
  • 2007年03月12日 14:40
  • 724

EntityFramework中Json序列化的循环引用问题解决--Newtonsoft.Json

1.在使用EF时,由于数据库主外键关联,将对象进行Json序列化时会遇到循环引用的问题 //EF 中由于数据库主外键关联,对象的序列化经常出现循环引用问题 //使用.Net 自带的序列化工具,序列化出...
  • u011127019
  • u011127019
  • 2016年06月18日 18:24
  • 4952

jquery的$('#theForm').serialize()获取表单数据,ajax传递到服务器中文乱码。

var params = $('#theForm').serialize(); params = decodeURIComponent(params,true); $.ajax({...
  • qq_30679953
  • qq_30679953
  • 2016年08月19日 18:16
  • 1010

Entity Framework的启动速度优化

转自:寒江独钓 最近开发的服务放到IIS上寄宿之后,遇到一些现象,比如刚部署之后,第一次启动很慢;程序放置一会儿,再次请求也会比较慢。比如第一个问题,可以解释为初次请求某一个服务的时候,需要把程...
  • asciil
  • asciil
  • 2016年09月05日 11:23
  • 554

利用JsonConvert.SerializeObject()实现类对象的json化

现阶段的项目是采用前后端分离的思想,前端使用的是Angular.JS,后端使用ABP框架,在后端我们通过WebAPI技术来向前端提供json数据。以前是通过MVC来写前端的代码,感觉后端有点在控制前端...
  • FLy6666666
  • FLy6666666
  • 2017年08月08日 17:01
  • 392

serialize datatable to json

public string CreateJsonParameters(DataTable dt) { /* /***********************...
  • fox123871
  • fox123871
  • 2012年06月03日 22:51
  • 837

jquery serialize传中文乱码解决方法

jquery form 表单.serialize()序列化后中文乱码 经过一天的时间终于解决了! 一开始的时候我并不知道乱码问题是jquery引起的! 我以为是后台转码的时间出错了! 最后在网络上到了...
  • zhou1672
  • zhou1672
  • 2015年09月25日 12:03
  • 3274

jQuery序列化表单的方法总结(serialize()、serializeArray())

jQuery序列化表单的方法总结现在这里贴出案例中静态的html网页内容: Title ...
  • xinghuo0007
  • xinghuo0007
  • 2017年05月23日 18:55
  • 997
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Entity framework serialize POCO to JSON
举报原因:
原因补充:

(最多只允许输入30个字)