当前位置:学习生活->编程学习->System.Data.Entity.DynamicProxies循环引用问题

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

作者:阿郎  发表时间:2017/1/11 21:09:05  阅读:
[摘要] 序列化类型为“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++技术网原创文章版权所有,会员文章禁止转载。非会员文章转载做好本文超链接即表示授权转载。通过文章下面的分享按钮可以自由分享所有文章。


返回顶部

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

C++技术网群幕群聊

弹幕