Example #1
0
 public OperationParameterInfo(OperationParameterKind kind, Type type, string name, bool canConvert)
 {
     this.Kind       = kind;
     this.Type       = type;
     this.Name       = name;
     this.CanConvert = canConvert;
 }
Example #2
0
        protected RequestBodyDispatchFormatter(OperationDescription operation, UriTemplate uriTemplate, QueryStringConverter converter, IDispatchMessageFormatter innerFormatter)
        {
            // The inner formatter is the default formatter that WCF normally uses.  When the request can't be deserialized
            //  by our custom formatter, we'll use the default formatter.
            this.innerFormatter = innerFormatter;

            // We'll use the query string converter for both Uri query string parameters and the values of the
            //  form post data
            this.QueryStringConverter = converter;

            // Messages[0] is the request message
            MessagePartDescriptionCollection parts = operation.Messages[0].Body.Parts;

            // This partsCount includes the Uri parts (both path segment variables and query string variables)
            //  1 body content part
            partsCount = parts.Count;

            ReadOnlyCollection <string> uriPathVariables  = uriTemplate.PathSegmentVariableNames;
            ReadOnlyCollection <string> uriQueryVariables = uriTemplate.QueryValueVariableNames;

            // For each part of the message, we need to capture it's name, type, and whether it is
            //  a Uri path segment variable, a Uri query string variable or the body content
            operationParameterInfo = new OperationParameterInfo[partsCount];
            for (int x = 0; x < partsCount; x++)
            {
                string name = parts[x].Name;
                Type   type = parts[x].Type;

                // We'll assume this part is the message body, but then check if there are
                //  uri variables that match the name
                OperationParameterKind kind = OperationParameterKind.MessageBody;
                bool canConvert             = false;
                CaseInsensitiveEqualityComparer <string> comparer = new CaseInsensitiveEqualityComparer <string>();

                if (uriPathVariables.Contains(name, comparer))
                {
                    kind = OperationParameterKind.UriPathVariable;
                }
                else if (uriQueryVariables.Contains(name, comparer))
                {
                    canConvert = converter.CanConvert(type);
                    kind       = OperationParameterKind.UriQueryVariable;
                }
                else
                {
                    // If we reached here, then this part really is the message body part.
                    //  We'll store the name and type in the class properties so that derived
                    //  types have access to this information
                    this.BodyParameterName = name;
                    this.BodyParameterType = type;
                }

                operationParameterInfo[x] = new OperationParameterInfo(kind, type, name, canConvert);
            }
        }
Example #3
0
        public void DeserializeRequest(Message message, object[] parameters)
        {
            // Classes that derive from this class will implement CanDeserializeRequestBody() to
            //  tell us if we should deserialize this request or allow the default inner formatter to deserailize it.
            if (CanDeserializeRequestBody(message))
            {
                // The UriTemplateMatch instance for the request will tell us the values of the Uri variable parts
                UriTemplateMatch match = message.Properties["UriTemplateMatchResults"] as UriTemplateMatch;

                for (int x = 0; x < this.partsCount; x++)
                {
                    // For each part of the message we check if the part is the message body or a Uri variable
                    OperationParameterKind kind = operationParameterInfo[x].Kind;
                    if (kind == OperationParameterKind.MessageBody)
                    {
                        // Since this part is the message body we'll let the derived class deserailize it.
                        //  We'll provide the message body as a stream to make it easier to work with
                        Stream stream = message.GetBodyAsStream();
                        parameters[x] = DeserializeRequestBody(stream);
                    }
                    else
                    {
                        // Since this part is a Uri variable, we'll get the value for it from the UriTemplateMAtch instance
                        string value = match.BoundVariables[operationParameterInfo[x].Name];

                        if (kind == OperationParameterKind.UriQueryVariable &&
                            operationParameterInfo[x].CanConvert &&
                            value != null)
                        {
                            // Query string Uri variables should be converted to the type of the parameter from the method signature
                            parameters[x] = QueryStringConverter.ConvertStringToValue(value, operationParameterInfo[x].Type);;
                        }
                        else
                        {
                            // Path segment Uri variables are always provided as strings
                            parameters[x] = value;
                        }
                    }
                }
            }
            else
            {
                this.innerFormatter.DeserializeRequest(message, parameters);
            }
        }