.Net MVC5 asynchronous request Entity Framework infinite loop solution
Entity Framework has a one-to-many, many-to-many relationship and is mutually dependent. When returning JSON data, there is often an infinite loop problem caused by mutual reference. For the JSON sequence provided by a third party, it can also be solved through features and serialization configuration. The problem of infinite loops is eliminated, so we can use third-party libraries to solve the problem of infinite loops in JSON returned by MVC.
We can use the JsonSerializerSettings class of Newtonsoft.Json for serialization settings
For the ReferenceLoopHandling enumeration type
1 #region 程序集 Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed 2 // E:\VsGit\DigitizationPlatform\dll\Newtonsoft.Json.dll 3 #endregion 4 5 namespace Newtonsoft.Json 6 { 7 // 8 // 摘要: 9 // Specifies reference loop handling options for the Newtonsoft.Json.JsonSerializer. 10 public enum ReferenceLoopHandling 11 { 12 // 13 // 摘要: 14 // Throw a Newtonsoft.Json.JsonSerializationException when a loop is encountered. 15 Error = 0, 16 // 17 // 摘要: 18 // Ignore loop references and do not serialize. 19 Ignore = 1, 20 // 21 // 摘要: 22 // Serialize loop references. 23 Serialize = 2 24 } 25 }
We can set JsonSerializerSettings
1 JsonSerializerSettings set = new JsonSerializerSettings(); 2 set.Formatting = Formatting.Indented; 3 set.DateFormatString = "yyyy-MM-dd HH:mm:ss"; 4 //set.MaxDepth = 10; 5 set.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
In this way, we can solve the problem that JsonResult returns JSON infinite loop
Override MVC -> JsonResult :
1 using Newtonsoft.Json; 2 using System; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 using System.Web; 8 using System.Web.Mvc; 9 10 namespace Goldwind.Framework.Web.OverrideExtension 11 { 12 public class MyJsonResult: JsonResult 13 { 14 public MyJsonResult() { } 15 public MyJsonResult(object Data) { 16 this.Data = Data; 17 } 18 public MyJsonResult(object Data, JsonRequestBehavior JsonRequestBehavior = JsonRequestBehavior.DenyGet) :this(Data){ 19 this.JsonRequestBehavior = JsonRequestBehavior; 20 } 21 public MyJsonResult(object Data, string ContentType,Encoding ContentEncoding = null, JsonRequestBehavior JsonRequestBehavior = JsonRequestBehavior.DenyGet) :this(Data,JsonRequestBehavior) { 22 this.ContentType = ContentType; 23 if(ContentEncoding != null) 24 { 25 this.ContentEncoding = ContentEncoding; 26 } 27 } 28 public override void ExecuteResult(ControllerContext context) 29 { 30 if(this.JsonRequestBehavior == JsonRequestBehavior.DenyGet 31 && string.Compare(context.HttpContext.Request.HttpMethod,"Get",true) == 0) 32 { 33 throw new InvalidOperationException(); 34 } 35 HttpResponseBase response = context.HttpContext.Response; 36 response.ContentType = string.IsNullOrEmpty(this.ContentType) ? 37 "application/json" : this.ContentType; 38 if(this.ContentEncoding != null) 39 { 40 response.ContentEncoding = this.ContentEncoding; 41 } 42 if(null != this.Data) 43 { 44 JsonSerializerSettings set = new JsonSerializerSettings(); 45 set.Formatting = Formatting.Indented; 46 set.DateFormatString = "yyyy-MM-dd HH:mm:ss"; 47 //set.MaxDepth = 10; 48 set.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; 49 response.Write(JsonConvert.SerializeObject(this.Data,set)); 50 } 51 } 52 } 53 }