public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger) {
            if (!DocumentUpgrader.Current.CanUpgradeType(type))
                return base.ReadFromStreamAsync(type, readStream, content, formatterLogger);

            Task<object> task = Task<object>.Factory.StartNew(() => {
                using (var reader = new StreamReader(readStream)) {
                    string json = reader.ReadToEnd();

                    try {
                        if (Settings.Current.SaveIncomingErrorsToDisk)
                            File.WriteAllText(String.Format("{0}\\{1}.json", Settings.Current.IncomingErrorPath, Guid.NewGuid().ToString("N")), json);
                    } catch (Exception ex) {
                        formatterLogger.LogError(String.Empty, ex);
                    }

                    try {
                        JObject document = JObject.Parse(json);
                        DocumentUpgrader.Current.Upgrade(document, type);
                        return JsonConvert.DeserializeObject(document.ToString(), type);
                    } catch (Exception ex) {
                        ex.ToExceptionless().AddObject(json, "Error").Submit();
                        formatterLogger.LogError(String.Empty, ex);
                        throw;
                    }
                }
            });

            return task;
        }
        /// <summary>
        /// Asynchronously deserializes an object of the specified type.
        /// </summary>
        /// <param name="type">The type of the object to deserialize.</param>
        /// <param name="readStream">The <see cref="T:System.IO.Stream" /> to read.</param>
        /// <param name="content">The <see cref="T:System.Net.Http.HttpContent" />, if available. It may be null.</param>
        /// <param name="formatterLogger">The <see cref="T:System.Net.Http.Formatting.IFormatterLogger" /> to log events to.</param>
        /// <returns>
        /// A <see cref="T:System.Threading.Tasks.Task" /> whose result will be an object of the given type.
        /// </returns>
        public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, System.Net.Http.HttpContent content, IFormatterLogger formatterLogger)
        {
            var tcs = new TaskCompletionSource<object>();

            try
            {
                var reader = GetJsonReader(readStream);
                using (reader)
                {
                    var jsonSerializerSettings = new JsonSerializerSettings();
                    jsonSerializerSettings.Converters.Add(new HyperNewtonsoftJsonConverter());
                    var jsonSerializer = JsonSerializer.Create(jsonSerializerSettings);
                    var output = jsonSerializer.Deserialize(reader, type);
                    if (formatterLogger != null)
                    {
                        jsonSerializer.Error += (sender, e) =>
                            {
                                var exception = e.ErrorContext.Error;
                                formatterLogger.LogError(e.ErrorContext.Path, exception.Message);
                                e.ErrorContext.Handled = true;
                            };
                    }
                    tcs.SetResult(output);
                }
            }
            catch (Exception e)
            {
                if (formatterLogger == null) throw;
                formatterLogger.LogError(String.Empty, e.Message);
                tcs.SetResult(GetDefaultValueForType(type));
            }

            return tcs.Task;
        }
        public override object ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger) {

            HttpContentHeaders contentHeaders = content == null ? null : content.Headers;

            // If content length is 0 then return default value for this type
            if (contentHeaders != null && contentHeaders.ContentLength == null) {

                return GetDefaultValueForType(type);
            }

            try {
                using (readStream) {
                    using (var reader = XmlReader.Create(readStream)) {

                        var formatter = new Atom10ItemFormatter();
                        formatter.ReadFrom(reader);

                        var command = Activator.CreateInstance(type);
                        ((IPublicationCommand)command).ReadSyndicationItem(formatter.Item);

                        return command;
                    }
                }
            }
            catch (Exception e) {

                if (formatterLogger == null) {
                    throw;
                }
                formatterLogger.LogError(String.Empty, e);
                return GetDefaultValueForType(type);
            }
        }
예제 #4
0
        private async Task<object> Deserialize(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {


            var headers = (content == null) ? null : content.Headers;
            if (headers != null && headers.ContentLength == 0L)
            {
                return MediaTypeFormatter.GetDefaultValueForType(type);
            }

            object result = null;
            try
            {

                result = DeserializeByJsonSerializer(type, readStream, headers);

            }
            catch (Exception exception)
            {
                if (formatterLogger != null)
                {
                    formatterLogger.LogError(string.Empty, exception);
                }

                result = MediaTypeFormatter.GetDefaultValueForType(type);
            }

            return result;
        }
        public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, System.Net.Http.HttpContent content, IFormatterLogger formatterLogger)
        {
            var taskCompletionSource = new TaskCompletionSource<object>();

            try
            {
                BsonReader reader = new BsonReader(readStream);
                if (typeof(IEnumerable).IsAssignableFrom(type)) reader.ReadRootValueAsArray = true;

                using (reader)
                {
                    var jsonSerializer = JsonSerializer.Create(_jsonSerializerSettings);
                    var output = jsonSerializer.Deserialize(reader, type);
                    if (formatterLogger != null)
                    {
                        jsonSerializer.Error += (sender, e) =>
                        {
                            Exception exception = e.ErrorContext.Error;
                            formatterLogger.LogError(e.ErrorContext.Path, exception.Message);
                            e.ErrorContext.Handled = true;
                        };
                    }
                    taskCompletionSource.SetResult(output);
                }
            }
            catch (Exception ex)
            {
                if (formatterLogger == null) throw;
                formatterLogger.LogError(String.Empty, ex.Message);
                taskCompletionSource.SetResult(GetDefaultValueForType(type));
            }

            return taskCompletionSource.Task;
        }
        private object ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            var root = GetRootFieldName(type);
            var contentHeaders = content == null ? null : content.Headers;

            // 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
            var effectiveEncoding = SelectCharacterEncoding(contentHeaders);

            try
            {
                using (var reader = (new StreamReader(readStream, effectiveEncoding)))
                {
                    var json = reader.ReadToEnd();
                    var serializer = new EmberJsonSerializer();
                    var deserialized = serializer.Deserialize(json, root);
                    return deserialized.ToObject(type);
                }
            }
            catch (Exception e)
            {
                if (formatterLogger == null)
                {
                    throw;
                }
                formatterLogger.LogError(String.Empty, e);
                return GetDefaultValueForType(type);
            }
        }
예제 #7
0
        /// <summary>
        /// Read RDF/XML from an HTTP input stream and convert to .NET objects
        /// </summary>
        /// <param name="type"></param>
        /// <param name="readStream"></param>
        /// <param name="content"></param>
        /// <param name="formatterLogger"></param>
        /// <returns></returns>
        public override Task <object> ReadFromStreamAsync(
            Type type,
            Stream readStream,
            HttpContent content,
            IFormatterLogger formatterLogger
            )
        {
            var tcs = new TaskCompletionSource <object>();

            if (content != null && content.Headers != null && content.Headers.ContentLength == 0)
            {
                return(null);
            }

            try
            {
                JsonObject jsonObject = (JsonObject)JsonObject.Load(readStream);

                Debug.WriteLine("JsonMediaTypeFormatter.ReadFromStreamAsync(): Loaded JSON: " + jsonObject);

                bool   isSingleton = IsSinglton(type);
                object output      = JsonHelper.FromJson(jsonObject, isSingleton ? type : GetMemberType(type));

                if (isSingleton)
                {
                    bool haveOne = (int)output.GetType().GetProperty("Count").GetValue(output, null) > 0;

                    tcs.SetResult(haveOne ? output.GetType().GetProperty("Item").GetValue(output, new object[] { 0 }): null);
                }
                else if (type.IsArray)
                {
                    tcs.SetResult(output.GetType().GetMethod("ToArray", Type.EmptyTypes).Invoke(output, null));
                }
                else
                {
                    tcs.SetResult(output);
                }
            }
            catch (Exception e)
            {
                if (formatterLogger == null)
                {
                    throw;
                }

                formatterLogger.LogError(String.Empty, e.Message);

                tcs.SetResult(GetDefaultValueForType(type));
            }

            return(tcs.Task);
        }
        /// <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 read.</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);

                object serializer = GetSerializerForType(type);

                try
                {
                    using (XmlReader reader = XmlDictionaryReader.CreateTextReader(new NonClosingDelegatingStream(stream), effectiveEncoding, _readerQuotas, null))
                    {
                        XmlSerializer xmlSerializer = serializer as XmlSerializer;
                        if (xmlSerializer != null)
                        {
                            return xmlSerializer.Deserialize(reader);
                        }
                        else
                        {
                            XmlObjectSerializer xmlObjectSerializer = (XmlObjectSerializer)serializer;
                            return xmlObjectSerializer.ReadObject(reader);
                        }
                    }
                }
                catch (Exception e)
                {
                    if (formatterLogger == null)
                    {
                        throw;
                    }
                    formatterLogger.LogError(String.Empty, e.Message);
                    return GetDefaultValueForType(type);
                }
            }));
        }
예제 #9
0
        /// <summary>
        /// Called during deserialization to read an object of the specified <paramref name="type"/>
        /// from the specified <paramref name="readStream"/>.
        /// </summary>
        /// <remarks>
        /// Public for delegating wrappers of this class.  Expected to be called only from
        /// <see cref="ReadFromStreamAsync"/>.
        /// </remarks>
        /// <param name="type">The <see cref="Type"/> of object to read.</param>
        /// <param name="readStream">The <see cref="Stream"/> from which to read.</param>
        /// <param name="effectiveEncoding">The <see cref="Encoding"/> to use when reading.</param>
        /// <param name="formatterLogger">The <see cref="IFormatterLogger"/> to log events to.</param>
        /// <returns>The <see cref="object"/> instance that has been read.</returns>
        public virtual object ReadFromStream(Type type, Stream readStream, Encoding effectiveEncoding, IFormatterLogger formatterLogger)
        {
            if (type == null)
            {
                throw Error.ArgumentNull("type");
            }

            if (readStream == null)
            {
                throw Error.ArgumentNull("readStream");
            }

            if (effectiveEncoding == null)
            {
                throw Error.ArgumentNull("effectiveEncoding");
            }

            using (JsonReader jsonReader = CreateJsonReaderInternal(type, readStream, effectiveEncoding))
            {
                jsonReader.CloseInput = false;
                jsonReader.MaxDepth   = _maxDepth;

                JsonSerializer jsonSerializer = CreateJsonSerializerInternal();

                EventHandler <Newtonsoft.Json.Serialization.ErrorEventArgs> errorHandler = null;
                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
                    errorHandler = (sender, e) =>
                    {
                        Exception exception = e.ErrorContext.Error;
                        formatterLogger.LogError(e.ErrorContext.Path, exception);
                        e.ErrorContext.Handled = true;
                    };
                    jsonSerializer.Error += errorHandler;
                }

                try
                {
                    return(jsonSerializer.Deserialize(jsonReader, type));
                }
                finally
                {
                    if (errorHandler != null)
                    {
                        // Clean up the error handler in case CreateJsonSerializer() reuses a serializer
                        jsonSerializer.Error -= errorHandler;
                    }
                }
            }
        }
        public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger) {
            HttpContentHeaders contentHeaders = content == null ? null : content.Headers;
            if (!DocumentUpgrader.Current.CanUpgradeType(type) || (contentHeaders != null && contentHeaders.ContentLength == 0))
                return base.ReadFromStreamAsync(type, readStream, content, formatterLogger);

            Task<object> task = Task<object>.Factory.StartNew(() => {
                Encoding effectiveEncoding = SelectCharacterEncoding(contentHeaders);
                try {
                    using (var reader = new StreamReader(readStream, effectiveEncoding)) {
                        string json = reader.ReadToEnd();

                        try {
                            if (Settings.Current.SaveIncomingErrorsToDisk)
                                File.WriteAllText(String.Format("{0}\\{1}.json", Settings.Current.IncomingErrorPath, Guid.NewGuid().ToString("N")), json);
                        } catch (Exception ex) {
                            if (formatterLogger != null)
                                formatterLogger.LogError(String.Empty, ex);
                        }

                        try {
                            JObject document = JObject.Parse(json);
                            DocumentUpgrader.Current.Upgrade(document, type);
                            return JsonConvert.DeserializeObject(document.ToString(), type);
                        } catch (Exception ex) {
                            ex.ToExceptionless().AddObject(json, "Error").Submit();
                            throw new Exception("An exception occurred while upgrading the document.", ex);
                        }
                    }
                } catch (Exception ex) {
                    if (formatterLogger == null)
                        throw;

                    formatterLogger.LogError(String.Empty, ex);
                    return GetDefaultValueForType(type);
                }
            });

            return task;
        }
예제 #11
0
        private T GetValue <T>(string name, string value, IFormatterLogger logger)
        {
            T result = default(T);

            try
            {
                result = (T)System.Convert.ChangeType(value, typeof(T));
            }
            catch
            {
                logger.LogError(name, "Cannot Parse Value");
            }
            return(result);
        }
        /// <summary>
        /// Asynchronously deserializes an object of the specified type.
        /// </summary>
        /// <param name="type">The type of the object to deserialize.</param>
        /// <param name="readStream">The <see cref="T:System.IO.Stream" /> to read.</param>
        /// <param name="content">The <see cref="T:System.Net.Http.HttpContent" />, if available. It may be null.</param>
        /// <param name="formatterLogger">The <see cref="T:System.Net.Http.Formatting.IFormatterLogger" /> to log events to.</param>
        /// <returns>
        /// A <see cref="T:System.Threading.Tasks.Task" /> whose result will be an object of the given type.
        /// </returns>
        public override Task <object> ReadFromStreamAsync(Type type, Stream readStream, System.Net.Http.HttpContent content, IFormatterLogger formatterLogger)
        {
            var tcs = new TaskCompletionSource <object>();

            try
            {
                var reader = GetJsonReader(readStream);
                using (reader)
                {
                    var jsonSerializerSettings = new JsonSerializerSettings();
                    jsonSerializerSettings.Converters.Add(new HyperNewtonsoftJsonConverter());
                    var jsonSerializer = JsonSerializer.Create(jsonSerializerSettings);
                    var output         = jsonSerializer.Deserialize(reader, type);
                    if (formatterLogger != null)
                    {
                        jsonSerializer.Error += (sender, e) =>
                        {
                            var exception = e.ErrorContext.Error;
                            formatterLogger.LogError(e.ErrorContext.Path, exception.Message);
                            e.ErrorContext.Handled = true;
                        };
                    }
                    tcs.SetResult(output);
                }
            }
            catch (Exception e)
            {
                if (formatterLogger == null)
                {
                    throw;
                }
                formatterLogger.LogError(String.Empty, e.Message);
                tcs.SetResult(GetDefaultValueForType(type));
            }

            return(tcs.Task);
        }
예제 #13
0
        private object ReadFromStream(Type type, Stream readStream,
                                      System.Net.Http.HttpContent content, IFormatterLogger formatterLogger,
                                      CancellationToken cancellationToken)
        {
            try
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return(null);
                }

                var    buffer = new byte[16 * 1024];
                byte[] data;
                using (var ms = new MemoryStream())
                {
                    int read;
                    while ((read = readStream.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        if (cancellationToken.IsCancellationRequested)
                        {
                            return(null);
                        }

                        ms.Write(buffer, 0, read);
                    }

                    data = ms.ToArray();
                }
                if (cancellationToken.IsCancellationRequested)
                {
                    return(null);
                }

                var serializer = ObjectBuilder.GetSerializer();

                var deserialized = serializer.Deserialize(data, null, type, ModeType.WebAPI);

                return(deserialized);
            }
            catch (Exception ex)
            {
                if (formatterLogger != null)
                {
                    formatterLogger.LogError(this.GetType().FullName, ex);
                }

                throw;
            }
        }
        private async Task <object> Deserialize(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            var idContent = content as IdFromRouteHttpContent;

            if (idContent != null)
            {
                content = idContent.Raw;
            }

            var headers = (content == null) ? null : content.Headers;

            if (headers != null && headers.ContentLength == 0L)
            {
                return(MediaTypeFormatter.GetDefaultValueForType(type));
            }

            object result = null;

            try
            {
                //对实体的属性进行特殊的处理。
                if (typeof(IDomainComponent).IsAssignableFrom(type))
                {
                    var json = await content.ReadAsStringAsync();

                    result = DeserializeDomainComponent(type, idContent != null ? idContent.Id : null, json);
                }
                //else if (type == typeof(CommonQueryCriteria))
                //{
                //    result = DesrializeCommonQueryCriteria(strContent);
                //}
                else
                {
                    result = DeserializeByJsonSerializer(type, readStream, headers);
                }
            }
            catch (Exception exception)
            {
                if (formatterLogger != null)
                {
                    formatterLogger.LogError(string.Empty, exception);
                }

                result = MediaTypeFormatter.GetDefaultValueForType(type);
            }

            return(result);
        }
예제 #15
0
        private object ReadFromStream(
            Type type,
            Stream readStream,
            HttpContent content,
            IFormatterLogger formatterLogger
            )
        {
            HttpContentHeaders contentHeaders = content == null ? null : content.Headers;

            // If content length is 0 then return default value for this type
            if (contentHeaders != null && contentHeaders.ContentLength == 0)
            {
                return(GetDefaultValueForType(type));
            }

            object serializer = GetDeserializer(type, content);

            try
            {
                using (XmlReader reader = CreateXmlReader(readStream, content))
                {
                    XmlSerializer xmlSerializer = serializer as XmlSerializer;
                    if (xmlSerializer != null)
                    {
                        return(xmlSerializer.Deserialize(reader));
                    }
                    else
                    {
                        XmlObjectSerializer xmlObjectSerializer = serializer as XmlObjectSerializer;
                        if (xmlObjectSerializer == null)
                        {
                            ThrowInvalidSerializerException(serializer, "GetDeserializer");
                        }
                        return(xmlObjectSerializer.ReadObject(reader));
                    }
                }
            }
            catch (Exception e)
            {
                if (formatterLogger == null)
                {
                    throw;
                }
                formatterLogger.LogError(String.Empty, e);
                return(GetDefaultValueForType(type));
            }
        }
    private object ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
    {
        var httpContentHeaders = content == null ? (HttpContentHeaders)null : content.Headers;

        if (httpContentHeaders != null)
        {
            var contentLength = httpContentHeaders.ContentLength;
            if ((contentLength.GetValueOrDefault() != 0L ? 0 : (contentLength.HasValue ? 1 : 0)) != 0)
            {
                return(GetDefaultValueForType(type));
            }
        }
        var settings = new XmlReaderSettings
        {
            DtdProcessing = DtdProcessing.Ignore
        };
        var deserializer = GetDeserializer(type, content);

        try
        {
            // The standard XmlMediaTypeFormatter will get the encoding from the HttpContent, instead
            // here the XmlReader will decide by itself according to the content
            using (var xmlReader = XmlReader.Create(readStream, settings))
            {
                var xmlSerializer = deserializer as XmlSerializer;
                if (xmlSerializer != null)
                {
                    return(xmlSerializer.Deserialize(xmlReader));
                }
                var objectSerializer = deserializer as XmlObjectSerializer;
                if (objectSerializer == null)
                {
                    throw new InvalidOperationException("xml object deserializer not available");
                }
                return(objectSerializer.ReadObject(xmlReader));
            }
        }
        catch (Exception ex)
        {
            if (formatterLogger == null)
            {
                throw;
            }
            formatterLogger.LogError(string.Empty, ex);
            return(GetDefaultValueForType(type));
        }
    }
        private async Task<object> ReadFromStreamAsyncCore(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            object obj = await base.ReadFromStreamAsync(typeof(FormDataCollection), readStream, content, formatterLogger);
            FormDataCollection fd = (FormDataCollection)obj;

            try
            {
                return fd.ReadAs(type, String.Empty, RequiredMemberSelector, formatterLogger, _configuration);
            }
            catch (Exception e)
            {
                if (formatterLogger == null)
                {
                    throw;
                }
                formatterLogger.LogError(String.Empty, e);
                return GetDefaultValueForType(type);
            }
        }
예제 #18
0
        private async Task <object> Deserialize(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            var headers = (content == null) ? null : content.Headers;

            if (headers != null && headers.ContentLength == 0L)
            {
                return(MediaTypeFormatter.GetDefaultValueForType(type));
            }

            object result = null;

            try
            {
                var strContent = await content.ReadAsStringAsync();

                //对实体的属性进行特殊的处理。
                if (type.IsSubclassOf(typeof(Entity)))
                {
                    var jObject = JObject.Parse(strContent);

                    result = DesrializeEntity(type, jObject);
                }
                //else if (type == typeof(CommonQueryCriteria))
                //{
                //    result = DesrializeCommonQueryCriteria(strContent);
                //}
                else
                {
                    result = DeserializeByJsonSerializer(type, readStream, headers);
                }
            }
            catch (Exception exception)
            {
                if (formatterLogger != null)
                {
                    formatterLogger.LogError(string.Empty, exception);
                }

                result = MediaTypeFormatter.GetDefaultValueForType(type);
            }

            return(result);
        }
        /// <param name="type">The type of the object to deserialize.</param>
        /// <param name="readStream">The <see cref="T:System.IO.Stream"/> to read.</param>
        /// <param name="content">The <see cref="T:System.Net.Http.HttpContent"/>, if available. It may be null.</param>
        /// <param name="formatterLogger">The <see cref="T:System.Net.Http.Formatting.IFormatterLogger"/> to log events to.</param>
        /// <returns>A <see cref="T:System.Threading.Tasks.Task"/> whose result will be an object of the given type.</returns>
        public override Task <object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            if (!CanReadType(type))
            {
                throw new InvalidOperationException();
            }

            if (content == null)
            {
                throw new ArgumentNullException("content");
            }

            if (!content.IsMimeMultipartContent())
            {
                throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
            }

            try
            {
                return(ReadFormDataAsync(content));
            }
            catch (Exception e)
            {
                if (formatterLogger == null)
                {
                    throw;
                }

                formatterLogger.LogError(string.Empty, e);
#if WEB_API2
                return(Task.FromResult <object>(new InputParameters()));
#else  // ASP.NET Web API 1
                var tcs = new TaskCompletionSource <object>();
                tcs.SetResult(new InputParameters());
                return(tcs.Task);
#endif
            }
        }
        public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content,
			IFormatterLogger formatterLogger)
        {
            if (content.IsMimeMultipartContent()) {
                var provider = GetMultipartProvider();

                try {
                    content.ReadAsMultipartAsync(provider);

                    object uploadData = GetFormData(type, provider);

                    return Task.FromResult(uploadData);
                }
                catch (Exception e) {
                    formatterLogger.LogError(e.Message, e);
                }
            }

            return base.ReadFromStreamAsync(type, readStream, content, formatterLogger);
        }
예제 #21
0
        private async Task <object> ReadFromStreamAsyncCore(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            object obj = await base.ReadFromStreamAsync(typeof(FormDataCollection), readStream, content, formatterLogger);

            FormDataCollection fd = (FormDataCollection)obj;

            try
            {
                return(fd.ReadAs(type, String.Empty, RequiredMemberSelector, formatterLogger));
            }
            catch (Exception e)
            {
                if (formatterLogger == null)
                {
                    throw;
                }
                formatterLogger.LogError(String.Empty, e);
                return(GetDefaultValueForType(type));
            }
        }
        private object ReadFromStream(Type type, Stream readStream, 
            System.Net.Http.HttpContent content, IFormatterLogger formatterLogger, 
            CancellationToken cancellationToken)
        {
            try
            {
                if (cancellationToken.IsCancellationRequested)
                    return null;

                var buffer = new byte[16*1024];
                byte[] data;
                using (var ms = new MemoryStream())
                {
                    int read;
                    while ((read = readStream.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        if (cancellationToken.IsCancellationRequested)
                            return null;

                        ms.Write(buffer, 0, read);
                    }

                    data = ms.ToArray();
                }
                if (cancellationToken.IsCancellationRequested)
                    return null;

                var serializer = ObjectBuilder.GetSerializer();

                var deserialized = serializer.Deserialize(data, null, type, ModeType.WebAPI);

                return deserialized;
            }
            catch(Exception ex)
            {
                if (formatterLogger != null)
                    formatterLogger.LogError(this.GetType().FullName, ex);

                throw;
            }
        }
        /// <summary>
        /// Reads synchronously from the buffered stream.
        /// </summary>
        /// <param name="type">The type of the object to deserialize.</param>
        /// <param name="readStream">The stream from which to read</param>
        /// <param name="content">The <see cref="T:System.Net.Http.HttpContent" />, if available. Can be null.</param>
        /// <param name="formatterLogger">The <see cref="T:System.Net.Http.Formatting.IFormatterLogger" /> to log events to.</param>
        /// <returns>
        /// An object of the given <paramref name="type" />.
        /// </returns>
        public override object ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            Throw.IfArgumentNull(type, "type");
            Throw.IfArgumentNull(readStream, "readStream");

            HttpContentHeaders contentHeaders = content == null ? null : content.Headers;

            // If content length is 0 then return default value for this type
            if (contentHeaders != null && contentHeaders.ContentLength == 0)
            {
                return(GetDefaultValueForType(type));
            }

            try
            {
                using (readStream)
                {
                    if (type.Implements <IPublication>())
                    {
                        return(ReadEntry(type, readStream, content.Headers.ContentType.MediaType));
                    }
                    else
                    {
                        var command = Activator.CreateInstance(type);
                        ((IMediaResourceCommand)command).ContentType = content.Headers.ContentType.MediaType;
                        ((IMediaResourceCommand)command).Content     = ReadFully(readStream);
                        ((IMediaResourceCommand)command).Summary     = "Added using Web Api";
                        return(command);
                    }
                }
            }
            catch (Exception e)
            {
                if (formatterLogger == null)
                {
                    throw;
                }
                formatterLogger.LogError(String.Empty, e);
                return(GetDefaultValueForType(type));
            }
        }
        public override Task <object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content,
                                                          IFormatterLogger formatterLogger)
        {
            if (content.IsMimeMultipartContent())
            {
                var provider = GetMultipartProvider();

                try {
                    content.ReadAsMultipartAsync(provider);

                    object uploadData = GetFormData(type, provider);

                    return(Task.FromResult(uploadData));
                }
                catch (Exception e) {
                    formatterLogger.LogError(e.Message, e);
                }
            }

            return(base.ReadFromStreamAsync(type, readStream, content, formatterLogger));
        }
        public override object ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            Ensure.Argument.NotNull(type, "type");
            Ensure.Argument.NotNull(readStream, "readStream");

            HttpContentHeaders contentHeaders = content == null ? null : content.Headers;

            // If content length is 0 then return default value for this type
            if (contentHeaders != null && contentHeaders.ContentLength == 0)
            {
                return(GetDefaultValueForType(type));
            }

            try
            {
                using (readStream)
                {
                    using (var reader = XmlReader.Create(readStream))
                    {
                        var formatter = new Atom10ItemFormatter();
                        formatter.ReadFrom(reader);

                        var command = Activator.CreateInstance(type);
                        ((IPublicationCommand)command)
                        .ReadSyndicationItem(formatter.Item);

                        return(command);
                    }
                }
            }
            catch (Exception e)
            {
                if (formatterLogger == null)
                {
                    throw;
                }
                formatterLogger.LogError(String.Empty, e);
                return(GetDefaultValueForType(type));
            }
        }
예제 #26
0
 public async override Task <object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
 {
     byte[]   buffer = new byte[Math.Min(content.Headers.ContentLength.Value, buffersize)];
     string[] items  = Encoding.Default.GetString(buffer, 0, await readStream.ReadAsync(buffer, 0, buffer.Length)).Split(',', '=');
     if (items.Length == 4)
     {
         return(new Numbers(
                    GetValue <int>("first", items[0], formatterLogger),
                    GetValue <int>("second", items[1], formatterLogger))
         {
             Op = new Operation {
                 Add = GetValue <bool>("Add", items[2], formatterLogger),
                 Double = GetValue <bool>("Double", items[3], formatterLogger)
             }
         });
     }
     else
     {
         formatterLogger.LogError("", "Wrong number of items");
         return(null);
     }
 }
        public override object ReadFromStream(Type type, System.IO.Stream readStream, System.Net.Http.HttpContent content, IFormatterLogger formatterLogger)
        {
            if (content.Headers != null && content.Headers.ContentLength == 0)
                return null;

            object result;
            try
            {
                var packer = new CompiledPacker(packPrivateField: false);
                result = packer.Unpack(type, readStream);
            }
            catch (Exception ex)
            {
                if (formatterLogger == null)
                    throw;

                formatterLogger.LogError("", ex.Message);
                result = GetDefaultValueForType(type);
            }

            return result;
        }
        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");
            }

            // For simple types, defer to base class
            if (base.CanReadType(type))
            {
                return base.ReadFromStreamAsync(type, stream, contentHeaders, formatterLogger);
            }

            return base.ReadFromStreamAsync(typeof(FormDataCollection), stream, contentHeaders, formatterLogger).Then(
                (obj) =>
                {
                    FormDataCollection fd = (FormDataCollection)obj;

                    try
                    {
                        return fd.ReadAs(type, String.Empty, RequiredMemberSelector, formatterLogger);
                    }
                    catch (Exception e)
                    {
                        if (formatterLogger == null)
                        {
                            throw;
                        }
                        formatterLogger.LogError(String.Empty, e.Message);
                        return GetDefaultValueForType(type);
                    }
                });
        }
        public override Task <object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            if (readStream == null)
            {
                throw new ArgumentNullException("readStream");
            }

            // For simple types, defer to base class
            if (base.CanReadType(type))
            {
                return(base.ReadFromStreamAsync(type, readStream, content, formatterLogger));
            }

            return(base.ReadFromStreamAsync(typeof(FormDataCollection), readStream, content, formatterLogger).Then(
                       (obj) =>
            {
                FormDataCollection fd = (FormDataCollection)obj;

                try
                {
                    return fd.ReadAs(type, String.Empty, RequiredMemberSelector, formatterLogger);
                }
                catch (Exception e)
                {
                    if (formatterLogger == null)
                    {
                        throw;
                    }
                    formatterLogger.LogError(String.Empty, e);
                    return GetDefaultValueForType(type);
                }
            }));
        }
        private object ReadFromStream(
            Type type,
            Stream readStream,
            HttpContent content,
            IFormatterLogger formatterLogger
            )
        {
            Contract.Assert(type != null);
            Contract.Assert(readStream != null);

            HttpContentHeaders contentHeaders = content == null ? null : content.Headers;

            // 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
            // Never non-null since SelectCharacterEncoding() throws in error / not found scenarios
            Encoding effectiveEncoding = SelectCharacterEncoding(contentHeaders);

            try
            {
                return(ReadFromStream(type, readStream, effectiveEncoding, formatterLogger));
            }
            catch (Exception e)
            {
                if (formatterLogger == null)
                {
                    throw;
                }

                formatterLogger.LogError(String.Empty, e);
                return(GetDefaultValueForType(type));
            }
        }
        public override async Task <object> ReadFromStreamAsync(
            Type type,
            Stream readStream,
            HttpContent content,
            IFormatterLogger formatterLogger)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }
            if (readStream == null)
            {
                throw new ArgumentNullException(nameof(readStream));
            }

            try
            {
                // load multipart data into memory
                var multipartProvider = await content.ReadAsMultipartAsync();

                // fill parts into a ditionary for later binding to model
                var modelDictionary = await ToModelDictionaryAsync(multipartProvider);

                // bind data to model
                return(BindToModel(modelDictionary, type, formatterLogger));
            }
            catch (Exception e)
            {
                if (formatterLogger == null)
                {
                    throw;
                }

                formatterLogger.LogError(string.Empty, e);
                return(GetDefaultValueForType(type));
            }
        }
예제 #32
0
        /// <inheritdoc />
        /// <exception cref="T:System.ArgumentNullException"><paramref name="type"/> is <see langword="null"/></exception>
        public override async Task <object?> ReadFromStreamAsync(
            Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }
            if (readStream == null)
            {
                throw new ArgumentNullException(nameof(readStream));
            }
            if (content == null)
            {
                throw new ArgumentNullException(nameof(content));
            }

            long?contentLength = content.Headers.ContentLength;

            if (contentLength.HasValue && contentLength.GetValueOrDefault() == 0L)
            {
                return(GetDefaultForType(type));
            }

            try
            {
                var result = await MessagePackSerializer.DeserializeAsync(type, readStream, _options)
                             .ConfigureAwait(false);

                return(result);
            }
            // ReSharper disable once CatchAllClause
            catch (Exception exception)
            {
                formatterLogger.LogError(string.Empty, exception);
                return(GetDefaultForType(type));
            }
        }
예제 #33
0
        public override Task<object> ReadFromStreamAsync(Type type, Stream stream, HttpContent content, IFormatterLogger formatterLogger)
        {
            var tcs = new TaskCompletionSource<object>();
            try
            {
                var serializer = MessagePackSerializer.Create(type);
                object result;
                using (var unpacker = Unpacker.Create(stream))
                {
                    unpacker.Read();
                    result = serializer.UnpackFrom(unpacker);
                }

                tcs.SetResult(result);
            }
            catch (Exception e)
            {
                if (formatterLogger == null) throw;
                formatterLogger.LogError(String.Empty, e.Message);
                tcs.SetResult(GetDefaultValueForType(type));
            }

            return tcs.Task;
        }
        public async override Task <object> ReadFromStreamAsync(Type type,
                                                                Stream readStream, HttpContent content,
                                                                IFormatterLogger formatterLogger)
        {
            byte[] buffer = new byte[Math.Min(content.Headers.ContentLength.Value,
                                              bufferSize)];
            string jsonString = Encoding.Default.GetString(buffer, 0,
                                                           await readStream.ReadAsync(buffer, 0, buffer.Length));

            JObject jData = JObject.Parse(jsonString);


            if (jData.Properties().Any(p =>
                                       string.Compare(p.Name, "includeinsale", true) == 0))
            {
                formatterLogger.LogError("IncludeInSale",
                                         "Request Must Not Contain IncludeInSale Value");
            }

            return(new Product {
                Name = (string)jData["name"],
                Price = (decimal)jData["price"]
            });
        }
예제 #35
0
        private object ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            var root           = GetRootFieldName(type);
            var contentHeaders = content == null ? null : content.Headers;

            // 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
            var effectiveEncoding = SelectCharacterEncoding(contentHeaders);

            try
            {
                using (var reader = (new StreamReader(readStream, effectiveEncoding)))
                {
                    var json = reader.ReadToEnd();

                    var parsedJson   = JObject.Parse(json);
                    var deserialized = parsedJson.SelectToken(root);

                    return(deserialized.ToObject(type));
                }
            }
            catch (Exception e)
            {
                if (formatterLogger == null)
                {
                    throw;
                }
                formatterLogger.LogError(String.Empty, e);
                return(GetDefaultValueForType(type));
            }
        }
        private object ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            object result;

            HttpContentHeaders contentHeaders = content == null ? null : content.Headers;

            // If content length is 0 then return default value for this type
            if (contentHeaders == null || contentHeaders.ContentLength == 0)
            {
                result = GetDefaultValueForType(type);
            }
            else
            {
                IEdmModel model = Request.GetEdmModel();
                if (model == null)
                {
                    throw Error.InvalidOperation(SRResources.RequestMustHaveModel);
                }

                IEdmTypeReference expectedPayloadType;
                ODataDeserializer deserializer = GetDeserializer(type, Request.GetODataPath(), model, _deserializerProvider, out expectedPayloadType);
                if (deserializer == null)
                {
                    throw Error.Argument("type", SRResources.FormatterReadIsNotSupportedForType, type.FullName, GetType().FullName);
                }

                try
                {
                    ODataMessageReaderSettings oDataReaderSettings = new ODataMessageReaderSettings(MessageReaderSettings);
                    oDataReaderSettings.BaseUri = GetBaseAddress(Request);

                    IODataRequestMessage oDataRequestMessage = new ODataMessageWrapper(readStream, contentHeaders, Request.GetODataContentIdMapping());
                    ODataMessageReader oDataMessageReader = new ODataMessageReader(oDataRequestMessage, oDataReaderSettings, model);

                    Request.RegisterForDispose(oDataMessageReader);
                    ODataPath path = Request.GetODataPath();
                    ODataDeserializerContext readContext = new ODataDeserializerContext
                    {
                        Path = path,
                        Model = model,
                        Request = Request,
                        ResourceType = type,
                        ResourceEdmType = expectedPayloadType,
                        RequestContext = Request.GetRequestContext(),
                    };

                    result = deserializer.Read(oDataMessageReader, type, readContext);
                }
                catch (Exception e)
                {
                    if (formatterLogger == null)
                    {
                        throw;
                    }

                    formatterLogger.LogError(String.Empty, e);
                    result = GetDefaultValueForType(type);
                }
            }

            return result;
        }
        public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            if (type == null)
                throw new ArgumentNullException("type");

            if (readStream == null)
                throw new ArgumentNullException("readStream");

            var serializer = SerializersCache.Current.GetSerializerForClass(type);

            if (serializer == null)
                return base.ReadFromStreamAsync(type, readStream, content, formatterLogger);

            return TaskHelpers.RunSynchronously<object>(() =>
            {
                HttpContentHeaders contentHeaders = content == null ? null : content.Headers;

                // 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
                {
                        using (JsonTextReader jsonTextReader = new JsonTextReader(new StreamReader(readStream, effectiveEncoding)) { CloseInput = false, MaxDepth = 256 })
                        {

                            var defaultSerializerSettings = CreateDefaultSerializerSettings();
                            defaultSerializerSettings.ContractResolver = serializer.GetContractResolver();

                            JsonSerializer jsonSerializer = JsonSerializer.Create(defaultSerializerSettings);
                            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);
                                    e.ErrorContext.Handled = true;
                                };
                            }
                            return jsonSerializer.Deserialize(jsonTextReader, type);
              //                      }
                    }
                }
                catch (Exception e)
                {
                    if (formatterLogger == null)
                    {
                        throw;
                    }
                    formatterLogger.LogError(String.Empty, e);
                    return GetDefaultValueForType(type);
                }
            });
        }
        /// <inheritdoc/>
        public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            if (type == null)
            {
                throw Error.ArgumentNull("type");
            }

            if (readStream == null)
            {
                throw Error.ArgumentNull("readStream");
            }

            return TaskHelpers.RunSynchronously<object>(() =>
            {
                object result;

                HttpContentHeaders contentHeaders = content == null ? null : content.Headers;
                // If content length is 0 then return default value for this type
                if (contentHeaders != null && contentHeaders.ContentLength == 0)
                {
                    result = GetDefaultValueForType(type);
                }
                else
                {
                    bool isPatchMode = TryGetInnerTypeForDelta(ref type);
                    ODataDeserializer deserializer = ODataDeserializerProvider.GetODataDeserializer(type);
                    if (deserializer == null)
                    {
                        throw Error.Argument("type", SRResources.FormatterReadIsNotSupportedForType, type.FullName, GetType().FullName);
                    }

                    ODataMessageReader oDataMessageReader = null;
                    ODataMessageReaderSettings oDataReaderSettings = new ODataMessageReaderSettings { DisableMessageStreamDisposal = true };
                    try
                    {
                        IODataRequestMessage oDataRequestMessage = new ODataMessageWrapper(readStream, contentHeaders);
                        oDataMessageReader = new ODataMessageReader(oDataRequestMessage, oDataReaderSettings, ODataDeserializerProvider.EdmModel);
                        ODataDeserializerContext readContext = new ODataDeserializerContext { IsPatchMode = isPatchMode, PatchKeyMode = PatchKeyMode, Request = Request, Model = Model };
                        result = deserializer.Read(oDataMessageReader, readContext);
                    }
                    catch (Exception e)
                    {
                        if (formatterLogger == null)
                        {
                            throw;
                        }

                        formatterLogger.LogError(String.Empty, e);
                        result = GetDefaultValueForType(type);
                    }
                    finally
                    {
                        if (oDataMessageReader != null)
                        {
                            oDataMessageReader.Dispose();
                        }
                    }
                }

                return result;
            });
        }
        private object ReadValue(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            var contentHeaders = content == null ? null : content.Headers;

            if (contentHeaders != null && contentHeaders.ContentLength == 0)
            {
                return GetDefaultValueForType(type);
            }

            var encoding = SelectCharacterEncoding(contentHeaders);

            try
            {
                var serializer = XmlSerializer.Create(type, new XmlSerializationOptions(encoding: encoding, shouldIndent: Indent));
                return serializer.Deserialize(readStream);
            }
            catch (Exception ex)
            {
                if (formatterLogger == null)
                {
                    throw;
                }

                formatterLogger.LogError(string.Empty, ex);

                return GetDefaultValueForType(type);
            }
        }
예제 #40
0
        private object ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            object retval = null;
            Type singleType = GetSingleType(type);
            var contentHeaders = content == null ? null : content.Headers;

            // If content length is 0 then return default value for this type
            if (contentHeaders != null && contentHeaders.ContentLength == 0)
                return GetDefaultValueForType(type);


            try
            {

                var effectiveEncoding = SelectCharacterEncoding(contentHeaders);
                JsonReader reader = this.CreateJsonReader(typeof (IDictionary<string, object>), readStream,
                    effectiveEncoding);

                reader.Read();
                if (reader.TokenType != JsonToken.StartObject)
                    throw new JsonSerializationException("Document root is not an object!");

                bool foundPrimaryData = false;
                while (reader.Read())
                {
                    if (reader.TokenType == JsonToken.PropertyName)
                    {
                        string value = (string) reader.Value;
                        reader.Read(); // burn the PropertyName token
                        switch (value)
                        {
                            case IncludedKeyName:
                                //TODO: If we want to capture linked/related objects in a compound document when deserializing, do it here...do we?
                                reader.Skip();
                                break;
                            case RelationshipsKeyName:
                                // ignore this, is it even meaningful in a PUT/POST body?
                                reader.Skip();
                                break;
                            case PrimaryDataKeyName:
                                // Could be a single resource or multiple, according to spec!
                                foundPrimaryData = true;
                                retval = DeserializePrimaryData(singleType, reader);
                                break;
                            case AttributesKeyName:
                                // Could be a single resource or multiple, according to spec!
                                foundPrimaryData = true;
                                retval = DeserializePrimaryData(singleType, reader);
                                break;
                        }
                    }
                    else
                        reader.Skip();
                }

                if (!foundPrimaryData)
                    throw new BadRequestException(String.Format("Expected primary data located at the `{0}` key", PrimaryDataKeyName));


                /* WARNING: May transform a single object into a list of objects!!!
                 * This is a necessary workaround to support POST and PUT of multiple 
                 * resoruces as per the spec, because WebAPI does NOT allow you to overload 
                 * a POST or PUT method based on the input parameter...i.e., you cannot 
                 * have a method that responds to POST of a single resource and a second 
                 * method that responds to the POST of a collection (list) of resources!
                 */
                if (retval != null)
                {
                    if (!type.IsAssignableFrom(retval.GetType()) && _modelManager.IsSerializedAsMany(type))
                    {
                        IList list = (IList) Activator.CreateInstance(typeof (List<>).MakeGenericType(singleType));
                        list.Add(retval);
                        return list;
                    }
                    else
                    {
                        return retval;
                    }
                }

            }
            catch (BadRequestException ex)
            {
                // We have to perform our own serialization of the error response here.
                var response = new HttpResponseMessage(HttpStatusCode.BadRequest);

                using (var writeStream = new MemoryStream())
                {
                    var effectiveEncoding = SelectCharacterEncoding(contentHeaders);
                    JsonWriter writer = CreateJsonWriter(typeof (object), writeStream, effectiveEncoding);
                    JsonSerializer serializer = CreateJsonSerializer();

                    var httpError = new HttpError(ex, true);
                        // TODO: allow consumer to choose whether to include error detail
                    _errorSerializer.SerializeError(httpError, writeStream, writer, serializer);

                    writer.Flush();
                    writeStream.Flush();
                    writeStream.Seek(0, SeekOrigin.Begin);

                    using (var stringReader = new StreamReader(writeStream))
                    {
                        var stringContent = stringReader.ReadToEnd(); // TODO: use async version
                        response.Content = new StringContent(stringContent, Encoding.UTF8, "application/vnd.api+json");
                    }
                }

                throw new HttpResponseException(response);
            }
            catch (Exception e)
            {
                if (formatterLogger == null)
                {
                    throw;
                }
                formatterLogger.LogError(String.Empty, e);
                return GetDefaultValueForType(type);
            }

            return GetDefaultValueForType(type);
        }
예제 #41
0
        public override Task <object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            if (type == null)
            {
                throw Error.ArgumentNull("type");
            }

            if (readStream == null)
            {
                throw Error.ArgumentNull("readStream");
            }

            if (Request == null)
            {
                throw Error.InvalidOperation(SRResources.ReadFromStreamAsyncMustHaveRequest);
            }

            object defaultValue = GetDefaultValueForType(type);

            // If content length is 0 then return default value for this type
            HttpContentHeaders contentHeaders = (content == null) ? null : content.Headers;

            if (contentHeaders == null || contentHeaders.ContentLength == 0)
            {
                return(Task.FromResult(defaultValue));
            }

            try
            {
                Func <ODataDeserializerContext> getODataDeserializerContext = () =>
                {
                    return(new ODataDeserializerContext
                    {
                        Request = Request,
                    });
                };

                Action <Exception> logErrorAction = (ex) =>
                {
                    if (formatterLogger == null)
                    {
                        throw ex;
                    }

                    formatterLogger.LogError(String.Empty, ex);
                };

                ODataDeserializerProvider deserializerProvider = Request.GetRequestContainer()
                                                                 .GetRequiredService <ODataDeserializerProvider>();

                return(Task.FromResult(ODataInputFormatterHelper.ReadFromStream(
                                           type,
                                           defaultValue,
                                           Request.GetModel(),
                                           GetBaseAddressInternal(Request),
                                           new WebApiRequestMessage(Request),
                                           () => ODataMessageWrapperHelper.Create(readStream, contentHeaders, Request.GetODataContentIdMapping(), Request.GetRequestContainer()),
                                           (objectType) => deserializerProvider.GetEdmTypeDeserializer(objectType),
                                           (objectType) => deserializerProvider.GetODataDeserializer(objectType, Request),
                                           getODataDeserializerContext,
                                           (disposable) => Request.RegisterForDispose(disposable),
                                           logErrorAction)));
            }
            catch (Exception ex)
            {
                return(TaskHelpers.FromError <object>(ex));
            }
        }
예제 #42
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="readStream"/>.
        /// </summary>
        /// <param name="type">The type of object to read.</param>
        /// <param name="readStream">The <see cref="Stream"/> from which to read.</param>
        /// <param name="content">The <see cref="HttpContent"/> 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 readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            if (type == null)
            {
                throw Error.ArgumentNull("type");
            }

            if (readStream == null)
            {
                throw Error.ArgumentNull("readStream");
            }

            return(TaskHelpers.RunSynchronously <object>(() =>
            {
                HttpContentHeaders contentHeaders = content == null ? null : content.Headers;

                // 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 !NETFX_CORE
                    if (UseDataContractJsonSerializer)
                    {
                        DataContractJsonSerializer dataContractSerializer = GetDataContractSerializer(type);
                        using (XmlReader reader = JsonReaderWriterFactory.CreateJsonReader(new NonClosingDelegatingStream(readStream), effectiveEncoding, _readerQuotas, null))
                        {
                            return dataContractSerializer.ReadObject(reader);
                        }
                    }
                    else
#endif
                    {
                        using (JsonTextReader jsonTextReader = new JsonTextReader(new StreamReader(readStream, effectiveEncoding))
                        {
                            CloseInput = false, MaxDepth = _maxDepth
                        })
                        {
                            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);
                                    e.ErrorContext.Handled = true;
                                };
                            }
                            return jsonSerializer.Deserialize(jsonTextReader, type);
                        }
                    }
                }
                catch (Exception e)
                {
                    if (formatterLogger == null)
                    {
                        throw;
                    }
                    formatterLogger.LogError(String.Empty, e);
                    return GetDefaultValueForType(type);
                }
            }));
        }
        /// <summary>
        /// Called during deserialization to read an object of the specified <paramref name="type"/>
        /// from the specified <paramref name="readStream"/>.
        /// </summary>
        /// <remarks>
        /// Public for delegating wrappers of this class.  Expected to be called only from
        /// <see cref="ReadFromStreamAsync"/>.
        /// </remarks>
        /// <param name="type">The <see cref="Type"/> of object to read.</param>
        /// <param name="readStream">The <see cref="Stream"/> from which to read.</param>
        /// <param name="effectiveEncoding">The <see cref="Encoding"/> to use when reading.</param>
        /// <param name="formatterLogger">The <see cref="IFormatterLogger"/> to log events to.</param>
        /// <returns>The <see cref="object"/> instance that has been read.</returns>
        public virtual object ReadFromStream(Type type, Stream readStream, Encoding effectiveEncoding, IFormatterLogger formatterLogger)
        {
            if (type == null)
            {
                throw Error.ArgumentNull("type");
            }

            if (readStream == null)
            {
                throw Error.ArgumentNull("readStream");
            }

            if (effectiveEncoding == null)
            {
                throw Error.ArgumentNull("effectiveEncoding");
            }

            using (JsonReader jsonReader = CreateJsonReaderInternal(type, readStream, effectiveEncoding))
            {
                jsonReader.CloseInput = false;
                jsonReader.MaxDepth = _maxDepth;

                JsonSerializer jsonSerializer = CreateJsonSerializerInternal();

                EventHandler<Newtonsoft.Json.Serialization.ErrorEventArgs> errorHandler = null;
                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
                    errorHandler = (sender, e) =>
                    {
                        Exception exception = e.ErrorContext.Error;
                        formatterLogger.LogError(e.ErrorContext.Path, exception);
                        e.ErrorContext.Handled = true;
                    };
                    jsonSerializer.Error += errorHandler;
                }

                try
                {
                    return jsonSerializer.Deserialize(jsonReader, type);
                }
                finally
                {
                    if (errorHandler != null)
                    {
                        // Clean up the error handler in case CreateJsonSerializer() reuses a serializer
                        jsonSerializer.Error -= errorHandler;
                    }
                }
            }
        }
        private object ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            Contract.Assert(type != null);
            Contract.Assert(readStream != null);

            HttpContentHeaders contentHeaders = content == null ? null : content.Headers;

            // 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
            // Never non-null since SelectCharacterEncoding() throws in error / not found scenarios
            Encoding effectiveEncoding = SelectCharacterEncoding(contentHeaders);

            try
            {
                return ReadFromStream(type, readStream, effectiveEncoding, formatterLogger);
            }
            catch (Exception e)
            {
                if (formatterLogger == null)
                {
                    throw;
                }

                formatterLogger.LogError(String.Empty, e);
                return GetDefaultValueForType(type);
            }
        }
예제 #46
0
        private object ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            object retval         = null;
            Type   singleType     = GetSingleType(type);
            var    pripropname    = _modelManager.GetJsonKeyForType(type);
            var    contentHeaders = content == null ? null : content.Headers;

            // If content length is 0 then return default value for this type
            if (contentHeaders != null && contentHeaders.ContentLength == 0)
            {
                return(GetDefaultValueForType(type));
            }


            try
            {
                var            effectiveEncoding = SelectCharacterEncoding(contentHeaders);
                JsonReader     reader            = this.CreateJsonReader(typeof(IDictionary <string, object>), readStream, effectiveEncoding);
                JsonSerializer serializer        = this.CreateJsonSerializer();

                reader.Read();
                if (reader.TokenType != JsonToken.StartObject)
                {
                    throw new JsonSerializationException("Document root is not an object!");
                }

                while (reader.Read())
                {
                    if (reader.TokenType == JsonToken.PropertyName)
                    {
                        string value = (string)reader.Value;
                        reader.Read(); // burn the PropertyName token
                        switch (value)
                        {
                        case "linked":
                            //TODO: If we want to capture linked/related objects in a compound document when deserializing, do it here...do we?
                            reader.Skip();
                            break;

                        case "links":
                            // ignore this, is it even meaningful in a PUT/POST body?
                            reader.Skip();
                            break;

                        default:
                            if (value == pripropname)
                            {
                                // Could be a single resource or multiple, according to spec!
                                if (reader.TokenType == JsonToken.StartArray)
                                {
                                    Type listType = (typeof(List <>)).MakeGenericType(singleType);
                                    retval = (IList)Activator.CreateInstance(listType);
                                    reader.Read();     // Burn off StartArray token
                                    while (reader.TokenType == JsonToken.StartObject)
                                    {
                                        ((IList)retval).Add(Deserialize(singleType, readStream, reader, serializer));
                                    }
                                    // burn EndArray token...
                                    if (reader.TokenType != JsonToken.EndArray)
                                    {
                                        throw new JsonReaderException(String.Format("Expected JsonToken.EndArray but got {0}", reader.TokenType));
                                    }
                                    reader.Read();
                                }
                                else
                                {
                                    // Because we choose what to deserialize based on the ApiController method signature
                                    // (not choose the method signature based on what we're deserializing), the `type`
                                    // parameter will always be `IList<Model>` even if a single model is sent!
                                    retval = Deserialize(singleType, readStream, reader, serializer);
                                }
                            }
                            else
                            {
                                reader.Skip();
                            }
                            break;
                        }
                    }
                    else
                    {
                        reader.Skip();
                    }
                }

                /* WARNING: May transform a single object into a list of objects!!!
                 * This is a necessary workaround to support POST and PUT of multiple
                 * resoruces as per the spec, because WebAPI does NOT allow you to overload
                 * a POST or PUT method based on the input parameter...i.e., you cannot
                 * have a method that responds to POST of a single resource and a second
                 * method that responds to the POST of a collection (list) of resources!
                 */
                if (retval != null)
                {
                    if (!type.IsAssignableFrom(retval.GetType()) && _modelManager.IsSerializedAsMany(type))
                    {
                        IList list = (IList)Activator.CreateInstance(typeof(List <>).MakeGenericType(singleType));
                        list.Add(retval);
                        return(list);
                    }
                    else
                    {
                        return(retval);
                    }
                }
            }
            catch (Exception e)
            {
                if (formatterLogger == null)
                {
                    throw;
                }
                formatterLogger.LogError(String.Empty, e);
                return(GetDefaultValueForType(type));
            }

            /*
             * try
             * {
             *  using (var reader = (new StreamReader(readStream, effectiveEncoding)))
             *  {
             *      var json = reader.ReadToEnd();
             *      var jo = JObject.Parse(json);
             *      return jo.SelectToken(root, false).ToObject(type);
             *  }
             * }
             * catch (Exception e)
             * {
             *  if (formatterLogger == null)
             *  {
             *      throw;
             *  }
             *  formatterLogger.LogError(String.Empty, e);
             *  return GetDefaultValueForType(type);
             * }
             */

            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);
                }
            });
        }
        private object ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            HttpContentHeaders contentHeaders = content == null ? null : content.Headers;

            // 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
            {
                using (JsonTextReader jsonTextReader = new JsonTextReader(new StreamReader(readStream, effectiveEncoding)) { CloseInput = false, MaxDepth = _maxDepth })
                {
                    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);
                            e.ErrorContext.Handled = true;
                        };
                    }
                    return jsonSerializer.Deserialize(jsonTextReader, type);
                }
            }
            catch (Exception e)
            {
                if (formatterLogger == null)
                {
                    throw;
                }
                formatterLogger.LogError(String.Empty, e);
                return GetDefaultValueForType(type);
            }
        }
        /// <summary>
        /// Read RDF/XML from an HTTP input stream and convert to .NET objects
        /// </summary>
        /// <param name="type"></param>
        /// <param name="readStream"></param>
        /// <param name="content"></param>
        /// <param name="formatterLogger"></param>
        /// <returns></returns>
        public override Task <object> ReadFromStreamAsync(
            Type type,
            Stream readStream,
            HttpContent content,
            IFormatterLogger formatterLogger
            )
        {
            var tcs = new TaskCompletionSource <object>();

            if (content != null && content.Headers != null && content.Headers.ContentLength == 0)
            {
                return(null);
            }

            try
            {
                IRdfReader rdfParser;

                if (content == null || content.Headers == null || content.Headers.ContentType.MediaType.Equals(OslcMediaType.APPLICATION_RDF_XML))
                {
                    rdfParser = new RdfXmlParser();
                }
                else if (content.Headers.ContentType.MediaType.Equals(OslcMediaType.TEXT_TURTLE))
                {
                    rdfParser = new TurtleParser(TurtleSyntax.W3C);
                }
                else
                {
                    //For now, use the dotNetRDF RdfXmlParser() for application/xml.  This could change
                    //rdfParser = new OslcXmlParser();
                    rdfParser = new RdfXmlParser();
                }

                IGraph       graph        = new Graph();
                StreamReader streamReader = new StreamReader(readStream);

                using (streamReader)
                {
                    rdfParser.Load(graph, streamReader);

                    bool   isSingleton = IsSinglton(type);
                    object output      = DotNetRdfHelper.FromDotNetRdfGraph(graph, isSingleton ? type : GetMemberType(type));

                    if (isSingleton)
                    {
                        bool haveOne = (int)output.GetType().GetProperty("Count").GetValue(output, null) > 0;

                        tcs.SetResult(haveOne ? output.GetType().GetProperty("Item").GetValue(output, new object[] { 0 }): null);
                    }
                    else if (type.IsArray)
                    {
                        tcs.SetResult(output.GetType().GetMethod("ToArray", Type.EmptyTypes).Invoke(output, null));
                    }
                    else
                    {
                        tcs.SetResult(output);
                    }
                }
            }
            catch (Exception e)
            {
                if (formatterLogger == null)
                {
                    throw;
                }

                formatterLogger.LogError(String.Empty, e.Message);

                tcs.SetResult(GetDefaultValueForType(type));
            }

            return(tcs.Task);
        }
예제 #50
0
        private object DeSerialize(Type type, Stream readStream, System.Net.Http.HttpContent content, IFormatterLogger formatterLogger)
        {
            HttpContentHeaders contentHeaders = content == null ? null : content.Headers;

            // 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
            {
                using (var reader = new StreamReader(readStream, effectiveEncoding, false, 512, true))
                {
                    var deserialize = TypedDeserializers.GetTyped(type);
                    return deserialize(reader, _jilOptions);
                }
            }
            catch (Exception e)
            {
                if (formatterLogger == null)
                {
                    throw;
                }
                formatterLogger.LogError(String.Empty, e);
                return GetDefaultValueForType(type);
            }
        }
        public override Task <object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            if (type == null)
            {
                throw Error.ArgumentNull("type");
            }

            if (readStream == null)
            {
                throw Error.ArgumentNull("readStream");
            }

            if (_request == null)
            {
                throw Error.InvalidOperation(SRResources.ReadFromStreamAsyncMustHaveRequest);
            }

            return(TaskHelpers.RunSynchronously <object>(() =>
            {
                object result;

                HttpContentHeaders contentHeaders = content == null ? null : content.Headers;

                // If content length is 0 then return default value for this type
                if (contentHeaders == null || contentHeaders.ContentLength == 0)
                {
                    result = GetDefaultValueForType(type);
                }
                else
                {
                    IEdmModel model = _request.GetEdmModel();
                    if (model == null)
                    {
                        throw Error.InvalidOperation(SRResources.RequestMustHaveModel);
                    }

                    Type originalType = type;
                    bool isPatchMode = TryGetInnerTypeForDelta(ref type);
                    ODataDeserializer deserializer = _deserializerProvider.GetODataDeserializer(model, type);
                    if (deserializer == null)
                    {
                        throw Error.Argument("type", SRResources.FormatterReadIsNotSupportedForType, type.FullName, GetType().FullName);
                    }

                    ODataMessageReader oDataMessageReader = null;
                    ODataMessageReaderSettings oDataReaderSettings = new ODataMessageReaderSettings
                    {
                        DisableMessageStreamDisposal = true,
                        MessageQuotas = MessageReaderQuotas,
                        BaseUri = GetBaseAddress(_request)
                    };

                    try
                    {
                        IODataRequestMessage oDataRequestMessage = new ODataMessageWrapper(readStream, contentHeaders);
                        oDataMessageReader = new ODataMessageReader(oDataRequestMessage, oDataReaderSettings, model);

                        _request.RegisterForDispose(oDataMessageReader);
                        ODataPath path = _request.GetODataPath();
                        ODataDeserializerContext readContext = new ODataDeserializerContext
                        {
                            IsPatchMode = isPatchMode,
                            Path = path,
                            Model = model,
                            Request = _request
                        };

                        if (isPatchMode)
                        {
                            readContext.PatchEntityType = originalType;
                        }

                        result = deserializer.Read(oDataMessageReader, readContext);
                    }
                    catch (Exception e)
                    {
                        if (formatterLogger == null)
                        {
                            throw;
                        }

                        formatterLogger.LogError(String.Empty, e);
                        result = GetDefaultValueForType(type);
                    }
                }

                return result;
            }));
        }
예제 #52
0
        private object ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            object result;

            HttpContentHeaders contentHeaders = content == null ? null : content.Headers;

            // If content length is 0 then return default value for this type
            if (contentHeaders == null || contentHeaders.ContentLength == 0)
            {
                result = GetDefaultValueForType(type);
            }
            else
            {
                IEdmModel model = Request.ODataProperties().Model;
                if (model == null)
                {
                    throw Error.InvalidOperation(SRResources.RequestMustHaveModel);
                }

                IEdmTypeReference expectedPayloadType;
                ODataDeserializer deserializer = GetDeserializer(type, Request.ODataProperties().Path, model, _deserializerProvider, out expectedPayloadType);
                if (deserializer == null)
                {
                    throw Error.Argument("type", SRResources.FormatterReadIsNotSupportedForType, type.FullName, GetType().FullName);
                }

                try
                {
                    ODataMessageReaderSettings oDataReaderSettings = new ODataMessageReaderSettings(MessageReaderSettings);
                    oDataReaderSettings.BaseUri = GetBaseAddress(Request);

                    IODataRequestMessage oDataRequestMessage = new ODataMessageWrapper(readStream, contentHeaders, Request.GetODataContentIdMapping());
                    ODataMessageReader   oDataMessageReader  = new ODataMessageReader(oDataRequestMessage, oDataReaderSettings, model);

                    Request.RegisterForDispose(oDataMessageReader);
                    ODataPath path = Request.ODataProperties().Path;
                    ODataDeserializerContext readContext = new ODataDeserializerContext
                    {
                        Path            = path,
                        Model           = model,
                        Request         = Request,
                        ResourceType    = type,
                        ResourceEdmType = expectedPayloadType,
                        RequestContext  = Request.GetRequestContext(),
                    };

                    result = deserializer.Read(oDataMessageReader, type, readContext);
                }
                catch (Exception e)
                {
                    if (formatterLogger == null)
                    {
                        throw;
                    }

                    formatterLogger.LogError(String.Empty, e);
                    result = GetDefaultValueForType(type);
                }
            }

            return(result);
        }
        /// <summary>
        /// Called during deserialization to read an object of the specified <paramref name="type"/>
        /// from the specified <paramref name="readStream"/>.
        /// </summary>
        /// <param name="type">The type of object to read.</param>
        /// <param name="readStream">The <see cref="Stream"/> from which to read.</param>
        /// <param name="content">The <see cref="HttpContent"/> 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 readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            if (type == null)
            {
                throw Error.ArgumentNull("type");
            }

            if (readStream == null)
            {
                throw Error.ArgumentNull("readStream");
            }

            return TaskHelpers.RunSynchronously<object>(() =>
            {
                HttpContentHeaders contentHeaders = content == null ? null : content.Headers;

                // 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 !NETFX_CORE
                    if (UseDataContractJsonSerializer)
                    {
                        DataContractJsonSerializer dataContractSerializer = GetDataContractSerializer(type);
                        using (XmlReader reader = JsonReaderWriterFactory.CreateJsonReader(new NonClosingDelegatingStream(readStream), effectiveEncoding, _readerQuotas, null))
                        {
                            return dataContractSerializer.ReadObject(reader);
                        }
                    }
                    else
#endif
                    {
                        using (JsonTextReader jsonTextReader = new JsonTextReader(new StreamReader(readStream, effectiveEncoding)) { CloseInput = false, MaxDepth = _maxDepth })
                        {
                            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);
                                    e.ErrorContext.Handled = true;
                                };
                            }
                            return jsonSerializer.Deserialize(jsonTextReader, type);
                        }
                    }
                }
                catch (Exception e)
                {
                    if (formatterLogger == null)
                    {
                        throw;
                    }
                    formatterLogger.LogError(String.Empty, e);
                    return GetDefaultValueForType(type);
                }
            });
        }
        public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            if (type == null)
            {
                throw Error.ArgumentNull("type");
            }

            if (readStream == null)
            {
                throw Error.ArgumentNull("readStream");
            }

            if (_request == null)
            {
                throw Error.InvalidOperation(SRResources.ReadFromStreamAsyncMustHaveRequest);
            }

            return TaskHelpers.RunSynchronously<object>(() =>
            {
                object result;

                HttpContentHeaders contentHeaders = content == null ? null : content.Headers;

                // If content length is 0 then return default value for this type
                if (contentHeaders == null || contentHeaders.ContentLength == 0)
                {
                    result = GetDefaultValueForType(type);
                }
                else
                {
                    IEdmModel model = _request.GetEdmModel();
                    if (model == null)
                    {
                        throw Error.InvalidOperation(SRResources.RequestMustHaveModel);
                    }

                    Type originalType = type;
                    bool isPatchMode = TryGetInnerTypeForDelta(ref type);
                    ODataDeserializer deserializer = _deserializerProvider.GetODataDeserializer(model, type);
                    if (deserializer == null)
                    {
                        throw Error.Argument("type", SRResources.FormatterReadIsNotSupportedForType, type.FullName, GetType().FullName);
                    }

                    ODataMessageReader oDataMessageReader = null;
                    ODataMessageReaderSettings oDataReaderSettings = new ODataMessageReaderSettings
                    {
                        DisableMessageStreamDisposal = true,
                        MessageQuotas = MessageReaderQuotas,
                        BaseUri = GetBaseAddress(_request)
                    };

                    try
                    {
                        IODataRequestMessage oDataRequestMessage = new ODataMessageWrapper(readStream, contentHeaders);
                        oDataMessageReader = new ODataMessageReader(oDataRequestMessage, oDataReaderSettings, model);

                        _request.RegisterForDispose(oDataMessageReader);
                        ODataPath path = _request.GetODataPath();
                        ODataDeserializerContext readContext = new ODataDeserializerContext
                        {
                            IsPatchMode = isPatchMode,
                            Path = path,
                            Model = model,
                            Request = _request
                        };

                        if (isPatchMode)
                        {
                            readContext.PatchEntityType = originalType;
                        }

                        result = deserializer.Read(oDataMessageReader, readContext);
                    }
                    catch (Exception e)
                    {
                        if (formatterLogger == null)
                        {
                            throw;
                        }

                        formatterLogger.LogError(String.Empty, e);
                        result = GetDefaultValueForType(type);
                    }
                }

                return result;
            });
        }
예제 #55
0
        private object BindToModel(IDictionary <string, object> data, Type type, IFormatterLogger formatterLogger)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            using (var config = new HttpConfiguration())
            {
                // if there is a requiredMemberSelector set, use this one by replacing the validator provider
                var validateRequiredMembers = RequiredMemberSelector != null && formatterLogger != null;
                if (validateRequiredMembers)
                {
                    config.Services.Replace(typeof(ModelValidatorProvider), new RequiredMemberModelValidatorProvider(RequiredMemberSelector));
                }

                // create a action context for model binding
                var actionContext = new HttpActionContext
                {
                    ControllerContext = new HttpControllerContext
                    {
                        Configuration        = config,
                        ControllerDescriptor = new HttpControllerDescriptor
                        {
                            Configuration = config
                        }
                    }
                };

                // create model binder context
                var valueProvider       = new NameValuePairsValueProvider(data, CultureInfo.InvariantCulture);
                var metadataProvider    = actionContext.ControllerContext.Configuration.Services.GetModelMetadataProvider();
                var metadata            = metadataProvider.GetMetadataForType(null, type);
                var modelBindingContext = new ModelBindingContext
                {
                    ModelName             = string.Empty,
                    FallbackToEmptyPrefix = false,
                    ModelMetadata         = metadata,
                    ModelState            = actionContext.ModelState,
                    ValueProvider         = valueProvider
                };

                // bind model
                var modelBinderProvider = new CompositeModelBinderProvider(config.Services.GetModelBinderProviders());
                var binder     = modelBinderProvider.GetBinder(config, type);
                var haveResult = binder.BindModel(actionContext, modelBindingContext);

                // log validation errors
                if (formatterLogger != null)
                {
                    foreach (var modelStatePair in actionContext.ModelState)
                    {
                        foreach (var modelError in modelStatePair.Value.Errors)
                        {
                            if (modelError.Exception != null)
                            {
                                formatterLogger.LogError(modelStatePair.Key, modelError.Exception);
                            }
                            else
                            {
                                formatterLogger.LogError(modelStatePair.Key, modelError.ErrorMessage);
                            }
                        }
                    }
                }

                return(haveResult ? modelBindingContext.Model : GetDefaultValueForType(type));
            }
        }