public void type_match_user_function_not_invoked_if_type_doesnt_match()
        {
            ParameterBindingRulesCollection pb          = new ParameterBindingRulesCollection();
            HttpParameterBinding            mockBinding = new EmptyParameterBinding();

            pb.Add(
                typeof(string),
                param =>
            {
                throw new InvalidOperationException("shouldn't be called");
            }
                );
            pb.Insert(
                0,
                typeof(string),
                param =>
            {
                throw new InvalidOperationException("shouldn't be called");
            }
                );

            // Act
            HttpParameterBinding b2 = pb.LookupBinding(
                CreateParameterDescriptor(typeof(int), "first")
                );
            // Assert - made it through the action without throwing.
        }
        // Create an instance and add some default binders
        internal static ParameterBindingRulesCollection GetDefaultParameterBinders()
        {
            ParameterBindingRulesCollection pb = new ParameterBindingRulesCollection();

            pb.Add(
                typeof(CancellationToken),
                parameter => new CancellationTokenParameterBinding(parameter)
                );
            pb.Add(
                typeof(HttpRequestMessage),
                parameter => new HttpRequestParameterBinding(parameter)
                );

            // Warning binder for HttpContent.
            pb.Add(
                parameter =>
                typeof(HttpContent).IsAssignableFrom(parameter.ParameterType)
                      ? parameter.BindAsError(
                    Error.Format(
                        SRResources.ParameterBindingIllegalType,
                        parameter.ParameterType.Name,
                        parameter.ParameterName
                        )
                    )
                      : null
                );

            return(pb);
        }
        public void Lookup_is_ordered()
        {
            ParameterBindingRulesCollection pb           = new ParameterBindingRulesCollection();
            HttpParameterBinding            mockBinding1 = new EmptyParameterBinding();
            HttpParameterBinding            mockBinding2 = new EmptyParameterBinding();
            HttpParameterBinding            mockBinding3 = new EmptyParameterBinding();

            pb.Add(param => param.ParameterName == "first" ? mockBinding1 : null);
            pb.Add(param => param.ParameterName == "first" ? mockBinding2 : null);
            pb.Add(param => param.ParameterType == typeof(int) ? mockBinding3 : null);

            // Act
            HttpParameterBinding b1 = pb.LookupBinding(CreateParameterDescriptor(null, "first"));
            HttpParameterBinding b2 = pb.LookupBinding(
                CreateParameterDescriptor(typeof(string), "none")
                );
            HttpParameterBinding b3 = pb.LookupBinding(
                CreateParameterDescriptor(typeof(int), "first")
                );
            HttpParameterBinding b4 = pb.LookupBinding(
                CreateParameterDescriptor(typeof(int), "last")
                );

            // Assert
            Assert.Equal(mockBinding1, b1);
            Assert.Null(b2);
            Assert.Equal(mockBinding1, b3);
            Assert.Equal(mockBinding3, b4);
        }
        public void AsCollection()
        {
            ParameterBindingRulesCollection pb = new ParameterBindingRulesCollection();

            // Knowing that it's a collection means we have known behavior around
            // the collection methods (like insert, add, clear, etc).
            Assert.True(pb is Collection <Func <HttpParameterDescriptor, HttpParameterBinding> >);
        }
        public void Lookup_empty_collection_returns_null()
        {
            // The collection is empty,  so lookup will fail.
            ParameterBindingRulesCollection pb        = new ParameterBindingRulesCollection();
            HttpParameterDescriptor         parameter = CreateParameterDescriptor(typeof(object), "none");

            // Act
            HttpParameterBinding binding = pb.LookupBinding(parameter);

            // Assert.
            Assert.Null(binding);
        }
        public void Add_with_type_match()
        {
            ParameterBindingRulesCollection pb          = new ParameterBindingRulesCollection();
            HttpParameterBinding            mockBinding = new EmptyParameterBinding();

            pb.Add(typeof(string), param => mockBinding);

            // Act
            HttpParameterBinding b1 = pb.LookupBinding(CreateParameterDescriptor(typeof(string), "first"));
            HttpParameterBinding b2 = pb.LookupBinding(CreateParameterDescriptor(typeof(int), "first"));

            // Assert
            Assert.Equal(mockBinding, b1);
            Assert.Null(b2); // doesn't match type, misses.
        }
        public void Insert_with_type_match()
        {
            ParameterBindingRulesCollection pb           = new ParameterBindingRulesCollection();
            HttpParameterBinding            mockBinding1 = new EmptyParameterBinding();
            HttpParameterBinding            mockBinding2 = new EmptyParameterBinding();
            HttpParameterBinding            mockBinding3 = new EmptyParameterBinding();

            // Act, test insertion
            pb.Add(typeof(string), param => mockBinding2);
            pb.Add(typeof(int), param => mockBinding2);
            pb.Insert(0, typeof(string), param => mockBinding1);
            pb.Insert(2, typeof(int), param => mockBinding3); // goes in middle

            // Assert via lookups
            Assert.Equal(mockBinding1, pb.LookupBinding(CreateParameterDescriptor(typeof(string), "first")));
            Assert.Equal(mockBinding3, pb.LookupBinding(CreateParameterDescriptor(typeof(int), "first")));
        }
        // Determine how a single parameter will get bound.
        // This is all sync. We don't need to actually read the body just to determine that we'll bind to the body.
        protected virtual HttpParameterBinding GetParameterBinding(
            HttpParameterDescriptor parameter
            )
        {
            // Attribute has the highest precedence
            // Presence of a model binder attribute overrides.
            ParameterBindingAttribute attr = parameter.ParameterBinderAttribute;

            if (attr != null)
            {
                return(attr.GetBinding(parameter));
            }

            // No attribute, so lookup in global map.
            ParameterBindingRulesCollection pb = parameter.Configuration.ParameterBindingRules;

            if (pb != null)
            {
                HttpParameterBinding binding = pb.LookupBinding(parameter);
                if (binding != null)
                {
                    return(binding);
                }
            }

            // Not explicitly specified in global map or attribute.
            // Use a default policy to determine it. These are catch-all policies.
            Type type = parameter.ParameterType;

            if (TypeHelper.CanConvertFromString(type))
            {
                // For simple types, the default is to look in URI. Exactly as if the parameter had a [FromUri] attribute.
                return(parameter.BindWithAttribute(new FromUriAttribute()));
            }

            // Fallback. Must be a complex type. Default is to look in body. Exactly as if this type had a [FromBody] attribute.
            attr = new FromBodyAttribute();
            return(attr.GetBinding(parameter));
        }