示例#1
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);
        }
示例#2
0
        public virtual Task <object> ReadContentAsync(HttpRequestMessage request, Type type, IEnumerable <MediaTypeFormatter> formatters, IFormatterLogger formatterLogger)
        {
            HttpContent content = request.Content;

            if (content == null)
            {
                object defaultValue = MediaTypeFormatter.GetDefaultValueForType(type);
                if (defaultValue == null)
                {
                    return(TaskHelpers.NullResult());
                }
                else
                {
                    return(TaskHelpers.FromResult(defaultValue));
                }
            }

            try
            {
                return(content.ReadAsAsync(type, formatters, formatterLogger));
            }
            catch (UnsupportedMediaTypeException exception)
            {
                // If there is no Content-Type header, provide a better error message
                string errorFormat = content.Headers.ContentType == null ?
                                     SRResources.UnsupportedMediaTypeNoContentType :
                                     SRResources.UnsupportedMediaType;

                throw new HttpResponseException(
                          request.CreateErrorResponse(
                              HttpStatusCode.UnsupportedMediaType,
                              Error.Format(errorFormat, exception.MediaType.MediaType),
                              exception));
            }
        }
        private static object ReadAsInternal(
            this FormDataCollection formData,
            Type type,
            string modelName,
            HttpActionContext actionContext
            )
        {
            Contract.Assert(formData != null);
            Contract.Assert(type != null);
            Contract.Assert(actionContext != null);

            IValueProvider      valueProvider  = formData.GetJQueryValueProvider();
            ModelBindingContext bindingContext = CreateModelBindingContext(
                actionContext,
                modelName ?? String.Empty,
                type,
                valueProvider
                );

            ModelBinderProvider modelBinderProvider = CreateModelBindingProvider(actionContext);

            IModelBinder modelBinder = modelBinderProvider.GetBinder(
                actionContext.ControllerContext.Configuration,
                type
                );
            bool haveResult = modelBinder.BindModel(actionContext, bindingContext);

            if (haveResult)
            {
                return(bindingContext.Model);
            }

            return(MediaTypeFormatter.GetDefaultValueForType(type));
        }
        // There are many helper overloads for ReadAs*(). Provide one worker function to ensure the logic is shared.
        //
        // For loosely typed, T = Object, type = specific class.
        // For strongly typed, T == type.GetType()
        private static Task <T> ReadAsAsync <T>(
            HttpContent content,
            Type type,
            IEnumerable <MediaTypeFormatter> formatters,
            IFormatterLogger formatterLogger,
            CancellationToken cancellationToken
            )
        {
            if (content == null)
            {
                throw Error.ArgumentNull("content");
            }
            if (type == null)
            {
                throw Error.ArgumentNull("type");
            }
            if (formatters == null)
            {
                throw Error.ArgumentNull("formatters");
            }

            ObjectContent objectContent = content as ObjectContent;

            if (
                objectContent != null &&
                objectContent.Value != null &&
                type.IsAssignableFrom(objectContent.Value.GetType())
                )
            {
                return(Task.FromResult((T)objectContent.Value));
            }

            MediaTypeFormatter formatter = null;
            // Default to "application/octet-stream" if there is no content-type in accordance with section 7.2.1 of the HTTP spec
            MediaTypeHeaderValue mediaType =
                content.Headers.ContentType ?? MediaTypeConstants.ApplicationOctetStreamMediaType;

            formatter = new MediaTypeFormatterCollection(formatters).FindReader(type, mediaType);

            if (formatter == null)
            {
                if (content.Headers.ContentLength == 0)
                {
                    T defaultValue = (T)MediaTypeFormatter.GetDefaultValueForType(type);
                    return(Task.FromResult <T>(defaultValue));
                }

                throw new UnsupportedMediaTypeException(
                          Error.Format(
                              Properties.Resources.NoReadSerializerAvailable,
                              type.Name,
                              mediaType.MediaType
                              ),
                          mediaType
                          );
            }

            return(ReadAsAsyncCore <T>(content, type, formatterLogger, formatter, cancellationToken));
        }
示例#5
0
    private Task <object> ReadContentAsync(HttpRequestMessage request, Type type,
                                           IEnumerable <MediaTypeFormatter> formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)
    {
        var content = request.Content;

        if (content == null)
        {
            var defaultValue = MediaTypeFormatter.GetDefaultValueForType(type);
            return(defaultValue == null?Task.FromResult <object>(null) : Task.FromResult(defaultValue));
        }
        return(content.ReadAsAsync(type, formatters, formatterLogger, cancellationToken));
    }
        public override Task <object> ReadContentAsync(HttpRequestMessage request, Type type, IEnumerable <MediaTypeFormatter> formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)
        {
            /*********************** 代码块解释 *********************************
             * 以下代码大部分拷贝自 WebApi 中基类的源码。
             * 中间要完成的工作主要是:当路由中提供了 id,那么应该把这个值存储下来,并替换 HttpContent。
             * 注意:
             * 新建了一个类型 IdFromRouteHttpContent 用于把 Id 的值存储下来。
             **********************************************************************/

            HttpContent content = request.Content;

            if (content != null)
            {
                Task <object> result;
                try
                {
                    /*********************** 代码块解释 *********************************
                     * //modified by huqf------------start;*/
                    //如果路由中提供了 id,那么应该把这个值存储下来。
                    var    route = this.Descriptor.Configuration.Routes.GetRouteData(request);
                    object id    = null;
                    if (route.Values.TryGetValue("id", out id) && id != null && id != RouteParameter.Optional)
                    {
                        var idContent = new IdFromRouteHttpContent(content, id.ToString());
                        result = idContent.ReadAsAsync(type, formatters, formatterLogger, cancellationToken);
                    }
                    else
                    {
                        result = content.ReadAsAsync(type, formatters, formatterLogger, cancellationToken);
                    }

                    /*modified by huqf------------end.
                     * **********************************************************************/
                }
                catch (UnsupportedMediaTypeException ex)
                {
                    string format = (content.Headers.ContentType == null) ? "SRResources.UnsupportedMediaTypeNoContentType" : "SRResources.UnsupportedMediaType";
                    throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.UnsupportedMediaType, string.Format(format, new object[]
                    {
                        ex.MediaType.MediaType
                    }), ex));
                }
                return(result);
            }
            object defaultValueForType = MediaTypeFormatter.GetDefaultValueForType(type);

            if (defaultValueForType == null)
            {
                return(Task.FromResult <object>(null));
            }
            return(Task.FromResult(defaultValueForType));
        }
        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);
        }
        // There are many helper overloads for ReadAs*(). Provide one worker function to ensure the logic is shared.
        //
        // For loosely typed, T = Object, type = specific class.
        // For strongly typed, T == type.GetType()
        private static Task <T> ReadAsAsync <T>(HttpContent content, Type type, IEnumerable <MediaTypeFormatter> formatters, IFormatterLogger formatterLogger)
        {
            if (content == null)
            {
                throw Error.ArgumentNull("content");
            }
            if (type == null)
            {
                throw Error.ArgumentNull("type");
            }
            if (formatters == null)
            {
                throw Error.ArgumentNull("formatters");
            }

            ObjectContent objectContent = content as ObjectContent;

            if (objectContent != null && objectContent.Value != null && type.IsAssignableFrom(objectContent.Value.GetType()))
            {
                return(TaskHelpers.FromResult((T)objectContent.Value));
            }

            MediaTypeFormatter   formatter = null;
            MediaTypeHeaderValue mediaType = content.Headers.ContentType;

            if (mediaType != null)
            {
                formatter = new MediaTypeFormatterCollection(formatters).FindReader(type, mediaType);
            }
            else
            {
                T defaultValue = (T)MediaTypeFormatter.GetDefaultValueForType(type);
                return(TaskHelpers.FromResult <T>(defaultValue));
            }

            if (formatter == null)
            {
                string mediaTypeAsString = mediaType != null ? mediaType.MediaType : Properties.Resources.UndefinedMediaType;
                throw Error.InvalidOperation(Properties.Resources.NoReadSerializerAvailable, type.Name, mediaTypeAsString);
            }

            return(content.ReadAsStreamAsync()
                   .Then(stream => formatter.ReadFromStreamAsync(type, stream, content, formatterLogger)
                         .CastFromObject <T>()));
        }
示例#9
0
        public virtual Task <object> ReadContentAsync(HttpRequestMessage request, Type type, IEnumerable <MediaTypeFormatter> formatters, IFormatterLogger formatterLogger)
        {
            HttpContent content = request.Content;

            if (content == null)
            {
                object defaultValue = MediaTypeFormatter.GetDefaultValueForType(type);
                if (defaultValue == null)
                {
                    return(TaskHelpers.NullResult());
                }
                else
                {
                    return(TaskHelpers.FromResult(defaultValue));
                }
            }
            return(content.ReadAsAsync(type, formatters, formatterLogger));
        }
示例#10
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);
        }
示例#11
0
        // There are many helper overloads for ReadAs*(). Provide one worker function to ensure the logic is shared.
        //
        // For loosely typed, T = Object, type = specific class.
        // For strongly typed, T == type.GetType()
        private static Task <T> ReadAsAsync <T>(HttpContent content, Type type,
                                                IEnumerable <MediaTypeFormatter> formatters,
                                                IFormatterLogger?formatterLogger, CancellationToken cancellationToken)
        {
            if (content == null)
            {
                throw Error.ArgumentNull(nameof(content));
            }
            if (type == null)
            {
                throw Error.ArgumentNull(nameof(type));
            }
            if (formatters == null)
            {
                throw Error.ArgumentNull(nameof(formatters));
            }

            if (content is ObjectContent objectContent && objectContent.Value != null &&
                type.IsInstanceOfType(objectContent.Value))
            {
                return(Task.FromResult((T)objectContent.Value));
            }

            // Default to "application/octet-stream" if there is no content-type in accordance with section 7.2.1 of the HTTP spec
            var mediaType = content.Headers.ContentType ?? MediaTypeConstants.ApplicationOctetStreamMediaType;

            var formatter = new MediaTypeFormatterCollection(formatters).FindReader(type, mediaType);

            if (formatter == null)
            {
                if (content.Headers.ContentLength == 0)
                {
                    var defaultValue = (T)MediaTypeFormatter.GetDefaultValueForType(type) !;
                    return(Task.FromResult(defaultValue));
                }

                throw Error.UnsupportedMediaType(type, mediaType);
            }

            return(ReadAsAsyncCore <T>(content, type, formatterLogger, formatter, cancellationToken));
        }
示例#12
0
            private async Task <object> ReadContentAsync(
                HttpRequestMessage request,
                Type type,
                IEnumerable <MediaTypeFormatter> formatters,
                IFormatterLogger formatterLogger,
                CancellationToken cancellationToken)
            {
                var content = request.Content;

                if (content == null)
                {
                    var defaultValue = MediaTypeFormatter.GetDefaultValueForType(type);

                    return(defaultValue == null?Task.FromResult <object>(null) : Task.FromResult(defaultValue));
                }

                object contentValue = null;

                using (var onReadBodyContentStream = new MemoryStream())
                {
                    var contentStream = await content.ReadAsStreamAsync();

                    contentStream.CopyTo(onReadBodyContentStream);
                    onReadBodyContentStream.Seek(0, SeekOrigin.Begin);

                    var contentString = new StreamReader(onReadBodyContentStream).ReadToEnd();

                    // Gets our hydrated request-model.
                    contentValue = await new StringContent(
                        contentString,
                        Encoding.UTF8,
                        content.Headers.ContentType?.MediaType).ReadAsAsync(type, formatters, formatterLogger, cancellationToken);

                    // Reset our stream so any registered-event can read.
                    onReadBodyContentStream.Seek(0, SeekOrigin.Begin);

                    OnBoundBodyContentToObject(contentValue, onReadBodyContentStream);
                }

                return(contentValue);
            }
示例#13
0
        /// <summary>
        /// Deserialize the form data to the given type, using model binding.
        /// </summary>
        /// <param name="formData">collection with parsed form url data</param>
        /// <param name="type">target type to read as</param>
        /// <param name="modelName">null or empty to read the entire form as a single object. This is common for body data.
        /// <param name="requiredMemberSelector">The <see cref="IRequiredMemberSelector"/> used to determine required members.</param>
        /// <param name="formatterLogger">The <see cref="IFormatterLogger"/> to log events to.</param>
        /// Or the name of a model to do a partial binding against the form data. This is common for extracting individual fields.</param>
        /// <returns>best attempt to bind the object. The best attempt may be null.</returns>
        public static object ReadAs(this FormDataCollection formData, Type type, string modelName, IRequiredMemberSelector requiredMemberSelector, IFormatterLogger formatterLogger)
        {
            if (formData == null)
            {
                throw Error.ArgumentNull("formData");
            }
            if (type == null)
            {
                throw Error.ArgumentNull("type");
            }

            if (modelName == null)
            {
                modelName = String.Empty;
            }

            using (HttpConfiguration config = new HttpConfiguration())
            {
                bool validateRequiredMembers = requiredMemberSelector != null && formatterLogger != null;
                if (validateRequiredMembers)
                {
                    // Set a ModelValidatorProvider that understands the IRequiredMemberSelector
                    config.Services.Replace(typeof(ModelValidatorProvider), new RequiredMemberModelValidatorProvider(requiredMemberSelector));
                }

                // Looks like HttpActionContext is just a way of getting to the config, which we really
                // just need to get a list of modelbinderPRoviders for composition.
                HttpActionContext actionContext = CreateActionContextForModelBinding(config);

                IValueProvider      vp  = formData.GetJQueryValueProvider();
                ModelBindingContext ctx = CreateModelBindingContext(actionContext, modelName, type, vp);

                ModelBinderProvider modelBinderProvider = CreateModelBindingProvider(actionContext);

                IModelBinder binder     = modelBinderProvider.GetBinder(config, type);
                bool         haveResult = binder.BindModel(actionContext, ctx);

                // Log model binding errors
                if (formatterLogger != null)
                {
                    foreach (KeyValuePair <string, ModelState> modelStatePair in actionContext.ModelState)
                    {
                        foreach (ModelError modelError in modelStatePair.Value.Errors)
                        {
                            if (modelError.Exception != null)
                            {
                                formatterLogger.LogError(modelStatePair.Key, modelError.Exception);
                            }
                            else
                            {
                                formatterLogger.LogError(modelStatePair.Key, modelError.ErrorMessage);
                            }
                        }
                    }
                }

                if (haveResult)
                {
                    return(ctx.Model);
                }
                return(MediaTypeFormatter.GetDefaultValueForType(type));
            }
        }