예제 #1
0
        /// <summary>
        /// Initializes a new instance of a <see cref="ResponseContentHandler"/> with the
        /// given <paramref name="responseContentParameter"/> and <paramref name="formatters"/>.
        /// </summary>
        /// <param name="responseContentParameter">The <see cref="HttpParameter"/> for the content of the response.</param>
        /// <param name="formatters">The collection of <see cref="MediaTypeFormatter"/> instances to use for deserializing the response content.</param>
        public ResponseContentHandler(HttpParameter responseContentParameter, IEnumerable <MediaTypeFormatter> formatters)
        {
            if (formatters == null)
            {
                throw Fx.Exception.ArgumentNull("formatters");
            }

            Type paramType = responseContentParameter == null ?
                             TypeHelper.VoidType :
                             responseContentParameter.Type;

            if (paramType == TypeHelper.VoidType)
            {
                this.responseMessageConverter = voidHttpResponseMessageConverter;
                this.outputParameter          = HttpParameter.ResponseMessage;
            }
            else
            {
                paramType = HttpTypeHelper.GetHttpResponseOrContentInnerTypeOrNull(paramType) ?? paramType;

                if (HttpTypeHelper.IsHttpRequest(paramType))
                {
                    throw Fx.Exception.AsError(
                              new InvalidOperationException(
                                  SR.InvalidParameterForContentHandler(
                                      HttpParameter.HttpParameterType.Name,
                                      responseContentParameter.Name,
                                      responseContentParameter.Type.Name,
                                      responseContentHandlerType.Name)));
                }

                Type outputParameterType = HttpTypeHelper.IsHttp(paramType) ? paramType : HttpTypeHelper.MakeHttpResponseMessageOf(paramType);
                this.outputParameter = new HttpParameter(responseContentParameter.Name, outputParameterType);

                this.inputParameter = responseContentParameter;

                if (HttpTypeHelper.IsHttpResponse(paramType))
                {
                    this.responseMessageConverter = simpleHttpResponseMessageConverter;
                }
                else if (HttpTypeHelper.IsHttpContent(paramType))
                {
                    this.responseMessageConverter = httpContentMessageConverter;
                }
                else
                {
                    Type            closedConverterType = httpResponseMessageConverterGenericType.MakeGenericType(new Type[] { paramType });
                    ConstructorInfo constructor         = closedConverterType.GetConstructor(Type.EmptyTypes);
                    this.responseMessageConverter = constructor.Invoke(null) as HttpResponseMessageConverter;
                }
            }

            this.Formatters = new MediaTypeFormatterCollection(formatters);
        }
예제 #2
0
        private static bool IsPossibleRequestContentParameter(HttpParameter parameter)
        {
            Fx.Assert(parameter != null, "The 'parameter' parameter should not be null.");

            if (parameter.IsContentParameter ||
                HttpTypeHelper.GetHttpRequestOrContentInnerTypeOrNull(parameter.Type) != null)
            {
                return(true);
            }

            return(false);
        }
예제 #3
0
        private static void SetXmlAndJsonSerializers(HttpOperationDescription operation, HttpParameter httpParameter, MediaTypeFormatterCollection formatters)
        {
            Fx.Assert(operation != null, "The 'operation' parameter should not be null.");
            Fx.Assert(httpParameter != null, "The 'httpParameter' parameter should not be null.");
            Fx.Assert(formatters != null, "The 'formatters' parameter should not be null.");

            Type contentType = HttpTypeHelper.GetHttpInnerTypeOrNull(httpParameter.Type) ?? httpParameter.Type;

            if (contentType != typeof(JsonValue) && !HttpTypeHelper.IsHttp(contentType))
            {
                SetSerializerForXmlFormatter(operation, contentType, formatters);
                SetSerializerForJsonFormatter(operation, contentType, httpParameter.Name, formatters);
            }
        }
예제 #4
0
        public static HttpParameterValueConverter GetValueConverter(Type type)
        {
            if (type == null)
            {
                throw Fx.Exception.ArgumentNull("type");
            }

            Type objectContentTypeArg = HttpTypeHelper.GetHttpContentInnerTypeOrNull(type);

            if (objectContentTypeArg != null)
            {
                Type            closedConverterType = objectContentValueConverterGenericType.MakeGenericType(new Type[] { objectContentTypeArg });
                ConstructorInfo constructor         = closedConverterType.GetConstructor(Type.EmptyTypes);
                return(constructor.Invoke(null) as HttpParameterValueConverter);
            }

            if (HttpTypeHelper.IsHttp(type))
            {
                Type            closedConverterType = refValueConverterGenericType.MakeGenericType(new Type[] { type });
                ConstructorInfo constructor         = closedConverterType.GetConstructor(Type.EmptyTypes);
                return(constructor.Invoke(null) as HttpParameterValueConverter);
            }

            Type nullableUnderlyingType = Nullable.GetUnderlyingType(type);
            bool typeIsNullable         = nullableUnderlyingType != null;
            Type actualType             = typeIsNullable ? nullableUnderlyingType : type;

            if (actualType.IsEnum)
            {
                Type            closedConverterType = enumValueConverterGenericType.MakeGenericType(new Type[] { actualType });
                ConstructorInfo constructor         = closedConverterType.GetConstructor(Type.EmptyTypes);
                return(constructor.Invoke(null) as HttpParameterValueConverter);
            }

            switch (Type.GetTypeCode(actualType))
            {
            case TypeCode.Boolean: return(booleanValueConverter);

            case TypeCode.Char: return(charValueConverter);

            case TypeCode.SByte: return(signedByteValueConverter);

            case TypeCode.Byte: return(byteValueConverter);

            case TypeCode.Int16: return(int16ValueConverter);

            case TypeCode.UInt16: return(unsignedInt16ValueConverter);

            case TypeCode.Int32: return(int32ValueConverter);

            case TypeCode.UInt32: return(unsignedInt32ValueConverter);

            case TypeCode.Int64: return(int64ValueConverter);

            case TypeCode.UInt64: return(unsignedInt64ValueConverter);

            case TypeCode.Single: return(singleValueConverter);

            case TypeCode.Double: return(doubleValueConverter);

            case TypeCode.Decimal: return(decimalValueConverter);

            case TypeCode.DateTime: return(dateTimeValueConverter);

            default:
                break;
            }

            if (actualType == typeof(TimeSpan))
            {
                return(timeSpanValueConverter);
            }
            else if (actualType == typeof(Guid))
            {
                return(guidValueConverter);
            }
            else if (actualType == typeof(DateTimeOffset))
            {
                return(dateTimeOffsetValueConverter);
            }
            else if (actualType == typeof(Uri))
            {
                return(uriValueConverter);
            }

            Type            closedValueConverterType  = nonNullableValueConverterGenericType.MakeGenericType(new Type[] { actualType });
            ConstructorInfo valueConverterConstructor = closedValueConverterType.GetConstructor(Type.EmptyTypes);

            return(valueConverterConstructor.Invoke(null) as HttpParameterValueConverter);
        }
예제 #5
0
        private static List <HttpParameterBinding> BindHandlers(List <HttpOperationHandler> handlers, string operationName, int serviceOperationIndex)
        {
            Fx.Assert(handlers != null, "The 'handlers' parameter should not be null.");
            Fx.Assert(operationName != null, "The 'operationName' parameter should not be null.");

            List <HttpParameterBinding> pipelineBindings = new List <HttpParameterBinding>();

            for (int inHandlerIndex = handlers.Count - 1; inHandlerIndex >= 1; inHandlerIndex--)
            {
                HttpOperationHandler inHandler     = handlers[inHandlerIndex];
                HandlerType          inHandlerType = GetHandlerType(inHandlerIndex, serviceOperationIndex);

                for (int inParamIndex = 0; inParamIndex < inHandler.InputParameters.Count; inParamIndex++)
                {
                    HttpParameter inParam = inHandler.InputParameters[inParamIndex];
                    List <HttpParameterBinding> bindings          = new List <HttpParameterBinding>();
                    List <HttpParameterBinding> tentativeBindings = new List <HttpParameterBinding>();

                    for (int outHandlerIndex = inHandlerIndex - 1; outHandlerIndex >= 0; outHandlerIndex--)
                    {
                        HttpOperationHandler outHandler     = handlers[outHandlerIndex];
                        HandlerType          outHandlerType = GetHandlerType(outHandlerIndex, serviceOperationIndex);

                        for (int outParamIndex = 0; outParamIndex < outHandler.OutputParameters.Count; outParamIndex++)
                        {
                            HttpParameter outParam = outHandler.OutputParameters[outParamIndex];

                            if (inParam.IsAssignableFromParameter(outParam.Type))
                            {
                                HttpParameterBinding binding = new HttpParameterBinding();
                                binding.InputHandler         = inHandler;
                                binding.InputHandlerIndex    = inHandlerIndex;
                                binding.InputParameter       = inParam;
                                binding.InputParameterIndex  = inParamIndex;
                                binding.InputHandlerType     = inHandlerType;
                                binding.OutputHandler        = outHandler;
                                binding.OutputHandlerIndex   = outHandlerIndex;
                                binding.OutputParameter      = outParam;
                                binding.OutputParameterIndex = outParamIndex;
                                binding.OutputHandlerType    = outHandlerType;

                                // If their names match or the input is either HttpRequesMessage,
                                //  HttpResponseMessage, or HttpContent, then go ahead and bind
                                if (string.Equals(outParam.Name, inParam.Name, StringComparison.OrdinalIgnoreCase) ||
                                    HttpTypeHelper.IsHttp(inParam.Type))
                                {
                                    bindings.Add(binding);
                                }
                                else
                                {
                                    // Otherwise we will tentatively bind if this is
                                    //  not a string conversion assignment
                                    if (outParam.Type != TypeHelper.StringType ||
                                        !inParam.ValueConverter.CanConvertFromString)
                                    {
                                        tentativeBindings.Add(binding);
                                    }
                                }
                            }
                        }
                    }

                    if (bindings.Count > 0)
                    {
                        pipelineBindings.AddRange(bindings);
                    }
                    else if (tentativeBindings.Count == 1)
                    {
                        pipelineBindings.AddRange(tentativeBindings);
                    }
                    else if (tentativeBindings.Count > 1)
                    {
                        ThrowForMulitpleTypeOnlyBindings(tentativeBindings, operationName);
                    }
                    else
                    {
                        ThrowForUnboundParameter(inHandler, inParam, inHandlerType, operationName);
                    }
                }
            }

            return(pipelineBindings);
        }