public static string Serialize(object obj, int maxDepth) { using (var strWriter = new StringWriter()) { using (var jsonWriter = new CustomJsonTextWriter(strWriter)) { //Func<bool> include = () => jsonWriter.CurrentDepth <= maxDepth; Func <MemberInfo, bool> include = (m) => jsonWriter.CurrentDepth <= maxDepth; var resolver = new CustomContractResolver(include); var serializer = new JsonSerializer { ContractResolver = resolver }; serializer.PreserveReferencesHandling = PreserveReferencesHandling.Objects; serializer.Serialize(jsonWriter, obj); } return(strWriter.ToString()); } }
//private static readonly MediaTypeHeaderValue[] _supportedMediaTypes = new MediaTypeHeaderValue[] { // MediaTypeConstants.ApplicationJsonMediaType, // MediaTypeConstants.TextJsonMediaType //}; //private JsonSerializerSettings _jsonSerializerSettings; //private readonly IContractResolver _defaultContractResolver; //private int _maxDepth = FormattingUtilities.DefaultMaxDepth; //private XmlDictionaryReaderQuotas _readerQuotas = FormattingUtilities.CreateDefaultReaderQuotas(); //private ConcurrentDictionary<Type, DataContractJsonSerializer> _dataContractSerializerCache = new ConcurrentDictionary<Type, DataContractJsonSerializer>(); //private RequestHeaderMapping _requestHeaderMapping; ///// <summary> ///// Initializes a new instance of the <see cref="JsonMediaTypeFormatter"/> class. ///// </summary> //public MaxDepthJsonMediaTypeFormatter() { // // Set default supported media types // foreach (MediaTypeHeaderValue value in _supportedMediaTypes) { // SupportedMediaTypes.Add(value); // } // // Initialize serializer // _defaultContractResolver = new JsonContractResolver(this); // _jsonSerializerSettings = CreateDefaultSerializerSettings(); // // Set default supported character encodings // SupportedEncodings.Add(new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true)); // SupportedEncodings.Add(new UnicodeEncoding(bigEndian: false, byteOrderMark: true, throwOnInvalidBytes: true)); // _requestHeaderMapping = new XHRRequestHeaderMapping(); // MediaTypeMappings.Add(_requestHeaderMapping); //} ///// <summary> ///// Gets the default media type for Json, namely "application/json". ///// </summary> ///// <remarks> ///// The default media type does not have any <c>charset</c> parameter as ///// the <see cref="Encoding"/> can be configured on a per <see cref="JsonMediaTypeFormatter"/> ///// instance basis. ///// </remarks> ///// <value> ///// Because <see cref="MediaTypeHeaderValue"/> is mutable, the value ///// returned will be a new instance every time. ///// </value> //public static MediaTypeHeaderValue DefaultMediaType { // get { return MediaTypeConstants.ApplicationJsonMediaType; } //} ///// <summary> ///// Gets or sets the <see cref="JsonSerializerSettings"/> used to configure the <see cref="JsonSerializer"/>. ///// </summary> //public JsonSerializerSettings SerializerSettings { // get { return _jsonSerializerSettings; } // set { // if (value == null) { // throw new ArgumentNullException("value"); // } // _jsonSerializerSettings = value; // } //} ///// <summary> ///// Gets or sets a value indicating whether to use <see cref="DataContractJsonSerializer"/> by default. ///// </summary> ///// <value> ///// <c>true</c> if use <see cref="DataContractJsonSerializer"/> by default; otherwise, <c>false</c>. The default is <c>false</c>. ///// </value> //public bool UseDataContractJsonSerializer { get; set; } ///// <summary> ///// Gets or sets a value indicating whether to indent elements when writing data. ///// </summary> //public bool Indent { get; set; } ///// <summary> ///// Gets or sets the maximum depth allowed by this formatter. ///// </summary> //public int MaxDepth { // get { // return _maxDepth; // } // set { // if (value < FormattingUtilities.DefaultMinDepth) { // throw new ArgumentOutOfRangeException("value", value, RS.Format(Properties.Resources.ArgumentMustBeGreaterThanOrEqualTo, FormattingUtilities.DefaultMinDepth)); // } // _maxDepth = value; // _readerQuotas.MaxDepth = value; // } //} ///// <summary> ///// Creates a <see cref="JsonSerializerSettings"/> instance with the default settings used by the <see cref="JsonMediaTypeFormatter"/>. ///// </summary> //public JsonSerializerSettings CreateDefaultSerializerSettings() { // return new JsonSerializerSettings() { // ContractResolver = _defaultContractResolver, // MissingMemberHandling = MissingMemberHandling.Ignore, // // Do not change this setting // // Setting this to None prevents Json.NET from loading malicious, unsafe, or security-sensitive types // TypeNameHandling = TypeNameHandling.None // }; //} //internal bool ContainsSerializerForType(Type type) { // return _dataContractSerializerCache.ContainsKey(type); //} ///// <summary> ///// Determines whether this <see cref="JsonMediaTypeFormatter"/> can read objects ///// of the specified <paramref name="type"/>. ///// </summary> ///// <param name="type">The type of object that will be read.</param> ///// <returns><c>true</c> if objects of this <paramref name="type"/> can be read, otherwise <c>false</c>.</returns> //public override bool CanReadType(Type type) { // if (type == null) { // throw new ArgumentNullException("type"); // } // if (UseDataContractJsonSerializer) { // // If there is a registered non-null serializer, we can support this type. // DataContractJsonSerializer serializer = // _dataContractSerializerCache.GetOrAdd(type, (t) => CreateDataContractSerializer(t)); // // Null means we tested it before and know it is not supported // return serializer != null; // } else { // return true; // } //} ///// <summary> ///// Determines whether this <see cref="JsonMediaTypeFormatter"/> can write objects ///// of the specified <paramref name="type"/>. ///// </summary> ///// <param name="type">The type of object that will be written.</param> ///// <returns><c>true</c> if objects of this <paramref name="type"/> can be written, otherwise <c>false</c>.</returns> //public override bool CanWriteType(Type type) { // if (type == null) { // throw new ArgumentNullException("type"); // } // if (UseDataContractJsonSerializer) { // MediaTypeFormatter.TryGetDelegatingTypeForIQueryableGenericOrSame(ref type); // // If there is a registered non-null serializer, we can support this type. // object serializer = // _dataContractSerializerCache.GetOrAdd(type, (t) => CreateDataContractSerializer(t)); // // Null means we tested it before and know it is not supported // return serializer != null; // } else { // return true; // } //} ///// <summary> ///// Called during deserialization to read an object of the specified <paramref name="type"/> ///// from the specified <paramref name="stream"/>. ///// </summary> ///// <param name="type">The type of object to read.</param> ///// <param name="stream">The <see cref="Stream"/> from which to read.</param> ///// <param name="contentHeaders">The <see cref="HttpContentHeaders"/> for the content being written.</param> ///// <param name="formatterLogger">The <see cref="IFormatterLogger"/> to log events to.</param> ///// <returns>A <see cref="Task"/> whose result will be the object instance that has been read.</returns> //public override Task<object> ReadFromStreamAsync(Type type, Stream stream, HttpContentHeaders contentHeaders, IFormatterLogger formatterLogger) { // if (type == null) { // throw new ArgumentNullException("type"); // } // if (stream == null) { // throw new ArgumentNullException("stream"); // } // return TaskHelpers.RunSynchronously<object>(() => { // // If content length is 0 then return default value for this type // if (contentHeaders != null && contentHeaders.ContentLength == 0) { // return GetDefaultValueForType(type); // } // // Get the character encoding for the content // Encoding effectiveEncoding = SelectCharacterEncoding(contentHeaders); // try { // if (UseDataContractJsonSerializer) { // DataContractJsonSerializer dataContractSerializer = GetDataContractSerializer(type); // using (XmlReader reader = JsonReaderWriterFactory.CreateJsonReader(new NonClosingDelegatingStream(stream), effectiveEncoding, _readerQuotas, null)) { // return dataContractSerializer.ReadObject(reader); // } // } else { // using (JsonTextReader jsonTextReader = new SecureJsonTextReader(new StreamReader(stream, effectiveEncoding), _maxDepth) { CloseInput = false }) { // JsonSerializer jsonSerializer = JsonSerializer.Create(_jsonSerializerSettings); // if (formatterLogger != null) { // // Error must always be marked as handled // // Failure to do so can cause the exception to be rethrown at every recursive level and overflow the stack for x64 CLR processes // jsonSerializer.Error += (sender, e) => { // Exception exception = e.ErrorContext.Error; // formatterLogger.LogError(e.ErrorContext.Path, exception.Message); // e.ErrorContext.Handled = true; // }; // } // return jsonSerializer.Deserialize(jsonTextReader, type); // } // } // } catch (Exception e) { // if (formatterLogger == null) { // throw; // } // formatterLogger.LogError(String.Empty, e.Message); // return GetDefaultValueForType(type); // } // }); //} /// <summary> /// Called during serialization to write an object of the specified <paramref name="type"/> /// to the specified <paramref name="stream"/>. /// </summary> /// <param name="type">The type of object to write.</param> /// <param name="value">The object to write.</param> /// <param name="writeStream">The <see cref="Stream"/> to which to write.</param> /// <param name="content">The <see cref="HttpContent"/> for the content being written.</param> /// <param name="transportContext">The <see cref="TransportContext"/>.</param> /// <returns>A <see cref="Task"/> that will write the value to the stream.</returns> public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext) { if (type == null) { throw new ArgumentNullException("type"); } if (writeStream == null) { throw new ArgumentNullException("stream"); } if (UseDataContractJsonSerializer && Indent) { throw new NotSupportedException(string.Format("Indentation is not supported by '{0}'", typeof(DataContractJsonSerializer))); } if (!UseDataContractJsonSerializer) { return(TaskHelpers.RunSynchronously(() => { Encoding effectiveEncoding = SelectCharacterEncoding(content.Headers); using (CustomJsonTextWriter jsonTextWriter = new CustomJsonTextWriter(new StreamWriter(writeStream, effectiveEncoding)) { CloseOutput = false }) { if (Indent) { jsonTextWriter.Formatting = Newtonsoft.Json.Formatting.Indented; } JsonSerializer jsonSerializer = JsonSerializer.Create(base.SerializerSettings); Func <MemberInfo, bool> include = (m) => jsonTextWriter.CurrentDepth < jsonSerializer.MaxDepth || jsonTextWriter.CurrentDepth == jsonSerializer.MaxDepth && !((PropertyInfo)m).PropertyType.FullName.Contains("Model.Entities"); //Func<MemberInfo, bool> include = (m) => jsonTextWriter.CurrentDepth < jsonSerializer.MaxDepth; if (jsonSerializer.ContractResolver != null) { jsonSerializer.ContractResolver = new CustomContractResolver(include); } jsonSerializer.Serialize(jsonTextWriter, value); jsonTextWriter.Flush(); } })); } else { return(base.WriteToStreamAsync(type, value, writeStream, content, transportContext)); } }