Rename DictionaryBasedValueProvider to RouteValueProvider

Fixes #3629
This commit is contained in:
Pranav K 2015-12-29 13:18:45 -08:00
parent 2b9dd76535
commit aab051a20f
9 changed files with 144 additions and 121 deletions

View File

@ -5,6 +5,9 @@ using System.Threading.Tasks;
namespace Microsoft.AspNet.Mvc.ModelBinding
{
/// <summary>
/// A factory for creating <see cref="IValueProvider"/> instances.
/// </summary>
public interface IValueProviderFactory
{
/// <summary>

View File

@ -51,7 +51,7 @@ namespace Microsoft.AspNet.Mvc.Internal
options.OutputFormatters.Add(new StreamOutputFormatter());
// Set up ValueProviders
options.ValueProviderFactories.Add(new RouteValueValueProviderFactory());
options.ValueProviderFactories.Add(new RouteValueProviderFactory());
options.ValueProviderFactories.Add(new QueryStringValueProviderFactory());
options.ValueProviderFactories.Add(new FormValueProviderFactory());
options.ValueProviderFactories.Add(new JQueryFormValueProviderFactory());

View File

@ -9,7 +9,7 @@ using Microsoft.Extensions.Primitives;
namespace Microsoft.AspNet.Mvc.ModelBinding
{
/// <summary>
/// An <see cref="IValueProvider"/> for form data stored in an <see cref="IDictionary{string, string[]}"/>.
/// An <see cref="IValueProvider"/> for jQuery formatted form data.
/// </summary>
public class JQueryFormValueProvider : BindingSourceValueProvider, IEnumerableValueProvider
{
@ -17,10 +17,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
private PrefixContainer _prefixContainer;
/// <summary>
/// Initializes a new instance of the <see cref="DictionaryBasedValueProvider"/> class.
/// Initializes a new instance of the <see cref="JQueryFormValueProvider"/> class.
/// </summary>
/// <param name="bindingSource">The <see cref="BindingSource"/> of the data.</param>
/// <param name="valuesFactory">A delegate which provides the values to wrap.</param>
/// <param name="values">The values.</param>
/// <param name="culture">The culture to return with ValueProviderResult instances.</param>
public JQueryFormValueProvider(
BindingSource bindingSource,

View File

@ -13,8 +13,12 @@ using Microsoft.Extensions.Primitives;
namespace Microsoft.AspNet.Mvc.ModelBinding
{
/// <summary>
/// A <see cref="IValueProviderFactory"/> for <see cref="JQueryFormValueProvider"/>.
/// </summary>
public class JQueryFormValueProviderFactory : IValueProviderFactory
{
/// <inheritdoc />
public Task<IValueProvider> GetValueProviderAsync(ActionContext context)
{
if (context == null)
@ -34,9 +38,9 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
private static async Task<IValueProvider> CreateValueProviderAsync(HttpRequest request)
{
return new JQueryFormValueProvider(
BindingSource.Form,
await GetValueCollectionAsync(request),
CultureInfo.CurrentCulture);
BindingSource.Form,
await GetValueCollectionAsync(request),
CultureInfo.CurrentCulture);
}
private static async Task<IDictionary<string, StringValues>> GetValueCollectionAsync(HttpRequest request)

View File

@ -2,28 +2,27 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Globalization;
using Microsoft.AspNet.Routing;
namespace Microsoft.AspNet.Mvc.ModelBinding
{
/// <summary>
/// An <see cref="IValueProvider"/> adapter for data stored in an
/// <see cref="IDictionary{string, object}"/>.
/// An <see cref="IValueProvider"/> adapter for data stored in an <see cref="RouteValueDictionary"/>.
/// </summary>
public class DictionaryBasedValueProvider : BindingSourceValueProvider
public class RouteValueProvider : BindingSourceValueProvider
{
private readonly IDictionary<string, object> _values;
private readonly RouteValueDictionary _values;
private PrefixContainer _prefixContainer;
/// <summary>
/// Creates a new <see cref="DictionaryBasedValueProvider"/>.
/// Creates a new <see cref="RouteValueProvider"/>.
/// </summary>
/// <param name="bindingSource">The <see cref="BindingSource"/> of the data.</param>
/// <param name="values">The values.</param>
public DictionaryBasedValueProvider(
public RouteValueProvider(
BindingSource bindingSource,
IDictionary<string, object> values)
RouteValueDictionary values)
: base(bindingSource)
{
if (bindingSource == null)

View File

@ -6,8 +6,12 @@ using System.Threading.Tasks;
namespace Microsoft.AspNet.Mvc.ModelBinding
{
public class RouteValueValueProviderFactory : IValueProviderFactory
/// <summary>
/// A <see cref="IValueProviderFactory"/> for creating <see cref="RouteValueProvider"/> instances.
/// </summary>
public class RouteValueProviderFactory : IValueProviderFactory
{
/// <inheritdoc />
public Task<IValueProvider> GetValueProviderAsync(ActionContext context)
{
if (context == null)
@ -15,7 +19,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
throw new ArgumentNullException(nameof(context));
}
return Task.FromResult<IValueProvider>(new DictionaryBasedValueProvider(
return Task.FromResult<IValueProvider>(new RouteValueProvider(
BindingSource.Path,
context.RouteData.Values));
}

View File

@ -3,22 +3,22 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNet.Routing;
using Xunit;
namespace Microsoft.AspNet.Mvc.ModelBinding
{
public class DictionaryBasedValueProviderTests
public class RouteValueProviderTests
{
[Fact]
public void GetValueProvider_ReturnsNull_WhenKeyIsNotFound()
{
// Arrange
var values = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase)
var values = new RouteValueDictionary(new Dictionary<string, object>
{
{ "test-key", "value" }
};
var provider = new DictionaryBasedValueProvider(BindingSource.Query, values);
});
var provider = new RouteValueProvider(BindingSource.Query, values);
// Act
var result = provider.GetValue("not-test-key");
@ -31,11 +31,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
public void GetValueProvider_ReturnsValue_IfKeyIsPresent()
{
// Arrange
var values = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase)
var values = new RouteValueDictionary(new Dictionary<string, object>
{
{ "test-key", "test-value" }
};
var provider = new DictionaryBasedValueProvider(BindingSource.Query, values);
});
var provider = new RouteValueProvider(BindingSource.Query, values);
// Act
var result = provider.GetValue("test-key");
@ -48,11 +48,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
public void ContainsPrefix_ReturnsNullValue_IfKeyIsPresent()
{
// Arrange
var values = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase)
var values = new RouteValueDictionary(new Dictionary<string, object>
{
{ "test-key", null }
};
var provider = new DictionaryBasedValueProvider(BindingSource.Query, values);
});
var provider = new RouteValueProvider(BindingSource.Query, values);
// Act
var result = provider.GetValue("test-key");
@ -68,13 +68,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
public void ContainsPrefix_ReturnsTrue_ForKnownPrefixes(string prefix)
{
// Arrange
var values = new Dictionary<string, object>
var values = new RouteValueDictionary(new Dictionary<string, object>
{
{ "foo", 1 },
{ "bar.baz", 1 },
};
});
var valueProvider = new DictionaryBasedValueProvider(BindingSource.Query, values);
var valueProvider = new RouteValueProvider(BindingSource.Query, values);
// Act
var result = valueProvider.ContainsPrefix(prefix);
@ -89,13 +89,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
public void GetValue_ReturnsCorrectValue_ForKnownKeys(string prefix, string expectedValue)
{
// Arrange
var values = new Dictionary<string, object>
var values = new RouteValueDictionary(new Dictionary<string, object>
{
{ "bar", 1 },
{ "bar.baz", 2 },
};
});
var valueProvider = new DictionaryBasedValueProvider(BindingSource.Query, values);
var valueProvider = new RouteValueProvider(BindingSource.Query, values);
// Act
var result = valueProvider.GetValue(prefix);
@ -108,12 +108,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
public void GetValue_DoesNotReturnAValue_ForAKeyPrefix()
{
// Arrange
var values = new Dictionary<string, object>
var values = new RouteValueDictionary(new Dictionary<string, object>
{
{ "bar.baz", 2 },
};
});
var valueProvider = new DictionaryBasedValueProvider(BindingSource.Query, values);
var valueProvider = new RouteValueProvider(BindingSource.Query, values);
// Act
var result = valueProvider.GetValue("bar");
@ -126,11 +126,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
public void ContainsPrefix_ReturnsFalse_IfKeyIsNotPresent()
{
// Arrange
var values = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase)
var values = new RouteValueDictionary(new Dictionary<string, object>
{
{ "test-key", "test-value" }
};
var provider = new DictionaryBasedValueProvider(BindingSource.Query, values);
});
var provider = new RouteValueProvider(BindingSource.Query, values);
// Act
var result = provider.ContainsPrefix("not-test-key");
@ -143,11 +143,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
public void ContainsPrefix_ReturnsTrue_IfKeyIsPresent()
{
// Arrange
var values = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase)
var values = new RouteValueDictionary(new Dictionary<string, object>
{
{ "test-key", "test-value" }
};
var provider = new DictionaryBasedValueProvider(BindingSource.Query, values);
});
var provider = new RouteValueProvider(BindingSource.Query, values);
// Act
var result = provider.ContainsPrefix("test-key");
@ -160,8 +160,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
public void FilterInclude()
{
// Arrange
var values = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
var provider = new DictionaryBasedValueProvider(BindingSource.Query, values);
var values = new RouteValueDictionary();
var provider = new RouteValueProvider(BindingSource.Query, values);
var bindingSource = new BindingSource(
BindingSource.Query.Id,
@ -181,8 +181,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
public void FilterExclude()
{
// Arrange
var values = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
var provider = new DictionaryBasedValueProvider(BindingSource.Query, values);
var values = new RouteValueDictionary();
var provider = new RouteValueProvider(BindingSource.Query, values);
var bindingSource = new BindingSource(
"Test",

View File

@ -2,10 +2,11 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using Microsoft.AspNet.Routing;
namespace Microsoft.AspNet.Mvc.ModelBinding
{
public class TestValueProvider : DictionaryBasedValueProvider
public class TestValueProvider : RouteValueProvider
{
public static readonly BindingSource TestBindingSource = new BindingSource(
id: "Test",
@ -14,12 +15,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
isFromRequest: true);
public TestValueProvider(IDictionary<string, object> values)
: base(TestBindingSource, values)
: base(TestBindingSource, new RouteValueDictionary(values))
{
}
public TestValueProvider(BindingSource bindingSource, IDictionary<string, object> values)
: base(bindingSource, values)
: base(bindingSource, new RouteValueDictionary(values))
{
}
}

View File

@ -4,24 +4,25 @@
using System;
using System.IO;
using System.Linq;
using System.Threading;
using System.Xml;
using System.Xml.Linq;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Mvc.Formatters;
using Microsoft.AspNet.Mvc.Internal;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.AspNet.Mvc.ModelBinding.Metadata;
using Microsoft.AspNet.Mvc.ModelBinding.Validation;
using Microsoft.AspNet.Mvc.Razor;
using Microsoft.Extensions.CompilationAbstractions;
using Microsoft.Extensions.PlatformAbstractions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.PlatformAbstractions;
using Moq;
using Newtonsoft.Json.Linq;
using Xunit;
using Microsoft.Extensions.Logging;
using System.Threading;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Mvc.ModelBinding.Metadata;
namespace Microsoft.AspNet.Mvc
{
@ -45,19 +46,18 @@ namespace Microsoft.AspNet.Mvc
var options = GetOptions<MvcOptions>();
// Assert
var i = 0;
Assert.Equal(11, options.ModelBinders.Count);
Assert.IsType(typeof(BinderTypeBasedModelBinder), options.ModelBinders[i++]);
Assert.IsType(typeof(ServicesModelBinder), options.ModelBinders[i++]);
Assert.IsType(typeof(BodyModelBinder), options.ModelBinders[i++]);
Assert.IsType(typeof(HeaderModelBinder), options.ModelBinders[i++]);
Assert.IsType(typeof(SimpleTypeModelBinder), options.ModelBinders[i++]);
Assert.IsType(typeof(CancellationTokenModelBinder), options.ModelBinders[i++]);
Assert.IsType(typeof(ByteArrayModelBinder), options.ModelBinders[i++]);
Assert.IsType(typeof(FormFileModelBinder), options.ModelBinders[i++]);
Assert.IsType(typeof(FormCollectionModelBinder), options.ModelBinders[i++]);
Assert.IsType(typeof(GenericModelBinder), options.ModelBinders[i++]);
Assert.IsType(typeof(MutableObjectModelBinder), options.ModelBinders[i++]);
Assert.Collection(options.ModelBinders,
binder => Assert.IsType<BinderTypeBasedModelBinder>(binder),
binder => Assert.IsType<ServicesModelBinder>(binder),
binder => Assert.IsType<BodyModelBinder>(binder),
binder => Assert.IsType<HeaderModelBinder>(binder),
binder => Assert.IsType<SimpleTypeModelBinder>(binder),
binder => Assert.IsType<CancellationTokenModelBinder>(binder),
binder => Assert.IsType<ByteArrayModelBinder>(binder),
binder => Assert.IsType<FormFileModelBinder>(binder),
binder => Assert.IsType<FormCollectionModelBinder>(binder),
binder => Assert.IsType<GenericModelBinder>(binder),
binder => Assert.IsType<MutableObjectModelBinder>(binder));
}
[Fact]
@ -68,11 +68,11 @@ namespace Microsoft.AspNet.Mvc
// Assert
var valueProviders = options.ValueProviderFactories;
Assert.Equal(4, valueProviders.Count);
Assert.IsType<RouteValueValueProviderFactory>(valueProviders[0]);
Assert.IsType<QueryStringValueProviderFactory>(valueProviders[1]);
Assert.IsType<FormValueProviderFactory>(valueProviders[2]);
Assert.IsType<JQueryFormValueProviderFactory>(valueProviders[3]);
Assert.Collection(valueProviders,
provider => Assert.IsType<RouteValueProviderFactory>(provider),
provider => Assert.IsType<QueryStringValueProviderFactory>(provider),
provider => Assert.IsType<FormValueProviderFactory>(provider),
provider => Assert.IsType<JQueryFormValueProviderFactory>(provider));
}
[Fact]
@ -82,11 +82,11 @@ namespace Microsoft.AspNet.Mvc
var options = GetOptions<MvcOptions>();
// Assert
Assert.Equal(4, options.OutputFormatters.Count);
Assert.IsType<HttpNoContentOutputFormatter>(options.OutputFormatters[0]);
Assert.IsType<StringOutputFormatter>(options.OutputFormatters[1]);
Assert.IsType<StreamOutputFormatter>(options.OutputFormatters[2]);
Assert.IsType<JsonOutputFormatter>(options.OutputFormatters[3]);
Assert.Collection(options.OutputFormatters,
formatter => Assert.IsType<HttpNoContentOutputFormatter>(formatter),
formatter => Assert.IsType<StringOutputFormatter>(formatter),
formatter => Assert.IsType<StreamOutputFormatter>(formatter),
formatter => Assert.IsType<JsonOutputFormatter>(formatter));
}
[Fact]
@ -96,9 +96,9 @@ namespace Microsoft.AspNet.Mvc
var options = GetOptions<MvcOptions>();
// Assert
Assert.Equal(2, options.InputFormatters.Count);
Assert.IsType<JsonInputFormatter>(options.InputFormatters[0]);
Assert.IsType<JsonPatchInputFormatter>(options.InputFormatters[1]);
Assert.Collection(options.InputFormatters,
formatter => Assert.IsType<JsonInputFormatter>(formatter),
formatter => Assert.IsType<JsonPatchInputFormatter>(formatter));
}
[Fact]
@ -108,9 +108,9 @@ namespace Microsoft.AspNet.Mvc
var options = GetOptions<MvcOptions>();
// Assert
Assert.Equal(2, options.ModelValidatorProviders.Count);
Assert.IsType<DefaultModelValidatorProvider>(options.ModelValidatorProviders[0]);
Assert.IsType<DataAnnotationsModelValidatorProvider>(options.ModelValidatorProviders[1]);
Assert.Collection(options.ModelValidatorProviders,
validator => Assert.IsType<DefaultModelValidatorProvider>(validator),
validator => Assert.IsType<DataAnnotationsModelValidatorProvider>(validator));
}
[Fact]
@ -120,10 +120,10 @@ namespace Microsoft.AspNet.Mvc
var options = GetOptions<MvcViewOptions>(AddDnxServices);
// Assert
Assert.Equal(3, options.ClientModelValidatorProviders.Count);
Assert.IsType<DefaultClientModelValidatorProvider>(options.ClientModelValidatorProviders[0]);
Assert.IsType<DataAnnotationsClientModelValidatorProvider>(options.ClientModelValidatorProviders[1]);
Assert.IsType<NumericClientModelValidatorProvider>(options.ClientModelValidatorProviders[2]);
Assert.Collection(options.ClientModelValidatorProviders,
validator => Assert.IsType<DefaultClientModelValidatorProvider>(validator),
validator => Assert.IsType<DataAnnotationsClientModelValidatorProvider>(validator),
validator => Assert.IsType<NumericClientModelValidatorProvider>(validator));
}
[Fact]
@ -148,39 +148,51 @@ namespace Microsoft.AspNet.Mvc
// Assert
var providers = options.ModelMetadataDetailsProviders;
Assert.Equal(12, providers.Count);
var i = 0;
Assert.IsType<DefaultBindingMetadataProvider>(providers[i++]);
Assert.IsType<DefaultValidationMetadataProvider>(providers[i++]);
var excludeFilter = Assert.IsType<ValidationExcludeFilter>(providers[i++]);
Assert.Equal(typeof(Type), excludeFilter.Type);
excludeFilter = Assert.IsType<ValidationExcludeFilter>(providers[i++]);
Assert.Equal(typeof(Uri), excludeFilter.Type);
excludeFilter = Assert.IsType<ValidationExcludeFilter>(providers[i++]);
Assert.Equal(typeof(CancellationToken), excludeFilter.Type);
excludeFilter = Assert.IsType<ValidationExcludeFilter>(providers[i++]);
Assert.Equal(typeof(IFormFile), excludeFilter.Type);
excludeFilter = Assert.IsType<ValidationExcludeFilter>(providers[i++]);
Assert.Equal(typeof(IFormCollection), excludeFilter.Type);
Assert.IsType<DataAnnotationsMetadataProvider>(providers[i++]);
excludeFilter = Assert.IsType<ValidationExcludeFilter>(providers[i++]);
Assert.Equal(typeof(JToken), excludeFilter.Type);
Assert.IsType<DataMemberRequiredBindingMetadataProvider>(providers[i++]);
excludeFilter = Assert.IsType<ValidationExcludeFilter>(providers[i++]);
Assert.Equal(typeof(XObject).FullName, excludeFilter.FullTypeName);
excludeFilter = Assert.IsType<ValidationExcludeFilter>(providers[i++]);
Assert.Equal("System.Xml.XmlNode", excludeFilter.FullTypeName);
Assert.Collection(providers,
provider => Assert.IsType<DefaultBindingMetadataProvider>(provider),
provider => Assert.IsType<DefaultValidationMetadataProvider>(provider),
provider =>
{
var excludeFilter = Assert.IsType<ValidationExcludeFilter>(provider);
Assert.Equal(typeof(Type), excludeFilter.Type);
},
provider =>
{
var excludeFilter = Assert.IsType<ValidationExcludeFilter>(provider);
Assert.Equal(typeof(Uri), excludeFilter.Type);
},
provider =>
{
var excludeFilter = Assert.IsType<ValidationExcludeFilter>(provider);
Assert.Equal(typeof(CancellationToken), excludeFilter.Type);
},
provider =>
{
var excludeFilter = Assert.IsType<ValidationExcludeFilter>(provider);
Assert.Equal(typeof(IFormFile), excludeFilter.Type);
},
provider =>
{
var excludeFilter = Assert.IsType<ValidationExcludeFilter>(provider);
Assert.Equal(typeof(IFormCollection), excludeFilter.Type);
},
provider => Assert.IsType<DataAnnotationsMetadataProvider>(provider),
provider =>
{
var excludeFilter = Assert.IsType<ValidationExcludeFilter>(provider);
Assert.Equal(typeof(JToken), excludeFilter.Type);
},
provider => Assert.IsType<DataMemberRequiredBindingMetadataProvider>(provider),
provider =>
{
var excludeFilter = Assert.IsType<ValidationExcludeFilter>(provider);
Assert.Equal(typeof(XObject).FullName, excludeFilter.FullTypeName);
},
provider =>
{
var excludeFilter = Assert.IsType<ValidationExcludeFilter>(provider);
Assert.Equal(typeof(XmlNode).FullName, excludeFilter.FullTypeName);
});
}
[Fact]