【今日/总数】文章:2/2773 用户:4/10747 书籍:0/200
回顾2016,喜迎2017,以“回顾我与C++技术网的2016,展望C++技术网的2017”为主题,发表文章,将有机会赢得2个月的会员或现金红包。

原创版权标志System.Data.Entity.DynamicProxies循环引用问题

作者:阿郎  发表时间:2017/1/11 21:09:05  阅读:53
[摘要]序列化类型为“System.Data.Entity.DynamicProxies.Photos_1F5D250F2735650E782711718DE2EFF2BBEA68EE8F6C5A1CF253FAABD0681F7B”的对象时检测到循环引用。
文章来源:C++技术网 原创文章版权所有,未经授权,禁止转载。

今天学习的过程中,遇到了这么个问题:

序列化类型为“System.Data.Entity.DynamicProxies.Photos_1F5D250F2735650E782711718DE2EFF2BBEA68EE8F6C5A1CF253FAABD0681F7B”的对象时检测到循环引用。

后来查资料才发现,原来是数据表的关联问题,因为这个表和另一个表是有一对多关系的,当序列化表1的时候,会找到和另一个表2关联的字段,就会到另一个表2中序列化,然后另一个表2中也有一个字段和表1相关联.这样.序列化就会发生这种错误!我采用的解决办法是这两种:

在MVC后台中,只访问我需要的数据字段,因为两个数据表关联的字段一般都是ID这些敏感的字段,我们一般不在页面中呈现出来,因此,可以这样:

public ActionResult Details(int id)
        {
            var order = _db.Orders.Find(id);

            var data = new {
                orderDate = order.OrderDate.ToString(),
                shipVia=order.ShipVia,
                freight=order.Freight
            };

            return this.Json(data, JsonRequestBehavior.AllowGet);
        }
这样前台就能接收到后台传来的JSON数据了。

第二种方法,治本!有一点要知道的就是MVC中的JsonResult是通过JavascriptSerializer(System.Web.Scripts.Serialization.JavaScripteSerializer,要添加System.Web.Extensions.dll)来实现Json序列化和反序列化的。

因此,我们就可以理由json.net自定义一个JsonNetResult,核心思想就是用json.net替换mvc默认的json序列化类,因为json.net官方给出了解决循环引用的配置选项:

首先新建一个类文件JsonNetResult:

public class JsonNetResult : JsonResult
    {
        public JsonSerializerSettings Settings { get; private set; }

        public JsonNetResult()
        {
            Settings = new JsonSerializerSettings
            {
                //这句是解决问题的关键,也就是json.net官方给出的解决配置选项.                 
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore
            };
        }

        public override void ExecuteResult(ControllerContext context)
        {
            if (context == null)
                throw new ArgumentNullException("context");
            if (this.JsonRequestBehavior == JsonRequestBehavior.DenyGet && string.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
                throw new InvalidOperationException("JSON GET is not allowed");
            HttpResponseBase response = context.HttpContext.Response;
            response.ContentType = string.IsNullOrEmpty(this.ContentType) ? "application/json" : this.ContentType;
            if (this.ContentEncoding != null)
                response.ContentEncoding = this.ContentEncoding;
            if (this.Data == null)
                return;
            var scriptSerializer = JsonSerializer.Create(this.Settings);
            using (var sw = new StringWriter())
            {
                scriptSerializer.Serialize(sw, this.Data);
                response.Write(sw.ToString());
            }
        } 
    }
然后新建一个控制器文件BaseController:
public class BaseController : Controller
    {
        //
        // GET: /Base/
        protected override JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior)
        {
            return new JsonNetResult
            {
                Data = data,
                ContentType = contentType,
                ContentEncoding = contentEncoding,
                JsonRequestBehavior = behavior
            };
        }
    }
最后在我们自己的控制器中调用重载的JsonResult类:
public ActionResult Details(int id)
        {
            var order = _db.Orders.Find(id);

            return this.Json(order, JsonRequestBehavior.AllowGet);
        }
文章来源:C++技术网 原创文章版权所有,未经授权,禁止转载。



返回顶部

关于我们 QQ群 广告服务 增值服务 捐款资助 版权声明 RSS订阅 站点地图 百度网站地图 意见反馈
鄂ICP备14001349号-2, Copyright © 2014-2017, CJJJS.COM/CJJJS.CN, All Rights Reserved

在线提问
问题标题:
问题描述:(简陋的描述会导致问题被最后回答、没有针对性回答甚至无法解答。请确保问题描述的足够清楚。)