Esempio n. 1
0
        public void HttpOperationDescription_Return_Parameter_Matches_Void_Method()
        {
            OperationDescription     od  = GetOperationDescription(typeof(SimpleOperationsService), "ZeroInputsAndReturnsVoid");
            HttpOperationDescription hod = od.ToHttpOperationDescription();

            Assert.IsNotNull(hod, "Failed to create HttpOperationDescription");
            HttpParameter returnParameter = hod.ReturnValue;

            Assert.IsNotNull(returnParameter, "Return parameter was null");
            Assert.AreEqual(typeof(void), returnParameter.Type, "Return parameter type should have been void");
        }
Esempio n. 2
0
        /// <summary>
        /// Called when the ordered collection of <see cref="HttpOperationHandler"/> instances is being created for
        /// the given <paramref name="operation"/>.  Can be overridden in a derived class to customize the
        /// collection of <see cref="HttpOperationHandler"/> instances returned.
        /// </summary>
        /// <remarks>
        /// The base implemenation returns the standard response <see cref="HttpOperationHandler"/> instances for the given
        /// operation.
        /// </remarks>
        /// <param name="endpoint">The service endpoint.</param>
        /// <param name="operation">
        /// The <see cref="HttpOperationDescription"/> for the given operation that the <see cref="HttpOperationHandler"/>
        /// instances will be associated with.</param>
        /// <returns>
        /// The ordered collection of <see cref="HttpOperationHandler"/> instances to use when handling
        /// <see cref="HttpResponseMessage"/> instances for the given operation.
        /// </returns>
        protected virtual Collection <HttpOperationHandler> OnCreateResponseHandlers(ServiceEndpoint endpoint, HttpOperationDescription operation)
        {
            if (endpoint == null)
            {
                throw Fx.Exception.ArgumentNull("endpoint");
            }

            if (operation == null)
            {
                throw Fx.Exception.ArgumentNull("operation");
            }

            Collection <HttpOperationHandler> responseHandlers = new Collection <HttpOperationHandler>();
            List <HttpParameter> possibleContentParameters     = new List <HttpParameter>();
            HttpParameter        returnValue = operation.ReturnValue;

            if (returnValue != null && IsPossibleResponseContentParameter(returnValue))
            {
                possibleContentParameters.Add(returnValue);
            }

            foreach (HttpParameter parameter in operation.OutputParameters)
            {
                if (parameter != null && IsPossibleResponseContentParameter(parameter))
                {
                    possibleContentParameters.Add(returnValue);
                }
            }

            if (possibleContentParameters.Count > 1)
            {
                ThrowExceptionForMulitpleResponseContentParameters(possibleContentParameters, returnValue, operation.Name);
            }

            HttpParameter responseContentParameter = possibleContentParameters.Count == 1 ?
                                                     possibleContentParameters[0] :
                                                     returnValue;

            if (responseContentParameter != null &&
                responseContentParameter.Type != TypeHelper.VoidType)
            {
                bool isReturnValue = responseContentParameter == returnValue;
                ValidateResponseContentParameter(responseContentParameter, isReturnValue, operation.Name);
                responseContentParameter.IsContentParameter = true;

                SetXmlAndJsonSerializers(operation, responseContentParameter, this.Formatters);
            }

            ResponseContentHandler responseContentHandler = new ResponseContentHandler(responseContentParameter, this.Formatters);

            responseHandlers.Add(responseContentHandler);

            return(responseHandlers);
        }
Esempio n. 3
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);
        }
Esempio n. 4
0
        // Verifies that a HttpOperationDescription built from an OperationDescription
        // matches the given MethodInfo for return type, parameters, and attributes
        private void AssertHttpOperationDescriptionMatchesMethod(HttpOperationDescription hod, MethodInfo method)
        {
            Assert.IsNotNull(hod, "HttpOperationDescription was null");
            Assert.AreEqual(hod.Name, method.Name, "Name mismatch");

            HttpParameter returnParameter = hod.ReturnValue;

            if (!hod.ToOperationDescription().IsOneWay)
            {
                Assert.AreEqual(returnParameter.Type, method.ReturnType, "Return type mismatch");
            }

            IList <HttpParameter> inputParameters = hod.InputParameters;

            ParameterInfo[] parameters = method.GetParameters().Where(p => !p.IsOut).ToArray();
            Assert.AreEqual(parameters.Length, inputParameters.Count, "Input parameter count mismatch");

            for (int i = 0; i < parameters.Length; ++i)
            {
                Assert.AreEqual(parameters[i].Name, inputParameters[i].Name, "Input parameter name mismatch");
                Assert.AreEqual(parameters[i].ParameterType, inputParameters[i].Type, "Input parameter type mismatch");
            }

            IList <HttpParameter> outputParameters = hod.OutputParameters;

            parameters = method.GetParameters().Where(p => p.IsOut).ToArray();
            Assert.AreEqual(parameters.Length, outputParameters.Count, "Output parameter count mismatch");

            for (int i = 0; i < parameters.Length; ++i)
            {
                Assert.AreEqual(parameters[i].Name, outputParameters[i].Name, "Output parameter name mismatch");

                // ServiceModel removes the ByRef part
                Type t = parameters[i].ParameterType;
                if (t.HasElementType && t.IsByRef)
                {
                    t = t.GetElementType();
                }
                Assert.AreEqual(t, outputParameters[i].Type, "Output parameter type mismatch");
            }

            IEnumerable <Attribute> hodAttributes    = hod.Attributes;
            IEnumerable <Attribute> methodAttributes = method.GetCustomAttributes(false).Cast <Attribute>().ToArray();

            foreach (Attribute a in methodAttributes)
            {
                if (!hodAttributes.Contains(a))
                {
                    Assert.Fail("Did not find attribute " + a.GetType().Name + " on method " + method.Name);
                }
            }
        }
Esempio n. 5
0
        public void HttpOperationDescription_Return_Parameter_Matches_Method()
        {
            OperationDescription     od  = GetOperationDescription(typeof(SimpleOperationsService), "OneInputAndReturnValue");
            HttpOperationDescription hod = od.ToHttpOperationDescription();

            Assert.IsNotNull(hod, "Failed to create HttpOperationDescription");
            HttpParameter returnParameter = hod.ReturnValue;

            Assert.IsNotNull(returnParameter, "Return parameter was null");
            Assert.AreEqual(typeof(string), returnParameter.Type, "Return parameter type should have been string");

            Assert.AreEqual("OneInputAndReturnValueResult", returnParameter.Name, "Return parameter name match operation + Result");
        }
Esempio n. 6
0
        public void HttpOperationDescription_Unsynchronized_ReturnValue_Setter()
        {
            HttpOperationDescription hod = new HttpOperationDescription();

            HttpParameter returnValue = new HttpParameter("TheReturn", typeof(string));

            hod.ReturnValue = returnValue;

            Assert.AreSame(returnValue, hod.ReturnValue, "Failed to set return value");

            hod.ReturnValue = null;
            Assert.IsNull(hod.ReturnValue, "Failed to reset return value");
        }
Esempio n. 7
0
        private static bool IsValidContentType(HttpParameter requestContentParameter)
        {
            Fx.Assert(requestContentParameter != null, "The 'requestContentParameter' parameter should not be null.");

            foreach (Type invalidType in invalidContentTypes)
            {
                if (invalidType.IsAssignableFrom(requestContentParameter.Type))
                {
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 8
0
        private static void ValidateRequestContentParameter(HttpParameter requestContentParameter, string operationName)
        {
            Fx.Assert(requestContentParameter != null, "The 'requestContentParameter' parameter should not be null.");
            Fx.Assert(operationName != null, "The 'operationName' parameter should not be null.");

            if (!IsValidContentType(requestContentParameter) ||
                HttpTypeHelper.HttpResponseMessageType.IsAssignableFrom(requestContentParameter.Type))
            {
                throw Fx.Exception.AsError(
                          new InvalidOperationException(
                              SR.InvalidRequestContentParameter(
                                  operationName,
                                  requestContentParameter.Type.Name,
                                  httpOperationHandlerFactoryType.Name)));
            }
        }
Esempio n. 9
0
        public void HttpOperationDescription_Update_ReturnValue_From_Incomplete_HttpOperationDescription()
        {
            OperationDescription     od  = GetOperationDescription(typeof(SimpleOperationsService), "OneInputAndReturnValue");
            MessagePartDescription   mpd = od.Messages[1].Body.ReturnValue;
            HttpOperationDescription hod = od.ToHttpOperationDescription();
            HttpParameter            hpd = hod.ReturnValue;

            // Clear out all of Messages[]
            od.Messages.Clear();

            Assert.IsNull(hod.ReturnValue, "ReturnValue should be null with no backing Messages[1]");

            // Setting a valid ReturnValue should auto-create Messages[1]
            hod.ReturnValue = hpd;

            Assert.IsNotNull(hod.ReturnValue, "ReturnValue was not set");
            Assert.AreSame(hpd.MessagePartDescription, hod.ReturnValue.MessagePartDescription, "ReturnValue not as expected");

            Assert.AreEqual(2, od.Messages.Count, "Setting ReturnValue should have created Messages[1]");
        }
Esempio n. 10
0
        public void HttpOperationDescription_Update_OutputParameters_From_Incomplete_HttpOperationDescription()
        {
            OperationDescription     od      = GetOperationDescription(typeof(SimpleOperationsService), "OneInputOneOutputAndReturnValue");
            MessagePartDescription   mpd     = od.Messages[1].Body.Parts[0]; // output parameter 1 in the MPD
            HttpOperationDescription hod     = od.ToHttpOperationDescription();
            IList <HttpParameter>    hpdColl = hod.OutputParameters;
            HttpParameter            hpd     = hpdColl[0];

            // Zap the Messages[]
            od.Messages.Clear();

            // Zapping the backing Messages should have rendered the input collection empty
            Assert.AreEqual(0, hpdColl.Count, "Resetting Messages did not reset count");
            Assert.AreEqual(0, hod.InputParameters.Count, "Resetting Messages did not reset count in HOD");

            // Mutating the OutputParameter collection should auto-create the both in and out Messages
            hpdColl.Add(hpd);

            Assert.AreEqual(2, od.Messages.Count, "Messages[1] was not autocreated");
            Assert.AreEqual(1, hpdColl.Count, "Creating Messages did not set count");
            Assert.AreEqual(1, hod.OutputParameters.Count, "Creating Messages did not set count in HOD");
        }
Esempio n. 11
0
        /// <summary>
        /// Called when the ordered collection of <see cref="HttpOperationHandler"/> instances is being created for
        /// the given <paramref name="operation"/>.  Can be overridden in a derived class to customize the
        /// collection of <see cref="HttpOperationHandler"/> instances returned.
        /// </summary>
        /// <remarks>
        /// The base implemenation returns the standard request <see cref="HttpOperationHandler"/> instances for the given
        /// operation.
        /// </remarks>
        /// <param name="endpoint">The service endpoint.</param>
        /// <param name="operation">The description of the service operation.</param>
        /// <returns>
        /// The ordered collection of <see cref="HttpOperationHandler"/> instances to use when handling
        /// <see cref="HttpRequestMessage"/> instances for the given operation.
        /// </returns>
        protected virtual Collection <HttpOperationHandler> OnCreateRequestHandlers(ServiceEndpoint endpoint, HttpOperationDescription operation)
        {
            if (endpoint == null)
            {
                throw Fx.Exception.ArgumentNull("endpoint");
            }

            if (operation == null)
            {
                throw Fx.Exception.ArgumentNull("operation");
            }

            Collection <HttpOperationHandler> requestHandlers = new Collection <HttpOperationHandler>();

            HttpMethod  method      = operation.GetHttpMethod();
            UriTemplate uriTemplate = operation.GetUriTemplate();

            string[] uriTemplateParameterNames = uriTemplate.PathSegmentVariableNames.Concat(uriTemplate.QueryValueVariableNames).ToArray();
            if (uriTemplateParameterNames.Length > 0)
            {
                requestHandlers.Add(new UriTemplateHandler(endpoint.Address.Uri, uriTemplate));
            }

            if (method != HttpMethod.Get && method != HttpMethod.Head)
            {
                HttpParameter requestContentParameter = GetRequestContentHandler(operation, uriTemplateParameterNames);
                if (requestContentParameter != null)
                {
                    requestContentParameter.IsContentParameter = true;
                    requestHandlers.Add(new RequestContentHandler(requestContentParameter, this.Formatters));

                    SetXmlAndJsonSerializers(operation, requestContentParameter, this.Formatters);
                }
            }

            return(requestHandlers);
        }
Esempio n. 12
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);
            }
        }
Esempio n. 13
0
        private static void ThrowExceptionForMulitpleResponseContentParameters(List <HttpParameter> possibleContentParameters, HttpParameter returnValue, string operationName)
        {
            Fx.Assert(possibleContentParameters != null, "The 'possibleContentParameters' parameter should not be null.");
            Fx.Assert(returnValue != null, "The 'returnValue' parameter should not be null.");
            Fx.Assert(operationName != null, "The 'operationName' parameter should not be null.");

            string errorMessage = SR.MultipleResponseContentParameters(
                httpOperationHandlerFactoryType.Name,
                operationName,
                possibleContentParameters.Count);
            StringBuilder stringBuilder = new StringBuilder(errorMessage);

            foreach (HttpParameter parameter in possibleContentParameters)
            {
                string parameterMessage = null;
                if (parameter.IsContentParameter)
                {
                    if (parameter == returnValue)
                    {
                        parameterMessage = SR.ReturnValueWithIsContentParameterSet(
                            HttpParameter.IsContentParameterPropertyName,
                            bool.TrueString);
                    }
                    else
                    {
                        parameterMessage = SR.ResponseParameterWithIsContentParameterSet(
                            parameter.Name,
                            HttpParameter.IsContentParameterPropertyName,
                            bool.TrueString);
                    }
                }
                else
                {
                    if (parameter == returnValue)
                    {
                        parameterMessage = SR.ReturnValueWithContentType(
                            parameter.Type.Name);
                    }
                    else
                    {
                        parameterMessage = SR.ResponseParameterWithContentType(
                            parameter.Name,
                            parameter.Type.Name);
                    }
                }

                stringBuilder.Append(Environment.NewLine);
                stringBuilder.Append(parameterMessage);
            }

            throw Fx.Exception.AsError(new InvalidOperationException(stringBuilder.ToString()));
        }
Esempio n. 14
0
        public static OperationDescription GetEquivalentOperationDescription(OperationDescription operation)
        {
            Fx.Assert(operation != null, "OperationDescription cannnot be null");

            OperationDescription     copy                    = CreateEmptyOperationDescription(operation);
            HttpOperationDescription httpDescription         = copy.ToHttpOperationDescription();
            HttpOperationDescription originalHttpDescription = operation.ToHttpOperationDescription();
            UriTemplate   template          = originalHttpDescription.GetUriTemplate();
            List <string> templateVariables = new List <string>(template.PathSegmentVariableNames.Concat(template.QueryValueVariableNames));

            IEnumerable <HttpParameter> originalRequestBodyParameters  = originalHttpDescription.InputParameters.Where(param => param.IsContentParameter);
            IEnumerable <HttpParameter> originalResponseBodyParameters = originalHttpDescription.OutputParameters.Where(param => param.IsContentParameter);
            IEnumerable <HttpParameter> originalUriTemplateParameters  = originalHttpDescription.InputParameters.Where(
                (param) =>
            {
                foreach (string templateVariable in templateVariables)
                {
                    if (string.Equals(templateVariable, param.Name, StringComparison.OrdinalIgnoreCase))
                    {
                        return(true);
                    }
                }

                return(false);
            });

            httpDescription.ReturnValue = originalHttpDescription.ReturnValue;

            // add UriTemplate parameters
            foreach (HttpParameter parameter in originalUriTemplateParameters)
            {
                httpDescription.InputParameters.Add(parameter);
            }

            // add body parameters
            foreach (HttpParameter parameter in originalRequestBodyParameters)
            {
                httpDescription.InputParameters.Add(parameter);
            }

            int index = httpDescription.InputParameters.Count;
            int requestBodyParametersCount  = originalRequestBodyParameters.Count <HttpParameter>();
            int responseBodyParametersCount = originalResponseBodyParameters.Count <HttpParameter>();

            if (requestBodyParametersCount == 0 || responseBodyParametersCount == 0)
            {
                // Special case if any input parameter is HttpRequestMessage or HttpResponseMessage
                foreach (HttpParameter inputParameter in originalHttpDescription.InputParameters)
                {
                    if (requestBodyParametersCount == 0 && originalHttpDescription.GetHttpMethod() != HttpMethod.Get && httpRequestMessageType.IsAssignableFrom(inputParameter.Type))
                    {
                        // add the HttpRequestmessage as a body parameter of type Message
                        HttpParameter parameter = new HttpParameter(new MessagePartDescription(inputParameter.Name, string.Empty)
                        {
                            Type = typeof(Message), Index = index++
                        });
                        httpDescription.InputParameters.Add(parameter);
                    }

                    if (!operation.IsOneWay && responseBodyParametersCount == 0 && httpResponseMessageType.IsAssignableFrom(inputParameter.Type))
                    {
                        // add the HttpResponsemessage as a return value of type Message
                        httpDescription.ReturnValue = new HttpParameter(new MessagePartDescription(inputParameter.Name, string.Empty)
                        {
                            Type = typeof(Message)
                        });
                    }
                }
            }

            foreach (HttpParameter parameter in originalResponseBodyParameters)
            {
                // cannot do a byRef comparison here
                if (parameter.Type != originalHttpDescription.ReturnValue.Type || !string.Equals(parameter.Name, originalHttpDescription.ReturnValue.Name, StringComparison.OrdinalIgnoreCase))
                {
                    httpDescription.OutputParameters.Add(parameter);
                }
            }

            if (responseBodyParametersCount == 0)
            {
                foreach (HttpParameter outputParameter in originalHttpDescription.OutputParameters)
                {
                    // special case HttpResponseMessage when it is set as an out parameter
                    if (httpResponseMessageType.IsAssignableFrom(outputParameter.Type))
                    {
                        httpDescription.ReturnValue = new HttpParameter(new MessagePartDescription(outputParameter.Name, string.Empty)
                        {
                            Type = typeof(Message)
                        });
                    }
                }
            }

            if (templateVariables.Count > originalUriTemplateParameters.Count <HttpParameter>())
            {
                // this means that we have some UriTemplate variables that are not explicitly bound to an input parameter
                foreach (HttpParameter parameter in originalUriTemplateParameters)
                {
                    templateVariables.Remove(parameter.Name);
                }

                foreach (string variable in templateVariables)
                {
                    HttpParameter parameter = new HttpParameter(new MessagePartDescription(variable, operation.DeclaringContract.Namespace)
                    {
                        Type = typeof(string), Index = index++
                    });
                    httpDescription.InputParameters.Add(parameter);
                }
            }

            return(httpDescription.ToOperationDescription());
        }