C# MVC 中对EF模型对象的序列化方案

2018-10-12  本文已影响0人  f5df0a516b61

在C# MVC中,如果使用entity framework做数据源,在模型对象中存在引用的时候,直接使用 return Json(object)会报循环引用异常。

解决的方案如下:
创建一个继承自JsonResult的类,内容如下

namespace xxx.Controllers

{
    /// <summary>
    /// 重写的jsonresult,处理ef model专用
    /// </summary>
    public class JsonNetResult : JsonResult
    {
        public JsonSerializerSettings Settings { get; private set; }

        public JsonNetResult()
        {
            Settings = new JsonSerializerSettings
            {
                //这句是解决问题的关键,也就是json.net官方给出的解决配置选项.               
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                DateFormatHandling= DateFormatHandling.MicrosoftDateFormat,
                DateFormatString = "yyyy-MM-dd HH:mm:ss",
            };
        }

        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());
            }
        }
    }
}

然后创建一个继承自Controller的BaseController
写入如下代码

        /// <summary>
        /// 重写mvc默认jsonresult使其能够兼容ef的model,不会loop
        /// </summary>
        /// <param name="data"></param>
        /// <param name="contentType"></param>
        /// <param name="contentEncoding"></param>
        /// <param name="behavior"></param>
        /// <returns></returns>
        protected override JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior)
        {
            return new JsonNetResult
            {
                Data = data,
                ContentType = contentType,
                ContentEncoding = contentEncoding,
                JsonRequestBehavior = behavior
            };
        }

然后上层控制器,继承自BaseController,正常使用return Json(object) 即可

上一篇下一篇

猜你喜欢

热点阅读