以前都是到處看博客,今天小菜也做點貢獻,希望能幫到大家.
廢話不多說,直接進入正題.
用過.net MVC的同學應該都被json序列化報循環引用錯誤這個問題騷擾過.網上有一些解決辦法,但是都治標不治本.如在引發異常的屬性上加上[ScriptIgnore]或者[JsonIgnore],又或者用db.Configuration.ProxyCreationEnabled = false;這些解決辦法都存在問題且需要多處修改並且測試.本小菜之前一直被其騷擾,就在前兩天我決定一定要找到比較優的解決辦法,google一頓查,各種查,終於在一個老外的文章中找到辦法,但是當時光顧考代碼看來着忘記鏈接了....,核心思想就是用json.net替換mvc默認的json序列化類,因為json.net官方給出了解決循環引用的配置選項.
step1 在項目上添加Newtonsoft.Json引用
step2 在項目中添加一個類,繼承JsonResult,代碼如下
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()); } } }
step3 在項目中新建一個BaseController,繼承Controller類,然后重寫Controller中的json方法,代碼如下
public class BaseController : Controller { protected override JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior) { return new JsonNetResult { Data = data, ContentType = contentType, ContentEncoding = contentEncoding, JsonRequestBehavior = behavior }; } }
step 4 在你自己的controller類中,繼承之前的BaseController,然后使用示例如下
[HttpPost] public JsonResult GetUserList() { try { User user = UserHelper.GetCurrentUser(); List<User> users = userService.GetCompanyUsers(user.Units.FirstOrDefault().ID,user.ID); //此時json方法會調用你重寫的json方法
return Json(users); } catch (Exception ex) { return Json(CommonException.GetError(ex)); } }
這樣就可以解決循環引用的問題了.親測好用.
菜鳥一枚,有不對的地方希望前輩們指點,謝謝.