.net mvc 解决Json序列化时循环引用问题及动态选择序列化字段

    public class JsonNetResult : JsonResult
    {

        private class ExcludePropertiesContractResolver : DefaultContractResolver
        {
            IEnumerable<string> lstExclude;
            public ExcludePropertiesContractResolver(IEnumerable<string> excludedProperties) { lstExclude = excludedProperties; }
            protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
            {
                return base.CreateProperties(type, memberSerialization).Where(p => !lstExclude.Contains(p.PropertyName)).ToList();
            }
        }

        public JsonSerializerSettings Settings { get; private set; }

        public JsonNetResult()
        {
            Settings = new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore, };
        }

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

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

    public class BaseController : Controller
    {
        private class MyJson
        {
            public object data;
            public IEnumerable<string> exculdedProperties;
        }

        protected override JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior)
        {
            if (data.GetType() == typeof(MyJson))
            {
                var md = data as MyJson;
                return new JsonNetResult(md.exculdedProperties)
                {
                    Data = md.data,
                    ContentType = contentType,
                    ContentEncoding = contentEncoding,
                    JsonRequestBehavior = behavior
                };
            }
            else
            {
                return new JsonNetResult()
                {
                    Data = data,
                    ContentType = contentType,
                    ContentEncoding = contentEncoding,
                    JsonRequestBehavior = behavior
                };
            }
        }

        protected internal JsonResult Json(object data, string[] excludedProperties)
        {
            return Json(new MyJson { data = data, exculdedProperties = excludedProperties });
        }
    }

  使用方法:

将你自己的Controller改为继承自BaseController。

遇到需要排除的字段使用 return Json(data,new string[]{"字段名"});

参考:

http://www.cnblogs.com/Gryzor/

http://hi.baidu.com/wokao100000/item/1f965bc27a96e611b77a2421

原文地址:https://www.cnblogs.com/niukuo/p/3137128.html