/// <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 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);
                }
            }));
        }
Esempio n. 3
0
        /// <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)
                            {
                                jsonSerializer.Error += (sender, e) =>
                                {
                                    Exception exception = e.ErrorContext.Error;

                                    // reader quota exceptions are fatal and cannot be recovered from
                                    // we need to shortcircuit any further deserialization
                                    if (exception is JsonReaderQuotaException)
                                    {
                                        e.ErrorContext.Handled = false;
                                    }
                                    else
                                    {
                                        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 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)
                            {
                                jsonSerializer.Error += (sender, e) =>
                                {
                                    Exception exception = e.ErrorContext.Error;

                                    // reader quota exceptions are fatal and cannot be recovered from
                                    // we need to shortcircuit any further deserialization
                                    if (exception is JsonReaderQuotaException)
                                    {
                                        e.ErrorContext.Handled = false;
                                    }
                                    else
                                    {
                                        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);
                }
            });
        }