From 4a7ada5f64d205f89675a5fe4553547d20cf94e8 Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Wed, 19 Aug 2015 11:04:08 -0700 Subject: [PATCH] Make IValueProvider sync, IValueProviderFactory async --- .../ModelBinding/IValueProvider.cs | 4 +- .../ModelBinding/IValueProviderFactory.cs | 11 +- .../ModelBinding/ValueProviderResult.cs | 2 +- .../FilterActionInvoker.cs | 2 +- .../BindingSourceValueProvider.cs | 4 +- .../ModelBinding/ByteArrayModelBinder.cs | 9 +- .../ModelBinding/CollectionModelBinder.cs | 6 +- .../ModelBinding/CompositeValueProvider.cs | 16 +-- .../DictionaryBasedValueProvider.cs | 13 +-- .../ModelBinding/DictionaryModelBinder.cs | 2 +- .../ModelBinding/ElementalValueProvider.cs | 11 +- .../ModelBinding/FormValueProviderFactory.cs | 5 +- .../ModelBinding/IEnumerableValueProvider.cs | 3 +- .../ModelBinding/JQueryFormValueProvider.cs | 74 ++++--------- .../JQueryFormValueProviderFactory.cs | 4 +- .../ModelBinding/MutableObjectModelBinder.cs | 14 +-- .../QueryStringValueProviderFactory.cs | 7 +- .../ReadableStringCollectionValueProvider.cs | 76 ++++--------- .../RouteValueValueProviderFactory.cs | 7 +- .../ModelBinding/SimpleTypeModelBinder.cs | 20 +++- .../ModelBinding/ArrayModelBinderTest.cs | 8 +- .../BindingSourceValueProviderTest.cs | 4 +- .../ModelBinding/CollectionModelBinderTest.cs | 12 ++- .../CompositeValueProviderTest.cs | 12 +-- .../DictionaryBasedValueProviderTests.cs | 32 +++--- .../ElementalValueProviderTests.cs | 22 ++-- .../EnumerableValueProviderTest.cs | 63 +++++------ .../FormValueProviderFactoryTest.cs | 14 ++- .../JQueryFormValueProviderFactoryTest.cs | 17 +-- .../MutableObjectModelBinderTest.cs | 102 +++++++++--------- .../QueryStringValueProviderFactoryTest.cs | 5 +- .../ModelBinding/SimpleValueProvider.cs | 39 ++----- .../ModelBindingTestHelper.cs | 4 +- .../ModelBinderAttribute_ProductController.cs | 10 +- .../Controllers/TryUpdateModelController.cs | 8 +- .../CustomValueProviderFactory.cs | 16 ++- 36 files changed, 302 insertions(+), 356 deletions(-) diff --git a/src/Microsoft.AspNet.Mvc.Abstractions/ModelBinding/IValueProvider.cs b/src/Microsoft.AspNet.Mvc.Abstractions/ModelBinding/IValueProvider.cs index eaff69fd19..b0c56d31ea 100644 --- a/src/Microsoft.AspNet.Mvc.Abstractions/ModelBinding/IValueProvider.cs +++ b/src/Microsoft.AspNet.Mvc.Abstractions/ModelBinding/IValueProvider.cs @@ -15,13 +15,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding /// /// The prefix to search for. /// true if the collection contains the specified prefix; otherwise, false. - Task ContainsPrefixAsync(string prefix); + bool ContainsPrefix(string prefix); /// /// Retrieves a value object using the specified key. /// /// The key of the value object to retrieve. /// The value object for the specified key. If the exact key is not found, null. - Task GetValueAsync(string key); + ValueProviderResult GetValue(string key); } } diff --git a/src/Microsoft.AspNet.Mvc.Abstractions/ModelBinding/IValueProviderFactory.cs b/src/Microsoft.AspNet.Mvc.Abstractions/ModelBinding/IValueProviderFactory.cs index 56a2fe3a07..cf7ba74b3c 100644 --- a/src/Microsoft.AspNet.Mvc.Abstractions/ModelBinding/IValueProviderFactory.cs +++ b/src/Microsoft.AspNet.Mvc.Abstractions/ModelBinding/IValueProviderFactory.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System.Threading.Tasks; using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Mvc.ModelBinding @@ -8,10 +9,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding public interface IValueProviderFactory { /// - /// Get a value provider with values from the given . + /// Gets a with values from the current request. /// - /// ValueProviderFactoryContext that value provider will populate from - /// a value provider instance or null - IValueProvider GetValueProvider([NotNull] ValueProviderFactoryContext context); + /// The . + /// + /// A that when completed will yield a instance or null. + /// + Task GetValueProviderAsync([NotNull] ValueProviderFactoryContext context); } } diff --git a/src/Microsoft.AspNet.Mvc.Abstractions/ModelBinding/ValueProviderResult.cs b/src/Microsoft.AspNet.Mvc.Abstractions/ModelBinding/ValueProviderResult.cs index 1c92b91ad8..0c3fcfe2b3 100644 --- a/src/Microsoft.AspNet.Mvc.Abstractions/ModelBinding/ValueProviderResult.cs +++ b/src/Microsoft.AspNet.Mvc.Abstractions/ModelBinding/ValueProviderResult.cs @@ -11,7 +11,7 @@ using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Mvc.ModelBinding { /// - /// Result of an operation. + /// Result of an operation. /// /// /// diff --git a/src/Microsoft.AspNet.Mvc.Core/FilterActionInvoker.cs b/src/Microsoft.AspNet.Mvc.Core/FilterActionInvoker.cs index 873eed3fa6..b928a72b63 100644 --- a/src/Microsoft.AspNet.Mvc.Core/FilterActionInvoker.cs +++ b/src/Microsoft.AspNet.Mvc.Core/FilterActionInvoker.cs @@ -333,7 +333,7 @@ namespace Microsoft.AspNet.Mvc.Core ActionContext.HttpContext, ActionContext.RouteData.Values); - ActionBindingContext.ValueProvider = CompositeValueProvider.Create( + ActionBindingContext.ValueProvider = await CompositeValueProvider.CreateAsync( _resourceExecutingContext.ValueProviderFactories, valueProviderFactoryContext); diff --git a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/BindingSourceValueProvider.cs b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/BindingSourceValueProvider.cs index c812609e39..6099e321ab 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/BindingSourceValueProvider.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/BindingSourceValueProvider.cs @@ -60,10 +60,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding protected BindingSource BindingSource { get; } /// - public abstract Task ContainsPrefixAsync(string prefix); + public abstract bool ContainsPrefix(string prefix); /// - public abstract Task GetValueAsync(string key); + public abstract ValueProviderResult GetValue(string key); /// public virtual IValueProvider Filter(BindingSource bindingSource) diff --git a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/ByteArrayModelBinder.cs b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/ByteArrayModelBinder.cs index c49f1fcdde..c1cd683223 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/ByteArrayModelBinder.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/ByteArrayModelBinder.cs @@ -13,7 +13,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding public class ByteArrayModelBinder : IModelBinder { /// - public async Task BindModelAsync([NotNull] ModelBindingContext bindingContext) + public Task BindModelAsync([NotNull] ModelBindingContext bindingContext) + { + return Task.FromResult(BindModel(bindingContext)); + } + + private ModelBindingResult BindModel(ModelBindingContext bindingContext) { // Check if this binder applies. if (bindingContext.ModelType != typeof(byte[])) @@ -22,7 +27,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding } // Check for missing data case 1: There was no element containing this data. - var valueProviderResult = await bindingContext.ValueProvider.GetValueAsync(bindingContext.ModelName); + var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); if (valueProviderResult == ValueProviderResult.None) { return new ModelBindingResult(model: null, key: bindingContext.ModelName, isModelSet: false); diff --git a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/CollectionModelBinder.cs b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/CollectionModelBinder.cs index 6cc2e1b291..8177bfa34c 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/CollectionModelBinder.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/CollectionModelBinder.cs @@ -27,7 +27,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding ModelBindingHelper.ValidateBindingContext(bindingContext); var model = bindingContext.Model; - if (!await bindingContext.ValueProvider.ContainsPrefixAsync(bindingContext.ModelName)) + if (!bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName)) { // If this is the fallback case and we failed to find data for a top-level model, then generate a // default 'empty' model (or use existing Model) and return it. @@ -53,7 +53,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding return null; } - var valueProviderResult = await bindingContext.ValueProvider.GetValueAsync(bindingContext.ModelName); + var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); CollectionResult result; if (valueProviderResult == ValueProviderResult.None) @@ -188,7 +188,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding private async Task BindComplexCollection(ModelBindingContext bindingContext) { var indexPropertyName = ModelNames.CreatePropertyModelName(bindingContext.ModelName, "index"); - var valueProviderResultIndex = await bindingContext.ValueProvider.GetValueAsync(indexPropertyName); + var valueProviderResultIndex = bindingContext.ValueProvider.GetValue(indexPropertyName); var indexNames = GetIndexNamesFromValueProviderResult(valueProviderResultIndex); return await BindComplexCollectionFromIndexes(bindingContext, indexNames); diff --git a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/CompositeValueProvider.cs b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/CompositeValueProvider.cs index 65ef7c6ec5..7ffa938daa 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/CompositeValueProvider.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/CompositeValueProvider.cs @@ -46,14 +46,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding /// A containing all instances /// created. /// - public static CompositeValueProvider Create( + public static async Task CreateAsync( [NotNull] IEnumerable factories, [NotNull] ValueProviderFactoryContext context) { var composite = new CompositeValueProvider(); foreach (var valueProvidersFactory in factories) { - var valueProvider = valueProvidersFactory.GetValueProvider(context); + var valueProvider = await valueProvidersFactory.GetValueProviderAsync(context); if (valueProvider != null) { composite.Add(valueProvider); @@ -64,11 +64,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding } /// - public virtual async Task ContainsPrefixAsync(string prefix) + public virtual bool ContainsPrefix(string prefix) { for (var i = 0; i < Count; i++) { - if (await this[i].ContainsPrefixAsync(prefix)) + if (this[i].ContainsPrefix(prefix)) { return true; } @@ -77,7 +77,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding } /// - public virtual async Task GetValueAsync(string key) + public virtual ValueProviderResult GetValue(string key) { // Performance-sensitive // Caching the count is faster for IList @@ -85,7 +85,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding for (var i = 0; i < itemCount; i++) { var valueProvider = Items[i]; - var result = await valueProvider.GetValueAsync(key); + var result = valueProvider.GetValue(key); if (result != ValueProviderResult.None) { return result; @@ -96,14 +96,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding } /// - public virtual async Task> GetKeysFromPrefixAsync(string prefix) + public virtual IDictionary GetKeysFromPrefix(string prefix) { foreach (var valueProvider in this) { var enumeratedProvider = valueProvider as IEnumerableValueProvider; if (enumeratedProvider != null) { - var result = await enumeratedProvider.GetKeysFromPrefixAsync(prefix); + var result = enumeratedProvider.GetKeysFromPrefix(prefix); if (result != null && result.Count > 0) { return result; diff --git a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/DictionaryBasedValueProvider.cs b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/DictionaryBasedValueProvider.cs index 39e9547f1b..7069f692d9 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/DictionaryBasedValueProvider.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/DictionaryBasedValueProvider.cs @@ -44,27 +44,24 @@ namespace Microsoft.AspNet.Mvc.ModelBinding } /// - public override Task ContainsPrefixAsync(string key) + public override bool ContainsPrefix(string key) { - return Task.FromResult(PrefixContainer.ContainsPrefix(key)); + return PrefixContainer.ContainsPrefix(key); } /// - public override Task GetValueAsync([NotNull] string key) + public override ValueProviderResult GetValue([NotNull] string key) { object value; - ValueProviderResult result; if (_values.TryGetValue(key, out value)) { var stringValue = value as string ?? value?.ToString() ?? string.Empty; - result = new ValueProviderResult(stringValue, CultureInfo.InvariantCulture); + return new ValueProviderResult(stringValue, CultureInfo.InvariantCulture); } else { - result = ValueProviderResult.None; + return ValueProviderResult.None; } - - return Task.FromResult(result); } } } diff --git a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/DictionaryModelBinder.cs b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/DictionaryModelBinder.cs index 9d3fac8d4c..640f5c8c7d 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/DictionaryModelBinder.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/DictionaryModelBinder.cs @@ -47,7 +47,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding } // Attempt to bind dictionary from a set of prefix[key]=value entries. Get the short and long keys first. - var keys = await enumerableValueProvider.GetKeysFromPrefixAsync(bindingContext.ModelName); + var keys = enumerableValueProvider.GetKeysFromPrefix(bindingContext.ModelName); if (!keys.Any()) { // No entries with the expected keys. diff --git a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/ElementalValueProvider.cs b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/ElementalValueProvider.cs index 25e7f96aee..80cb112734 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/ElementalValueProvider.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/ElementalValueProvider.cs @@ -3,7 +3,6 @@ using System; using System.Globalization; -using System.Threading.Tasks; namespace Microsoft.AspNet.Mvc.ModelBinding { @@ -22,20 +21,20 @@ namespace Microsoft.AspNet.Mvc.ModelBinding public string Value { get; } - public Task ContainsPrefixAsync(string prefix) + public bool ContainsPrefix(string prefix) { - return Task.FromResult(PrefixContainer.IsPrefixMatch(prefix, Key)); + return PrefixContainer.IsPrefixMatch(prefix, Key); } - public Task GetValueAsync(string key) + public ValueProviderResult GetValue(string key) { if (string.Equals(key, Key, StringComparison.OrdinalIgnoreCase)) { - return Task.FromResult(new ValueProviderResult(Value, Culture)); + return new ValueProviderResult(Value, Culture); } else { - return Task.FromResult(ValueProviderResult.None); + return ValueProviderResult.None; } } } diff --git a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/FormValueProviderFactory.cs b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/FormValueProviderFactory.cs index 56ee8e1250..cd2f1bbf07 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/FormValueProviderFactory.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/FormValueProviderFactory.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Globalization; +using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.Framework.Internal; @@ -9,7 +10,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding { public class FormValueProviderFactory : IValueProviderFactory { - public IValueProvider GetValueProvider([NotNull] ValueProviderFactoryContext context) + public async Task GetValueProviderAsync([NotNull] ValueProviderFactoryContext context) { var request = context.HttpContext.Request; @@ -19,7 +20,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding return new ReadableStringCollectionValueProvider( BindingSource.Form, - async () => await request.ReadFormAsync(), + await request.ReadFormAsync(), culture); } diff --git a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/IEnumerableValueProvider.cs b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/IEnumerableValueProvider.cs index 7945bfa85d..003f9cca4d 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/IEnumerableValueProvider.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/IEnumerableValueProvider.cs @@ -2,12 +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 System.Threading.Tasks; namespace Microsoft.AspNet.Mvc.ModelBinding { public interface IEnumerableValueProvider : IValueProvider { - Task> GetKeysFromPrefixAsync(string prefix); + IDictionary GetKeysFromPrefix(string prefix); } } diff --git a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/JQueryFormValueProvider.cs b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/JQueryFormValueProvider.cs index 439dd1a556..d72fbaa0e2 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/JQueryFormValueProvider.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/JQueryFormValueProvider.cs @@ -1,7 +1,6 @@ // Copyright (c) .NET Foundation. All rights reserved. // 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.Diagnostics; using System.Globalization; @@ -11,15 +10,12 @@ using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Mvc.ModelBinding { /// - /// An for form data stored in an and - /// generally accessed asynchronously. + /// An for form data stored in an . /// public class JQueryFormValueProvider : BindingSourceValueProvider, IEnumerableValueProvider { - private readonly Func>> _valuesFactory; - private PrefixContainer _prefixContainer; - private IDictionary _values; + private readonly IDictionary _values; /// /// Initializes a new instance of the class. @@ -28,17 +24,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding /// A delegate which provides the values to wrap. /// The culture to return with ValueProviderResult instances. public JQueryFormValueProvider( - [NotNull] BindingSource bindingSource, - [NotNull] Func>> valuesFactory, - CultureInfo culture) - : base(bindingSource) - { - _valuesFactory = valuesFactory; - Culture = culture; - } - - // Internal for testing. - internal JQueryFormValueProvider( [NotNull] BindingSource bindingSource, [NotNull] IDictionary values, CultureInfo culture) @@ -51,58 +36,41 @@ namespace Microsoft.AspNet.Mvc.ModelBinding // Internal for testing internal CultureInfo Culture { get; } - /// - public override async Task ContainsPrefixAsync(string prefix) + protected PrefixContainer PrefixContainer { - var prefixContainer = await GetPrefixContainerAsync(); - return prefixContainer.ContainsPrefix(prefix); + get + { + if (_prefixContainer == null) + { + _prefixContainer = new PrefixContainer(_values.Keys); + } + + return _prefixContainer; + } } /// - public async Task> GetKeysFromPrefixAsync(string prefix) + public override bool ContainsPrefix(string prefix) { - var prefixContainer = await GetPrefixContainerAsync(); - return prefixContainer.GetKeysFromPrefix(prefix); + return PrefixContainer.ContainsPrefix(prefix); } /// - public override async Task GetValueAsync(string key) + public IDictionary GetKeysFromPrefix(string prefix) { - var dictionary = await GetDictionary(); + return PrefixContainer.GetKeysFromPrefix(prefix); + } + /// + public override ValueProviderResult GetValue(string key) + { string[] values; - if (dictionary.TryGetValue(key, out values) && values != null && values.Length > 0) + if (_values.TryGetValue(key, out values) && values != null && values.Length > 0) { return new ValueProviderResult(values, Culture); } return ValueProviderResult.None; } - - private async Task> GetDictionary() - { - if (_values == null) - { - Debug.Assert(_valuesFactory != null); - - // Initialization race is OK providing data remains read-only. - _values = await _valuesFactory(); - } - - return _values; - } - - private async Task GetPrefixContainerAsync() - { - if (_prefixContainer == null) - { - var dictionary = await GetDictionary(); - - // Initialization race is OK providing data remains read-only and object identity is not significant. - _prefixContainer = new PrefixContainer(dictionary.Keys); - } - - return _prefixContainer; - } } } diff --git a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/JQueryFormValueProviderFactory.cs b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/JQueryFormValueProviderFactory.cs index e40cd205c0..c1d289cb62 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/JQueryFormValueProviderFactory.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/JQueryFormValueProviderFactory.cs @@ -14,7 +14,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding { public class JQueryFormValueProviderFactory : IValueProviderFactory { - public IValueProvider GetValueProvider([NotNull] ValueProviderFactoryContext context) + public async Task GetValueProviderAsync([NotNull] ValueProviderFactoryContext context) { var request = context.HttpContext.Request; @@ -22,7 +22,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding { return new JQueryFormValueProvider( BindingSource.Form, - () => GetValueCollectionAsync(request), + await GetValueCollectionAsync(request), CultureInfo.CurrentCulture); } diff --git a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/MutableObjectModelBinder.cs b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/MutableObjectModelBinder.cs index fda668a1f5..b3806828b9 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/MutableObjectModelBinder.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/MutableObjectModelBinder.cs @@ -35,7 +35,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding PropertyMetadata = GetMetadataForProperties(bindingContext).ToArray(), }; - if (!(await CanCreateModel(mutableObjectBinderContext))) + if (!(CanCreateModel(mutableObjectBinderContext))) { return null; } @@ -72,7 +72,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding return CanUpdatePropertyInternal(propertyMetadata); } - internal async Task CanCreateModel(MutableObjectBinderContext context) + internal bool CanCreateModel(MutableObjectBinderContext context) { var bindingContext = context.ModelBindingContext; var isTopLevelObject = bindingContext.IsTopLevelObject; @@ -109,7 +109,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding } // 3. Any of the model properties can be bound using a value provider. - if (await CanValueBindAnyModelProperties(context)) + if (CanValueBindAnyModelProperties(context)) { return true; } @@ -117,7 +117,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding return false; } - private async Task CanValueBindAnyModelProperties(MutableObjectBinderContext context) + private bool CanValueBindAnyModelProperties(MutableObjectBinderContext context) { // If there are no properties on the model, there is nothing to bind. We are here means this is not a top // level object. So we return false. @@ -170,7 +170,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding propertyMetadata); // If any property can return a true value. - if (await CanBindValue(propertyModelBindingContext)) + if (CanBindValue(propertyModelBindingContext)) { return true; } @@ -189,7 +189,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding return false; } - private async Task CanBindValue(ModelBindingContext bindingContext) + private bool CanBindValue(ModelBindingContext bindingContext) { var valueProvider = bindingContext.ValueProvider; @@ -209,7 +209,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding } } - if (await valueProvider.ContainsPrefixAsync(bindingContext.ModelName)) + if (valueProvider.ContainsPrefix(bindingContext.ModelName)) { return true; } diff --git a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/QueryStringValueProviderFactory.cs b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/QueryStringValueProviderFactory.cs index 27374f9daf..2096aa0649 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/QueryStringValueProviderFactory.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/QueryStringValueProviderFactory.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Globalization; +using System.Threading.Tasks; using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Mvc.ModelBinding @@ -13,12 +14,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding public class QueryStringValueProviderFactory : IValueProviderFactory { /// - public IValueProvider GetValueProvider([NotNull] ValueProviderFactoryContext context) + public Task GetValueProviderAsync([NotNull] ValueProviderFactoryContext context) { - return new ReadableStringCollectionValueProvider( + return Task.FromResult(new ReadableStringCollectionValueProvider( BindingSource.Query, context.HttpContext.Request.Query, - CultureInfo.InvariantCulture); + CultureInfo.InvariantCulture)); } } } diff --git a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/ReadableStringCollectionValueProvider.cs b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/ReadableStringCollectionValueProvider.cs index c47be559f4..305c053cf2 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/ReadableStringCollectionValueProvider.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/ReadableStringCollectionValueProvider.cs @@ -18,7 +18,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding public class ReadableStringCollectionValueProvider : BindingSourceValueProvider, IEnumerableValueProvider { private readonly CultureInfo _culture; - private readonly Func> _valuesFactory; private PrefixContainer _prefixContainer; private IReadableStringCollection _values; @@ -38,23 +37,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding _culture = culture; } - /// - /// Creates a provider for wrapping an - /// existing set of key value pairs provided by the delegate. - /// - /// The for the data. - /// The delegate that provides the key value pairs to wrap. - /// The culture to return with ValueProviderResult instances. - public ReadableStringCollectionValueProvider( - [NotNull] BindingSource bindingSource, - [NotNull] Func> valuesFactory, - CultureInfo culture) - : base(bindingSource) - { - _valuesFactory = valuesFactory; - _culture = culture; - } - public CultureInfo Culture { get @@ -63,59 +45,43 @@ namespace Microsoft.AspNet.Mvc.ModelBinding } } - /// - public override async Task ContainsPrefixAsync(string prefix) + protected PrefixContainer PrefixContainer { - var prefixContainer = await GetPrefixContainerAsync(); - return prefixContainer.ContainsPrefix(prefix); + get + { + if (_prefixContainer == null) + { + _prefixContainer = new PrefixContainer(_values.Keys); + } + + return _prefixContainer; + } } /// - public virtual async Task> GetKeysFromPrefixAsync([NotNull] string prefix) + public override bool ContainsPrefix(string prefix) { - var prefixContainer = await GetPrefixContainerAsync(); - return prefixContainer.GetKeysFromPrefix(prefix); + return PrefixContainer.ContainsPrefix(prefix); } /// - public override async Task GetValueAsync([NotNull] string key) + public virtual IDictionary GetKeysFromPrefix([NotNull] string prefix) { - var collection = await GetValueCollectionAsync(); - var values = collection.GetValues(key); + return PrefixContainer.GetKeysFromPrefix(prefix); + } - ValueProviderResult result; + /// + public override ValueProviderResult GetValue([NotNull] string key) + { + var values = _values.GetValues(key); if (values == null) { - result = ValueProviderResult.None; + return ValueProviderResult.None; } else { - result = new ValueProviderResult(values.ToArray(), _culture); + return new ValueProviderResult(values.ToArray(), _culture); } - - return result; - } - - private async Task GetValueCollectionAsync() - { - if (_values == null) - { - Debug.Assert(_valuesFactory != null); - _values = await _valuesFactory(); - } - - return _values; - } - - private async Task GetPrefixContainerAsync() - { - if (_prefixContainer == null) - { - // Initialization race is OK providing data remains read-only and object identity is not significant - var collection = await GetValueCollectionAsync(); - _prefixContainer = new PrefixContainer(collection.Keys); - } - return _prefixContainer; } } } diff --git a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/RouteValueValueProviderFactory.cs b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/RouteValueValueProviderFactory.cs index 76a55a70f5..6b1d8b9fad 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/RouteValueValueProviderFactory.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/RouteValueValueProviderFactory.cs @@ -1,15 +1,18 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System.Threading.Tasks; using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Mvc.ModelBinding { public class RouteValueValueProviderFactory : IValueProviderFactory { - public IValueProvider GetValueProvider([NotNull] ValueProviderFactoryContext context) + public Task GetValueProviderAsync([NotNull] ValueProviderFactoryContext context) { - return new DictionaryBasedValueProvider(BindingSource.Path, context.RouteValues); + return Task.FromResult(new DictionaryBasedValueProvider( + BindingSource.Path, + context.RouteValues)); } } } diff --git a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/SimpleTypeModelBinder.cs b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/SimpleTypeModelBinder.cs index efab3c0971..db83cb5cb8 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ModelBinding/SimpleTypeModelBinder.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ModelBinding/SimpleTypeModelBinder.cs @@ -10,7 +10,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding { public class SimpleTypeModelBinder : IModelBinder { - public async Task BindModelAsync(ModelBindingContext bindingContext) + public Task BindModelAsync(ModelBindingContext bindingContext) + { + return Task.FromResult(BindModel(bindingContext)); + } + + public ModelBindingResult BindModel(ModelBindingContext bindingContext) { if (bindingContext.ModelMetadata.IsComplexType) { @@ -18,7 +23,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding return null; } - var valueProviderResult = await bindingContext.ValueProvider.GetValueAsync(bindingContext.ModelName); + var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); if (valueProviderResult == ValueProviderResult.None) { // no entry @@ -60,7 +65,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding new ModelValidationNode(bindingContext.ModelName, bindingContext.ModelMetadata, model) : null; - return new ModelBindingResult(model, bindingContext.ModelName, isModelSet, validationNode); + return new ModelBindingResult( + model, + bindingContext.ModelName, + isModelSet, + validationNode); } catch (Exception ex) { @@ -69,7 +78,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding // Were able to find a converter for the type but conversion failed. // Tell the model binding system to skip other model binders i.e. return non-null. - return new ModelBindingResult(model: null, key: bindingContext.ModelName, isModelSet: false); + return new ModelBindingResult( + model: null, + key: bindingContext.ModelName, + isModelSet: false); } private static bool AllowsNullValue(Type type) diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/ArrayModelBinderTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/ArrayModelBinderTest.cs index dea769501f..e525fadd9f 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/ArrayModelBinderTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/ArrayModelBinderTest.cs @@ -193,15 +193,15 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test var mockIntBinder = new Mock(); mockIntBinder .Setup(o => o.BindModelAsync(It.IsAny())) - .Returns(async (ModelBindingContext mbc) => + .Returns((ModelBindingContext mbc) => { - var value = await mbc.ValueProvider.GetValueAsync(mbc.ModelName); + var value = mbc.ValueProvider.GetValue(mbc.ModelName); if (value != ValueProviderResult.None) { var model = value.ConvertTo(mbc.ModelType); - return new ModelBindingResult(model, key: null, isModelSet: true); + return Task.FromResult(new ModelBindingResult(model, key: null, isModelSet: true)); } - return null; + return Task.FromResult(null); }); return mockIntBinder.Object; } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/BindingSourceValueProviderTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/BindingSourceValueProviderTest.cs index fdf2f5aeb0..79df3554df 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/BindingSourceValueProviderTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/BindingSourceValueProviderTest.cs @@ -83,12 +83,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding { } - public override Task ContainsPrefixAsync(string prefix) + public override bool ContainsPrefix(string prefix) { throw new NotImplementedException(); } - public override Task GetValueAsync(string key) + public override ValueProviderResult GetValue(string key) { throw new NotImplementedException(); } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/CollectionModelBinderTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/CollectionModelBinderTest.cs index b0b6e1278d..28f553726a 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/CollectionModelBinderTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/CollectionModelBinderTest.cs @@ -435,17 +435,21 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test Mock mockIntBinder = new Mock(); mockIntBinder .Setup(o => o.BindModelAsync(It.IsAny())) - .Returns(async (ModelBindingContext mbc) => + .Returns((ModelBindingContext mbc) => { - var value = await mbc.ValueProvider.GetValueAsync(mbc.ModelName); + var value = mbc.ValueProvider.GetValue(mbc.ModelName); if (value != ValueProviderResult.None) { var model = value.ConvertTo(mbc.ModelType); var modelValidationNode = new ModelValidationNode(mbc.ModelName, mbc.ModelMetadata, model); - return new ModelBindingResult(model, mbc.ModelName, model != null, modelValidationNode); + return Task.FromResult(new ModelBindingResult( + model, + mbc.ModelName, + model != null, + modelValidationNode)); } - return null; + return Task.FromResult(null); }); return mockIntBinder.Object; } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/CompositeValueProviderTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/CompositeValueProviderTest.cs index 6537336403..6a0896429c 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/CompositeValueProviderTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/CompositeValueProviderTest.cs @@ -30,7 +30,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding #if DNX451 [Fact] - public async Task GetKeysFromPrefixAsync_ReturnsResultFromFirstValueProviderThatReturnsValues() + public void GetKeysFromPrefixAsync_ReturnsResultFromFirstValueProviderThatReturnsValues() { // Arrange var provider1 = Mock.Of(); @@ -39,13 +39,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding { "prefix-test", "some-value" }, }; var provider2 = new Mock(); - provider2.Setup(p => p.GetKeysFromPrefixAsync("prefix")) - .Returns(Task.FromResult>(dictionary)) + provider2.Setup(p => p.GetKeysFromPrefix("prefix")) + .Returns(dictionary) .Verifiable(); var provider = new CompositeValueProvider(new[] { provider1, provider2.Object }); // Act - var values = await provider.GetKeysFromPrefixAsync("prefix"); + var values = provider.GetKeysFromPrefix("prefix"); // Assert var result = Assert.Single(values); @@ -55,7 +55,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding } [Fact] - public async Task GetKeysFromPrefixAsync_ReturnsEmptyDictionaryIfNoValueProviderReturnsValues() + public void GetKeysFromPrefixAsync_ReturnsEmptyDictionaryIfNoValueProviderReturnsValues() { // Arrange var provider1 = Mock.Of(); @@ -63,7 +63,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding var provider = new CompositeValueProvider(new[] { provider1, provider2 }); // Act - var values = await provider.GetKeysFromPrefixAsync("prefix"); + var values = provider.GetKeysFromPrefix("prefix"); // Assert Assert.Empty(values); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/DictionaryBasedValueProviderTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/DictionaryBasedValueProviderTests.cs index a59d3b4af0..01dd0baeca 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/DictionaryBasedValueProviderTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/DictionaryBasedValueProviderTests.cs @@ -11,7 +11,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding public class DictionaryBasedValueProviderTests { [Fact] - public async Task GetValueProvider_ReturnsNull_WhenKeyIsNotFound() + public void GetValueProvider_ReturnsNull_WhenKeyIsNotFound() { // Arrange var values = new Dictionary(StringComparer.OrdinalIgnoreCase) @@ -21,14 +21,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding var provider = new DictionaryBasedValueProvider(BindingSource.Query, values); // Act - var result = await provider.GetValueAsync("not-test-key"); + var result = provider.GetValue("not-test-key"); // Assert Assert.Equal(ValueProviderResult.None, result); } [Fact] - public async Task GetValueProvider_ReturnsValue_IfKeyIsPresent() + public void GetValueProvider_ReturnsValue_IfKeyIsPresent() { // Arrange var values = new Dictionary(StringComparer.OrdinalIgnoreCase) @@ -38,14 +38,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding var provider = new DictionaryBasedValueProvider(BindingSource.Query, values); // Act - var result = await provider.GetValueAsync("test-key"); + var result = provider.GetValue("test-key"); // Assert Assert.Equal("test-value", (string)result); } [Fact] - public async Task ContainsPrefixAsync_ReturnsNullValue_IfKeyIsPresent() + public void ContainsPrefix_ReturnsNullValue_IfKeyIsPresent() { // Arrange var values = new Dictionary(StringComparer.OrdinalIgnoreCase) @@ -55,7 +55,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding var provider = new DictionaryBasedValueProvider(BindingSource.Query, values); // Act - var result = await provider.GetValueAsync("test-key"); + var result = provider.GetValue("test-key"); // Assert Assert.Equal(string.Empty, (string)result); @@ -65,7 +65,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding [InlineData("foo")] [InlineData("bar")] [InlineData("bar.baz")] - public async Task ContainsPrefixAsync_ReturnsTrue_ForKnownPrefixes(string prefix) + public void ContainsPrefix_ReturnsTrue_ForKnownPrefixes(string prefix) { // Arrange var values = new Dictionary @@ -77,7 +77,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding var valueProvider = new DictionaryBasedValueProvider(BindingSource.Query, values); // Act - var result = await valueProvider.ContainsPrefixAsync(prefix); + var result = valueProvider.ContainsPrefix(prefix); // Assert Assert.True(result); @@ -86,7 +86,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding [Theory] [InlineData("bar", "1")] [InlineData("bar.baz", "2")] - public async Task GetValueAsync_ReturnsCorrectValue_ForKnownKeys(string prefix, string expectedValue) + public void GetValue_ReturnsCorrectValue_ForKnownKeys(string prefix, string expectedValue) { // Arrange var values = new Dictionary @@ -98,14 +98,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding var valueProvider = new DictionaryBasedValueProvider(BindingSource.Query, values); // Act - var result = await valueProvider.GetValueAsync(prefix); + var result = valueProvider.GetValue(prefix); // Assert Assert.Equal(expectedValue, (string)result); } [Fact] - public async Task GetValueAsync_DoesNotReturnAValue_ForAKeyPrefix() + public void GetValue_DoesNotReturnAValue_ForAKeyPrefix() { // Arrange var values = new Dictionary @@ -116,14 +116,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding var valueProvider = new DictionaryBasedValueProvider(BindingSource.Query, values); // Act - var result = await valueProvider.GetValueAsync("bar"); + var result = valueProvider.GetValue("bar"); // Assert Assert.Equal(ValueProviderResult.None, result); } [Fact] - public async Task ContainsPrefixAsync_ReturnsFalse_IfKeyIsNotPresent() + public void ContainsPrefix_ReturnsFalse_IfKeyIsNotPresent() { // Arrange var values = new Dictionary(StringComparer.OrdinalIgnoreCase) @@ -133,14 +133,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding var provider = new DictionaryBasedValueProvider(BindingSource.Query, values); // Act - var result = await provider.ContainsPrefixAsync("not-test-key"); + var result = provider.ContainsPrefix("not-test-key"); // Assert Assert.False(result); } [Fact] - public async Task ContainsPrefixAsync_ReturnsTrue_IfKeyIsPresent() + public void ContainsPrefix_ReturnsTrue_IfKeyIsPresent() { // Arrange var values = new Dictionary(StringComparer.OrdinalIgnoreCase) @@ -150,7 +150,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding var provider = new DictionaryBasedValueProvider(BindingSource.Query, values); // Act - var result = await provider.ContainsPrefixAsync("test-key"); + var result = provider.ContainsPrefix("test-key"); // Assert Assert.True(result); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/ElementalValueProviderTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/ElementalValueProviderTests.cs index b6c4c7ff5b..453ba4c606 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/ElementalValueProviderTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/ElementalValueProviderTests.cs @@ -14,8 +14,9 @@ namespace Microsoft.AspNet.Mvc.ModelBinding [InlineData("MyProperty", "MyProperty")] [InlineData("MyProperty.SubProperty", "MyProperty")] [InlineData("MyProperty[0]", "MyProperty")] - public async Task ContainsPrefixAsync_ReturnsTrue_IfElementNameStartsWithPrefix(string elementName, - string prefix) + public void ContainsPrefix_ReturnsTrue_IfElementNameStartsWithPrefix( + string elementName, + string prefix) { // Arrange var culture = new CultureInfo("en-US"); @@ -25,7 +26,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding culture); // Act - var containsPrefix = await elementalValueProvider.ContainsPrefixAsync(prefix); + var containsPrefix = elementalValueProvider.ContainsPrefix(prefix); // Assert Assert.True(containsPrefix); @@ -35,8 +36,9 @@ namespace Microsoft.AspNet.Mvc.ModelBinding [InlineData("MyProperty", "MyProperty1")] [InlineData("MyPropertyTest", "MyProperty")] [InlineData("Random", "MyProperty")] - public async Task ContainsPrefixAsync_ReturnsFalse_IfElementCannotSpecifyValuesForPrefix(string elementName, - string prefix) + public void ContainsPrefix_ReturnsFalse_IfElementCannotSpecifyValuesForPrefix( + string elementName, + string prefix) { // Arrange var culture = new CultureInfo("en-US"); @@ -46,21 +48,21 @@ namespace Microsoft.AspNet.Mvc.ModelBinding culture); // Act - var containsPrefix = await elementalValueProvider.ContainsPrefixAsync(prefix); + var containsPrefix = elementalValueProvider.ContainsPrefix(prefix); // Assert Assert.False(containsPrefix); } [Fact] - public async Task GetValueAsync_NameDoesNotMatch_ReturnsEmptyResult() + public void GetValue_NameDoesNotMatch_ReturnsEmptyResult() { // Arrange var culture = new CultureInfo("fr-FR"); var valueProvider = new ElementalValueProvider("foo", "hi", culture); // Act - var result = await valueProvider.GetValueAsync("bar"); + var result = valueProvider.GetValue("bar"); // Assert Assert.Equal(ValueProviderResult.None, result); @@ -70,14 +72,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding [InlineData("foo")] [InlineData("FOO")] [InlineData("FoO")] - public async Task GetValueAsync_NameMatches_ReturnsValueProviderResult(string name) + public void GetValue_NameMatches_ReturnsValueProviderResult(string name) { // Arrange var culture = new CultureInfo("fr-FR"); var valueProvider = new ElementalValueProvider("foo", "hi", culture); // Act - var result = await valueProvider.GetValueAsync(name); + var result = valueProvider.GetValue(name); // Assert Assert.NotNull(result); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/EnumerableValueProviderTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/EnumerableValueProviderTest.cs index ea635be0b7..9eef0f2438 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/EnumerableValueProviderTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/EnumerableValueProviderTest.cs @@ -29,61 +29,62 @@ namespace Microsoft.AspNet.Mvc.ModelBinding }; [Fact] - public async Task ContainsPrefixAsync_WithEmptyCollection_ReturnsFalseForEmptyPrefix() + public void ContainsPrefix_WithEmptyCollection_ReturnsFalseForEmptyPrefix() { // Arrange var backingStore = new Dictionary(); var valueProvider = GetEnumerableValueProvider(BindingSource.Query, backingStore, culture: null); // Act - var result = await valueProvider.ContainsPrefixAsync(string.Empty); + var result = valueProvider.ContainsPrefix(string.Empty); // Assert Assert.False(result); } [Fact] - public async Task ContainsPrefixAsync_WithNonEmptyCollection_ReturnsTrueForEmptyPrefix() + public void ContainsPrefix_WithNonEmptyCollection_ReturnsTrueForEmptyPrefix() { // Arrange var valueProvider = GetEnumerableValueProvider(BindingSource.Query, _backingStore, culture: null); // Act - var result = await valueProvider.ContainsPrefixAsync(string.Empty); + var result = valueProvider.ContainsPrefix(string.Empty); // Assert Assert.True(result); } - [Fact] - public async Task ContainsPrefixAsync_WithNonEmptyCollection_ReturnsTrueForKnownPrefixes() + [Theory] + [InlineData("some")] + [InlineData("prefix")] + [InlineData("prefix.name")] + [InlineData("[index]")] + [InlineData("prefix[index1]")] + public void ContainsPrefix_WithNonEmptyCollection_ReturnsTrueForKnownPrefixes(string prefix) { // Arrange var valueProvider = GetEnumerableValueProvider(BindingSource.Query, _backingStore, culture: null); // Act & Assert - Assert.True(await valueProvider.ContainsPrefixAsync("some")); - Assert.True(await valueProvider.ContainsPrefixAsync("prefix")); - Assert.True(await valueProvider.ContainsPrefixAsync("prefix.name")); - Assert.True(await valueProvider.ContainsPrefixAsync("[index]")); - Assert.True(await valueProvider.ContainsPrefixAsync("prefix[index1]")); + Assert.True(valueProvider.ContainsPrefix(prefix)); } [Fact] - public async Task ContainsPrefixAsync_WithNonEmptyCollection_ReturnsFalseForUnknownPrefix() + public void ContainsPrefix_WithNonEmptyCollection_ReturnsFalseForUnknownPrefix() { // Arrange var valueProvider = GetEnumerableValueProvider(BindingSource.Query, _backingStore, culture: null); // Act - var result = await valueProvider.ContainsPrefixAsync("biff"); + var result = valueProvider.ContainsPrefix("biff"); // Assert Assert.False(result); } [Fact] - public async Task GetKeysFromPrefixAsync_EmptyPrefix_ReturnsAllPrefixes() + public void GetKeysFromPrefix_EmptyPrefix_ReturnsAllPrefixes() { // Arrange var expected = new Dictionary @@ -96,27 +97,27 @@ namespace Microsoft.AspNet.Mvc.ModelBinding var valueProvider = GetEnumerableValueProvider(BindingSource.Query, _backingStore, culture: null); // Act - var result = await valueProvider.GetKeysFromPrefixAsync(string.Empty); + var result = valueProvider.GetKeysFromPrefix(string.Empty); // Assert Assert.Equal(expected, result.OrderBy(kvp => kvp.Key)); } [Fact] - public async Task GetKeysFromPrefixAsync_UnknownPrefix_ReturnsEmptyDictionary() + public void GetKeysFromPrefix_UnknownPrefix_ReturnsEmptyDictionary() { // Arrange var valueProvider = GetEnumerableValueProvider(BindingSource.Query, _backingStore, culture: null); // Act - var result = await valueProvider.GetKeysFromPrefixAsync("abc"); + var result = valueProvider.GetKeysFromPrefix("abc"); // Assert Assert.Empty(result); } [Fact] - public async Task GetKeysFromPrefixAsync_KnownPrefix_ReturnsMatchingItems() + public void GetKeysFromPrefix_KnownPrefix_ReturnsMatchingItems() { // Arrange var expected = new Dictionary @@ -131,14 +132,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding var valueProvider = GetEnumerableValueProvider(BindingSource.Query, _backingStore, culture: null); // Act - var result = await valueProvider.GetKeysFromPrefixAsync("prefix"); + var result = valueProvider.GetKeysFromPrefix("prefix"); // Assert Assert.Equal(expected, result); } [Fact] - public async Task GetKeysFromPrefixAsync_IndexPrefix_ReturnsMatchingItems() + public void GetKeysFromPrefix_IndexPrefix_ReturnsMatchingItems() { // Arrange var expected = new Dictionary @@ -149,21 +150,21 @@ namespace Microsoft.AspNet.Mvc.ModelBinding var valueProvider = GetEnumerableValueProvider(BindingSource.Query, _backingStore, culture: null); // Act - var result = await valueProvider.GetKeysFromPrefixAsync("[index]"); + var result = valueProvider.GetKeysFromPrefix("[index]"); // Assert Assert.Equal(expected, result); } [Fact] - public async Task GetValueAsync_SingleValue() + public void GetValue_SingleValue() { // Arrange var culture = new CultureInfo("fr-FR"); var valueProvider = GetEnumerableValueProvider(BindingSource.Query, _backingStore, culture); // Act - var result = await valueProvider.GetValueAsync("prefix.name"); + var result = valueProvider.GetValue("prefix.name"); // Assert Assert.NotNull(result); @@ -172,14 +173,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding } [Fact] - public async Task GetValueAsync_MultiValue() + public void GetValue_MultiValue() { // Arrange var culture = new CultureInfo("fr-FR"); var valueProvider = GetEnumerableValueProvider(BindingSource.Query, _backingStore, culture); // Act - var result = await valueProvider.GetValueAsync("some"); + var result = valueProvider.GetValue("some"); // Assert Assert.NotNull(result); @@ -191,21 +192,21 @@ namespace Microsoft.AspNet.Mvc.ModelBinding [Theory] [InlineData("null_value")] [InlineData("prefix.null_value")] - public async Task GetValue_NullValue(string key) + public void GetValue_NullValue(string key) { // Arrange var culture = new CultureInfo("fr-FR"); var valueProvider = GetEnumerableValueProvider(BindingSource.Query, _backingStore, culture); // Act - var result = await valueProvider.GetValueAsync(key); + var result = valueProvider.GetValue(key); // Assert Assert.Equal(ValueProviderResult.None, result); } [Fact] - public async Task GetValueAsync_NullMultipleValue() + public void GetValue_NullMultipleValue() { // Arrange var backingStore = new Dictionary @@ -216,7 +217,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding var valueProvider = GetEnumerableValueProvider(BindingSource.Query, backingStore, culture); // Act - var result = await valueProvider.GetValueAsync("key"); + var result = valueProvider.GetValue("key"); // Assert Assert.Equal(new[] { null, null, "value" }, result.Values); @@ -224,13 +225,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding } [Fact] - public async Task GetValueAsync_ReturnsNullIfKeyNotFound() + public void GetValue_ReturnsNullIfKeyNotFound() { // Arrange var valueProvider = GetEnumerableValueProvider(BindingSource.Query, _backingStore, culture: null); // Act - var result = await valueProvider.GetValueAsync("prefix"); + var result = valueProvider.GetValue("prefix"); // Assert Assert.Equal(ValueProviderResult.None, result); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/FormValueProviderFactoryTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/FormValueProviderFactoryTest.cs index 5ef29bcea4..dffcf21cb4 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/FormValueProviderFactoryTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/FormValueProviderFactoryTest.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.Threading.Tasks; using Microsoft.AspNet.Http.Internal; using Xunit; @@ -12,14 +13,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test public class FormValueProviderFactoryTest { [Fact] - public void GetValueProvider_ReturnsNull_WhenContentTypeIsNotFormUrlEncoded() + public async Task GetValueProviderAsync_ReturnsNull_WhenContentTypeIsNotFormUrlEncoded() { // Arrange var context = CreateContext("some-content-type"); var factory = new FormValueProviderFactory(); // Act - var result = factory.GetValueProvider(context); + var result = await factory.GetValueProviderAsync(context); // Assert Assert.Null(result); @@ -30,14 +31,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test [InlineData("application/x-www-form-urlencoded;charset=utf-8")] [InlineData("multipart/form-data; boundary=----WebKitFormBoundarymx2fSWqWSd0OxQqq")] [InlineData("multipart/form-data; boundary=----WebKitFormBoundarymx2fSWqWSd0OxQqq; charset=utf-8")] - public void GetValueProvider_ReturnsValueProviderInstanceWithCurrentCulture(string contentType) + public async Task GetValueProviderAsync_ReturnsValueProvider_WithCurrentCulture(string contentType) { // Arrange var context = CreateContext(contentType); var factory = new FormValueProviderFactory(); // Act - var result = factory.GetValueProvider(context); + var result = await factory.GetValueProviderAsync(context); // Assert var valueProvider = Assert.IsType(result); @@ -49,6 +50,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test var context = new DefaultHttpContext(); context.Request.ContentType = contentType; + if (context.Request.HasFormContentType) + { + context.Request.Form = new FormCollection(new Dictionary()); + } + return new ValueProviderFactoryContext( context, new Dictionary(StringComparer.OrdinalIgnoreCase)); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/JQueryFormValueProviderFactoryTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/JQueryFormValueProviderFactoryTest.cs index e9de57468e..76fdd6f600 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/JQueryFormValueProviderFactoryTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/JQueryFormValueProviderFactoryTest.cs @@ -37,14 +37,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test }; [Fact] - public void GetValueProvider_ReturnsNull_WhenContentTypeIsNotFormUrlEncoded() + public async Task GetValueProvider_ReturnsNull_WhenContentTypeIsNotFormUrlEncoded() { // Arrange var context = CreateContext("some-content-type", formValues: null); var factory = new JQueryFormValueProviderFactory(); // Act - var result = factory.GetValueProvider(context); + var result = await factory.GetValueProviderAsync(context); // Assert Assert.Null(result); @@ -55,14 +55,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test [InlineData("application/x-www-form-urlencoded;charset=utf-8")] [InlineData("multipart/form-data; boundary=----WebKitFormBoundarymx2fSWqWSd0OxQqq")] [InlineData("multipart/form-data; boundary=----WebKitFormBoundarymx2fSWqWSd0OxQqq; charset=utf-8")] - public void GetValueProvider_ReturnsExpectedValueProviderInstanceWithCurrentCulture(string contentType) + public async Task GetValueProviderAsync_ReturnsValueProvider_WithCurrentCulture(string contentType) { // Arrange var context = CreateContext(contentType, formValues: null); var factory = new JQueryFormValueProviderFactory(); // Act - var result = factory.GetValueProvider(context); + var result = await factory.GetValueProviderAsync(context); // Assert var valueProvider = Assert.IsType(result); @@ -106,8 +106,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test var factory = new JQueryFormValueProviderFactory(); // Act - var valueProvider = factory.GetValueProvider(context); - var result = await valueProvider.GetValueAsync(key); + var valueProvider = await factory.GetValueProviderAsync(context); + var result = valueProvider.GetValue(key); // Assert Assert.Equal("found", (string)result); @@ -119,9 +119,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test { var context = new DefaultHttpContext(); context.Request.ContentType = contentType; - if (formValues != null) + + if (context.Request.HasFormContentType) { - context.Request.Form = new FormCollection(formValues); + context.Request.Form = new FormCollection(formValues ?? new Dictionary()); } return new ValueProviderFactoryContext( diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/MutableObjectModelBinderTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/MutableObjectModelBinderTest.cs index 08c7e95cd6..324286d243 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/MutableObjectModelBinderTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/MutableObjectModelBinderTest.cs @@ -36,7 +36,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding [InlineData(true, false, "prefix", "dummyModelName", true)] [InlineData(false, true, "prefix", "dummyModelName", false)] [InlineData(false, false, "prefix", "dummyModelName", false)] - public async Task CanCreateModel_ReturnsTrue_IfIsTopLevelObjectAndNotIsFirstChanceBinding( + public void CanCreateModel_ReturnsTrue_IfIsTopLevelObjectAndNotIsFirstChanceBinding( bool isTopLevelObject, bool isFirstChanceBinding, string binderModelName, @@ -45,8 +45,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding { var mockValueProvider = new Mock(); mockValueProvider - .Setup(o => o.ContainsPrefixAsync(It.IsAny())) - .Returns(Task.FromResult(false)); + .Setup(o => o.ContainsPrefix(It.IsAny())) + .Returns(false); var metadataProvider = new TestModelMetadataProvider(); var bindingContext = new MutableObjectBinderContext @@ -77,14 +77,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding mutableBinder.GetMetadataForProperties(bindingContext.ModelBindingContext).ToArray(); // Act - var canCreate = await mutableBinder.CanCreateModel(bindingContext); + var canCreate = mutableBinder.CanCreateModel(bindingContext); // Assert Assert.Equal(expectedCanCreate, canCreate); } [Fact] - public async Task CanCreateModel_ReturnsFalse_IfNotIsTopLevelObjectAndModelIsMarkedWithBinderMetadata() + public void CanCreateModel_ReturnsFalse_IfNotIsTopLevelObjectAndModelIsMarkedWithBinderMetadata() { // Get the property metadata so that it is not a top level object. var modelMetadata = GetMetadataForType(typeof(Document)) @@ -107,14 +107,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding var mutableBinder = new MutableObjectModelBinder(); // Act - var canCreate = await mutableBinder.CanCreateModel(bindingContext); + var canCreate = mutableBinder.CanCreateModel(bindingContext); // Assert Assert.False(canCreate); } [Fact] - public async Task CanCreateModel_ReturnsTrue_IfIsTopLevelObjectAndModelIsMarkedWithBinderMetadata() + public void CanCreateModel_ReturnsTrue_IfIsTopLevelObjectAndModelIsMarkedWithBinderMetadata() { var bindingContext = new MutableObjectBinderContext { @@ -134,18 +134,19 @@ namespace Microsoft.AspNet.Mvc.ModelBinding var mutableBinder = new MutableObjectModelBinder(); // Act - var canCreate = await mutableBinder.CanCreateModel(bindingContext); + var canCreate = mutableBinder.CanCreateModel(bindingContext); // Assert Assert.True(canCreate); } [Fact] - public async Task CanCreateModel_CreatesModel_IfTheModelIsBinderPoco() + public void CanCreateModel_CreatesModel_IfTheModelIsBinderPoco() { var mockValueProvider = new Mock(); - mockValueProvider.Setup(o => o.ContainsPrefixAsync(It.IsAny())) - .Returns(Task.FromResult(false)); + mockValueProvider + .Setup(o => o.ContainsPrefix(It.IsAny())) + .Returns(false); var bindingContext = new MutableObjectBinderContext { @@ -170,23 +171,23 @@ namespace Microsoft.AspNet.Mvc.ModelBinding mutableBinder.GetMetadataForProperties(bindingContext.ModelBindingContext).ToArray(); // Act - var retModel = await mutableBinder.CanCreateModel(bindingContext); + var canCreate = mutableBinder.CanCreateModel(bindingContext); // Assert - Assert.True(retModel); + Assert.True(canCreate); } [Theory] [InlineData(true)] [InlineData(false)] - public async Task CanCreateModel_ReturnsTrue_IfNotIsTopLevelObject_BasedOnValueAvailability( + public void CanCreateModel_ReturnsTrue_IfNotIsTopLevelObject_BasedOnValueAvailability( bool valueAvailable) { // Arrange var mockValueProvider = new Mock(MockBehavior.Strict); mockValueProvider - .Setup(provider => provider.ContainsPrefixAsync("SimpleContainer.Simple.Name")) - .Returns(Task.FromResult(valueAvailable)); + .Setup(provider => provider.ContainsPrefix("SimpleContainer.Simple.Name")) + .Returns(valueAvailable); var typeMetadata = GetMetadataForType(typeof(SimpleContainer)); var modelMetadata = typeMetadata.Properties[nameof(SimpleContainer.Simple)]; @@ -210,15 +211,15 @@ namespace Microsoft.AspNet.Mvc.ModelBinding var mutableBinder = new MutableObjectModelBinder(); // Act - var result = await mutableBinder.CanCreateModel(bindingContext); + var canCreate = mutableBinder.CanCreateModel(bindingContext); // Assert // Result matches whether first Simple property can bind. - Assert.Equal(valueAvailable, result); + Assert.Equal(valueAvailable, canCreate); } [Fact] - public async Task CanCreateModel_ReturnsFalse_IfNotIsTopLevelObjectAndModelHasNoProperties() + public void CanCreateModel_ReturnsFalse_IfNotIsTopLevelObjectAndModelHasNoProperties() { // Arrange var bindingContext = new MutableObjectBinderContext @@ -236,14 +237,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding mutableBinder.GetMetadataForProperties(bindingContext.ModelBindingContext).ToArray(); // Act - var canCreate = await mutableBinder.CanCreateModel(bindingContext); + var canCreate = mutableBinder.CanCreateModel(bindingContext); // Assert Assert.False(canCreate); } [Fact] - public async Task CanCreateModel_ReturnsTrue_IfIsTopLevelObjectAndModelHasNoProperties() + public void CanCreateModel_ReturnsTrue_IfIsTopLevelObjectAndModelHasNoProperties() { // Arrange var bindingContext = new MutableObjectBinderContext @@ -260,10 +261,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding mutableBinder.GetMetadataForProperties(bindingContext.ModelBindingContext).ToArray(); // Act - var retModel = await mutableBinder.CanCreateModel(bindingContext); + var canCreate = mutableBinder.CanCreateModel(bindingContext); // Assert - Assert.True(retModel); + Assert.True(canCreate); } [Theory] @@ -273,13 +274,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding [InlineData(typeof(TypeWithAtLeastOnePropertyMarkedUsingValueBinderMetadata), true)] [InlineData(typeof(TypeWithUnmarkedAndBinderMetadataMarkedProperties), false)] [InlineData(typeof(TypeWithUnmarkedAndBinderMetadataMarkedProperties), true)] - public async Task - CanCreateModel_CreatesModelForValueProviderBasedBinderMetadatas_IfAValueProviderProvidesValue - (Type modelType, bool valueProviderProvidesValue) + public void CanCreateModel_CreatesModelForValueProviderBasedBinderMetadatas_IfAValueProviderProvidesValue( + Type modelType, + bool valueProviderProvidesValue) { var mockValueProvider = new Mock(); - mockValueProvider.Setup(o => o.ContainsPrefixAsync(It.IsAny())) - .Returns(Task.FromResult(valueProviderProvidesValue)); + mockValueProvider.Setup(o => o.ContainsPrefix(It.IsAny())) + .Returns(valueProviderProvidesValue); var bindingContext = new MutableObjectBinderContext { @@ -303,27 +304,28 @@ namespace Microsoft.AspNet.Mvc.ModelBinding mutableBinder.GetMetadataForProperties(bindingContext.ModelBindingContext).ToArray(); // Act - var retModel = await mutableBinder.CanCreateModel(bindingContext); + var canCreate = mutableBinder.CanCreateModel(bindingContext); // Assert - Assert.Equal(valueProviderProvidesValue, retModel); + Assert.Equal(valueProviderProvidesValue, canCreate); } [Theory] [InlineData(typeof(TypeWithAtLeastOnePropertyMarkedUsingValueBinderMetadata), false)] [InlineData(typeof(TypeWithAtLeastOnePropertyMarkedUsingValueBinderMetadata), true)] - public async Task CanCreateModel_ForExplicitValueProviderMetadata_UsesOriginalValueProvider( + public void CanCreateModel_ForExplicitValueProviderMetadata_UsesOriginalValueProvider( Type modelType, bool originalValueProviderProvidesValue) { var mockValueProvider = new Mock(); - mockValueProvider.Setup(o => o.ContainsPrefixAsync(It.IsAny())) - .Returns(Task.FromResult(false)); + mockValueProvider + .Setup(o => o.ContainsPrefix(It.IsAny())) + .Returns(false); var mockOriginalValueProvider = new Mock(); mockOriginalValueProvider - .Setup(o => o.ContainsPrefixAsync(It.IsAny())) - .Returns(Task.FromResult(originalValueProviderProvidesValue)); + .Setup(o => o.ContainsPrefix(It.IsAny())) + .Returns(originalValueProviderProvidesValue); mockOriginalValueProvider .Setup(o => o.Filter(It.IsAny())) @@ -363,10 +365,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding mutableBinder.GetMetadataForProperties(bindingContext.ModelBindingContext).ToArray(); // Act - var retModel = await mutableBinder.CanCreateModel(bindingContext); + var canCreate = mutableBinder.CanCreateModel(bindingContext); // Assert - Assert.Equal(originalValueProviderProvidesValue, retModel); + Assert.Equal(originalValueProviderProvidesValue, canCreate); } [Theory] @@ -374,17 +376,17 @@ namespace Microsoft.AspNet.Mvc.ModelBinding [InlineData(typeof(TypeWithUnmarkedAndBinderMetadataMarkedProperties), true)] [InlineData(typeof(TypeWithNoBinderMetadata), false)] [InlineData(typeof(TypeWithNoBinderMetadata), true)] - public async Task CanCreateModel_UnmarkedProperties_UsesCurrentValueProvider( + public void CanCreateModel_UnmarkedProperties_UsesCurrentValueProvider( Type modelType, bool valueProviderProvidesValue) { var mockValueProvider = new Mock(); - mockValueProvider.Setup(o => o.ContainsPrefixAsync(It.IsAny())) - .Returns(Task.FromResult(valueProviderProvidesValue)); + mockValueProvider.Setup(o => o.ContainsPrefix(It.IsAny())) + .Returns(valueProviderProvidesValue); var mockOriginalValueProvider = new Mock(); - mockOriginalValueProvider.Setup(o => o.ContainsPrefixAsync(It.IsAny())) - .Returns(Task.FromResult(false)); + mockOriginalValueProvider.Setup(o => o.ContainsPrefix(It.IsAny())) + .Returns(false); var bindingContext = new MutableObjectBinderContext { @@ -408,10 +410,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding mutableBinder.GetMetadataForProperties(bindingContext.ModelBindingContext).ToArray(); // Act - var retModel = await mutableBinder.CanCreateModel(bindingContext); + var canCreate = mutableBinder.CanCreateModel(bindingContext); // Assert - Assert.Equal(valueProviderProvidesValue, retModel); + Assert.Equal(valueProviderProvidesValue, canCreate); } [Fact] @@ -420,8 +422,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding // Arrange var mockValueProvider = new Mock(); mockValueProvider - .Setup(o => o.ContainsPrefixAsync(It.IsAny())) - .Returns(Task.FromResult(true)); + .Setup(o => o.ContainsPrefix(It.IsAny())) + .Returns(true); // Mock binder fails to bind all properties. var mockBinder = new Mock(); @@ -470,8 +472,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding // Arrange var mockValueProvider = new Mock(); mockValueProvider - .Setup(o => o.ContainsPrefixAsync(It.IsAny())) - .Returns(Task.FromResult(false)); + .Setup(o => o.ContainsPrefix(It.IsAny())) + .Returns(false); // Mock binder fails to bind all properties. var mockBinder = new Mock(); @@ -567,10 +569,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding var testableBinder = new TestableMutableObjectModelBinder(); // Act - var retModel = testableBinder.CreateModelPublic(bindingContext); + var model = testableBinder.CreateModelPublic(bindingContext); // Assert - Assert.IsType(retModel); + Assert.IsType(model); } [Fact] diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/QueryStringValueProviderFactoryTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/QueryStringValueProviderFactoryTest.cs index 28657621f0..ecf753cb1d 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/QueryStringValueProviderFactoryTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/QueryStringValueProviderFactoryTest.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.Threading.Tasks; using Microsoft.AspNet.Http; using Moq; using Xunit; @@ -18,7 +19,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test #if DNX451 [Fact] - public void GetValueProvider_ReturnsQueryStringValueProviderInstanceWithInvariantCulture() + public async Task GetValueProvider_ReturnsQueryStringValueProviderInstanceWithInvariantCulture() { // Arrange var request = new Mock(); @@ -31,7 +32,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test new Dictionary(StringComparer.OrdinalIgnoreCase)); // Act - var result = _factory.GetValueProvider(factoryContext); + var result = await _factory.GetValueProviderAsync(factoryContext); // Assert var valueProvider = Assert.IsType(result); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/SimpleValueProvider.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/SimpleValueProvider.cs index 1570b22b42..4fc0a4c856 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/SimpleValueProvider.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ModelBinding/SimpleValueProvider.cs @@ -23,44 +23,21 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test _culture = culture ?? CultureInfo.InvariantCulture; } - // copied from ValueProviderUtil - public Task ContainsPrefixAsync(string prefix) + public bool ContainsPrefix(string prefix) { foreach (string key in Keys) { - if (key != null) + if (PrefixContainer.IsPrefixMatch(prefix, key)) { - if (prefix.Length == 0) - { - return Task.FromResult(true); // shortcut - non-null key matches empty prefix - } - - if (key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) - { - if (key.Length == prefix.Length) - { - return Task.FromResult(true); // exact match - } - else - { - switch (key[prefix.Length]) - { - case '.': // known separator characters - case '[': - return Task.FromResult(true); - } - } - } + return true; } } - return Task.FromResult(false); // nothing found + return false; } - public Task GetValueAsync(string key) + public ValueProviderResult GetValue(string key) { - ValueProviderResult result = ValueProviderResult.None; - object rawValue; if (TryGetValue(key, out rawValue)) { @@ -74,16 +51,16 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test stringValues[i] = array.GetValue(i) as string ?? Convert.ToString(array.GetValue(i), _culture); } - result = new ValueProviderResult(stringValues, _culture); + return new ValueProviderResult(stringValues, _culture); } else { var stringValue = rawValue as string ?? Convert.ToString(rawValue, _culture) ?? string.Empty; - result = new ValueProviderResult(stringValue, _culture); + return new ValueProviderResult(stringValue, _culture); } } - return Task.FromResult(result); + return ValueProviderResult.None; } } } diff --git a/test/Microsoft.AspNet.Mvc.IntegrationTests/ModelBindingTestHelper.cs b/test/Microsoft.AspNet.Mvc.IntegrationTests/ModelBindingTestHelper.cs index a7fe7139e4..be6c7432a7 100644 --- a/test/Microsoft.AspNet.Mvc.IntegrationTests/ModelBindingTestHelper.cs +++ b/test/Microsoft.AspNet.Mvc.IntegrationTests/ModelBindingTestHelper.cs @@ -97,9 +97,9 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests actionContext.HttpContext, actionContext.RouteData.Values); - var valueProvider = CompositeValueProvider.Create( + var valueProvider = CompositeValueProvider.CreateAsync( options.ValueProviderFactories, - valueProviderFactoryContext); + valueProviderFactoryContext).Result; return new ActionBindingContext() { diff --git a/test/WebSites/ModelBindingWebSite/Controllers/ModelBinderAttribute_ProductController.cs b/test/WebSites/ModelBindingWebSite/Controllers/ModelBinderAttribute_ProductController.cs index 309b2502b0..1dce9b2a7d 100644 --- a/test/WebSites/ModelBindingWebSite/Controllers/ModelBinderAttribute_ProductController.cs +++ b/test/WebSites/ModelBindingWebSite/Controllers/ModelBinderAttribute_ProductController.cs @@ -85,7 +85,7 @@ namespace ModelBindingWebSite.Controllers private class ProductModelBinder : IModelBinder { - public async Task BindModelAsync(ModelBindingContext bindingContext) + public Task BindModelAsync(ModelBindingContext bindingContext) { if (typeof(Product).IsAssignableFrom(bindingContext.ModelType)) { @@ -97,16 +97,16 @@ namespace ModelBindingWebSite.Controllers string.IsNullOrEmpty(bindingContext.ModelName) ? "productId" : bindingContext.ModelName + "." + "productId"; - - var value = await bindingContext.ValueProvider.GetValueAsync(key); + + var value = bindingContext.ValueProvider.GetValue(key); model.ProductId = value.ConvertTo(); var validationNode = new ModelValidationNode(bindingContext.ModelName, bindingContext.ModelMetadata, value); - return new ModelBindingResult(model, key, true, validationNode); + return Task.FromResult(new ModelBindingResult(model, key, true, validationNode)); } - return null; + return Task.FromResult(null); } } } diff --git a/test/WebSites/ModelBindingWebSite/Controllers/TryUpdateModelController.cs b/test/WebSites/ModelBindingWebSite/Controllers/TryUpdateModelController.cs index e37f0ac8f4..6ea38ecbe9 100644 --- a/test/WebSites/ModelBindingWebSite/Controllers/TryUpdateModelController.cs +++ b/test/WebSites/ModelBindingWebSite/Controllers/TryUpdateModelController.cs @@ -211,14 +211,14 @@ namespace ModelBindingWebSite.Controllers public class CustomValueProvider : IValueProvider { - public Task ContainsPrefixAsync(string prefix) + public bool ContainsPrefix(string prefix) { - return Task.FromResult(false); + return false; } - public Task GetValueAsync(string key) + public ValueProviderResult GetValue(string key) { - return Task.FromResult(ValueProviderResult.None); + return ValueProviderResult.None; } } } diff --git a/test/WebSites/ValueProvidersWebSite/CustomValueProviderFactory.cs b/test/WebSites/ValueProvidersWebSite/CustomValueProviderFactory.cs index f41657ff43..d4b87904a0 100644 --- a/test/WebSites/ValueProvidersWebSite/CustomValueProviderFactory.cs +++ b/test/WebSites/ValueProvidersWebSite/CustomValueProviderFactory.cs @@ -10,29 +10,27 @@ namespace ValueProvidersWebSite { public class CustomValueProviderFactory : IValueProviderFactory { - public IValueProvider GetValueProvider(ValueProviderFactoryContext context) + public Task GetValueProviderAsync(ValueProviderFactoryContext context) { if (context.HttpContext.Request.Path.Value.Contains("TestValueProvider")) { - return new CustomValueProvider(); + return Task.FromResult(new CustomValueProvider()); } - return null; + return Task.FromResult(null); } private class CustomValueProvider : IValueProvider { - public Task ContainsPrefixAsync(string prefix) + public bool ContainsPrefix(string prefix) { - var result = string.Equals(prefix, "test", StringComparison.OrdinalIgnoreCase); - return Task.FromResult(result); + return string.Equals(prefix, "test", StringComparison.OrdinalIgnoreCase); } - public Task GetValueAsync(string key) + public ValueProviderResult GetValue(string key) { var value = "custom-value-provider-value"; - var result = new ValueProviderResult(value, CultureInfo.CurrentCulture); - return Task.FromResult(result); + return new ValueProviderResult(value, CultureInfo.CurrentCulture); } } }