Make IModelBinder and IValueProvider methods async
This commit is contained in:
parent
d46389888d
commit
b0c7dc9220
|
|
@ -78,7 +78,7 @@ namespace Microsoft.AspNet.Mvc
|
||||||
|
|
||||||
foreach (var parameter in action.Parameters.Where(p => p.ParameterBindingInfo != null))
|
foreach (var parameter in action.Parameters.Where(p => p.ParameterBindingInfo != null))
|
||||||
{
|
{
|
||||||
if (actionBindingContext.ValueProvider.ContainsPrefix(parameter.ParameterBindingInfo.Prefix))
|
if (await actionBindingContext.ValueProvider.ContainsPrefixAsync(parameter.ParameterBindingInfo.Prefix))
|
||||||
{
|
{
|
||||||
candidate.FoundParameters++;
|
candidate.FoundParameters++;
|
||||||
if (parameter.IsOptional)
|
if (parameter.IsOptional)
|
||||||
|
|
|
||||||
|
|
@ -278,7 +278,7 @@ namespace Microsoft.AspNet.Mvc
|
||||||
HttpContext = actionBindingContext.ActionContext.HttpContext,
|
HttpContext = actionBindingContext.ActionContext.HttpContext,
|
||||||
FallbackToEmptyPrefix = true
|
FallbackToEmptyPrefix = true
|
||||||
};
|
};
|
||||||
actionBindingContext.ModelBinder.BindModel(modelBindingContext);
|
await actionBindingContext.ModelBinder.BindModelAsync(modelBindingContext);
|
||||||
parameterValues[parameter.Name] = modelBindingContext.Model;
|
parameterValues[parameter.Name] = modelBindingContext.Model;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,19 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
public class ArrayModelBinder<TElement> : CollectionModelBinder<TElement>
|
public class ArrayModelBinder<TElement> : CollectionModelBinder<TElement>
|
||||||
{
|
{
|
||||||
public override bool BindModel(ModelBindingContext bindingContext)
|
public override Task<bool> BindModelAsync(ModelBindingContext bindingContext)
|
||||||
{
|
{
|
||||||
if (bindingContext.ModelMetadata.IsReadOnly)
|
if (bindingContext.ModelMetadata.IsReadOnly)
|
||||||
{
|
{
|
||||||
return false;
|
return Task.FromResult(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return base.BindModel(bindingContext);
|
return base.BindModelAsync(bindingContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool CreateOrReplaceCollection(ModelBindingContext bindingContext, IList<TElement> newCollection)
|
protected override bool CreateOrReplaceCollection(ModelBindingContext bindingContext, IList<TElement> newCollection)
|
||||||
|
|
|
||||||
|
|
@ -3,36 +3,36 @@ using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding.Internal;
|
using Microsoft.AspNet.Mvc.ModelBinding.Internal;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
public class CollectionModelBinder<TElement> : IModelBinder
|
public class CollectionModelBinder<TElement> : IModelBinder
|
||||||
{
|
{
|
||||||
public virtual bool BindModel(ModelBindingContext bindingContext)
|
public virtual async Task<bool> BindModelAsync(ModelBindingContext bindingContext)
|
||||||
{
|
{
|
||||||
ModelBindingHelper.ValidateBindingContext(bindingContext);
|
ModelBindingHelper.ValidateBindingContext(bindingContext);
|
||||||
|
|
||||||
if (!bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName))
|
if (!await bindingContext.ValueProvider.ContainsPrefixAsync(bindingContext.ModelName))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueProviderResult valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
|
var valueProviderResult = await bindingContext.ValueProvider.GetValueAsync(bindingContext.ModelName);
|
||||||
List<TElement> boundCollection = (valueProviderResult != null)
|
var boundCollection = await ((valueProviderResult != null) ?
|
||||||
? BindSimpleCollection(bindingContext, valueProviderResult.RawValue, valueProviderResult.Culture)
|
BindSimpleCollection(bindingContext, valueProviderResult.RawValue, valueProviderResult.Culture) :
|
||||||
: BindComplexCollection(bindingContext);
|
BindComplexCollection(bindingContext));
|
||||||
|
|
||||||
bool retVal = CreateOrReplaceCollection(bindingContext, boundCollection);
|
return CreateOrReplaceCollection(bindingContext, boundCollection);
|
||||||
return retVal;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Make this method internal
|
// TODO: Make this method internal
|
||||||
// Used when the ValueProvider contains the collection to be bound as a single element, e.g. the raw value
|
// Used when the ValueProvider contains the collection to be bound as a single element, e.g. the raw value
|
||||||
// is [ "1", "2" ] and needs to be converted to an int[].
|
// is [ "1", "2" ] and needs to be converted to an int[].
|
||||||
public List<TElement> BindSimpleCollection(ModelBindingContext bindingContext,
|
public async Task<List<TElement>> BindSimpleCollection(ModelBindingContext bindingContext,
|
||||||
object rawValue,
|
object rawValue,
|
||||||
CultureInfo culture)
|
CultureInfo culture)
|
||||||
{
|
{
|
||||||
if (rawValue == null)
|
if (rawValue == null)
|
||||||
{
|
{
|
||||||
|
|
@ -57,7 +57,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
};
|
};
|
||||||
|
|
||||||
object boundValue = null;
|
object boundValue = null;
|
||||||
if (bindingContext.ModelBinder.BindModel(innerBindingContext))
|
if (await bindingContext.ModelBinder.BindModelAsync(innerBindingContext))
|
||||||
{
|
{
|
||||||
boundValue = innerBindingContext.Model;
|
boundValue = innerBindingContext.Model;
|
||||||
bindingContext.ValidationNode.ChildNodes.Add(innerBindingContext.ValidationNode);
|
bindingContext.ValidationNode.ChildNodes.Add(innerBindingContext.ValidationNode);
|
||||||
|
|
@ -69,17 +69,17 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used when the ValueProvider contains the collection to be bound as multiple elements, e.g. foo[0], foo[1].
|
// Used when the ValueProvider contains the collection to be bound as multiple elements, e.g. foo[0], foo[1].
|
||||||
private List<TElement> BindComplexCollection(ModelBindingContext bindingContext)
|
private async Task<List<TElement>> BindComplexCollection(ModelBindingContext bindingContext)
|
||||||
{
|
{
|
||||||
string indexPropertyName = ModelBindingHelper.CreatePropertyModelName(bindingContext.ModelName, "index");
|
string indexPropertyName = ModelBindingHelper.CreatePropertyModelName(bindingContext.ModelName, "index");
|
||||||
ValueProviderResult valueProviderResultIndex = bindingContext.ValueProvider.GetValue(indexPropertyName);
|
ValueProviderResult valueProviderResultIndex = await bindingContext.ValueProvider.GetValueAsync(indexPropertyName);
|
||||||
IEnumerable<string> indexNames = CollectionModelBinderUtil.GetIndexNamesFromValueProviderResult(valueProviderResultIndex);
|
IEnumerable<string> indexNames = CollectionModelBinderUtil.GetIndexNamesFromValueProviderResult(valueProviderResultIndex);
|
||||||
return BindComplexCollectionFromIndexes(bindingContext, indexNames);
|
return await BindComplexCollectionFromIndexes(bindingContext, indexNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Convert to internal
|
// TODO: Convert to internal
|
||||||
public List<TElement> BindComplexCollectionFromIndexes(ModelBindingContext bindingContext,
|
public async Task<List<TElement>> BindComplexCollectionFromIndexes(ModelBindingContext bindingContext,
|
||||||
IEnumerable<string> indexNames)
|
IEnumerable<string> indexNames)
|
||||||
{
|
{
|
||||||
bool indexNamesIsFinite;
|
bool indexNamesIsFinite;
|
||||||
if (indexNames != null)
|
if (indexNames != null)
|
||||||
|
|
@ -108,7 +108,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
|
|
||||||
Type modelType = bindingContext.ModelType;
|
Type modelType = bindingContext.ModelType;
|
||||||
|
|
||||||
if (bindingContext.ModelBinder.BindModel(childBindingContext))
|
if (await bindingContext.ModelBinder.BindModelAsync(childBindingContext))
|
||||||
{
|
{
|
||||||
didBind = true;
|
didBind = true;
|
||||||
boundValue = childBindingContext.Model;
|
boundValue = childBindingContext.Model;
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding.Internal;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Mvc.ModelBinding.Internal;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
public sealed class ComplexModelDtoModelBinder : IModelBinder
|
public sealed class ComplexModelDtoModelBinder : IModelBinder
|
||||||
{
|
{
|
||||||
public bool BindModel(ModelBindingContext bindingContext)
|
public async Task<bool> BindModelAsync(ModelBindingContext bindingContext)
|
||||||
{
|
{
|
||||||
if (bindingContext.ModelType == typeof(ComplexModelDto))
|
if (bindingContext.ModelType == typeof(ComplexModelDto))
|
||||||
{
|
{
|
||||||
|
|
@ -21,8 +22,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
|
|
||||||
// bind and propagate the values
|
// bind and propagate the values
|
||||||
// If we can't bind, then leave the result missing (don't add a null).
|
// If we can't bind, then leave the result missing (don't add a null).
|
||||||
|
if (await bindingContext.ModelBinder.BindModelAsync(propertyBindingContext))
|
||||||
if (bindingContext.ModelBinder.BindModel(propertyBindingContext))
|
|
||||||
{
|
{
|
||||||
dto.Results[propertyMetadata] = new ComplexModelDtoResult(propertyBindingContext.Model, propertyBindingContext.ValidationNode);
|
dto.Results[propertyMetadata] = new ComplexModelDtoResult(propertyBindingContext.Model, propertyBindingContext.ValidationNode);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
|
|
@ -26,13 +27,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
|
|
||||||
private IModelBinder[] Binders { get; set; }
|
private IModelBinder[] Binders { get; set; }
|
||||||
|
|
||||||
public virtual bool BindModel(ModelBindingContext bindingContext)
|
public virtual async Task<bool> BindModelAsync(ModelBindingContext bindingContext)
|
||||||
{
|
{
|
||||||
var newBindingContext = CreateNewBindingContext(bindingContext,
|
var newBindingContext = CreateNewBindingContext(bindingContext,
|
||||||
bindingContext.ModelName,
|
bindingContext.ModelName,
|
||||||
reuseValidationNode: true);
|
reuseValidationNode: true);
|
||||||
|
|
||||||
bool boundSuccessfully = TryBind(newBindingContext);
|
var boundSuccessfully = await TryBind(newBindingContext);
|
||||||
if (!boundSuccessfully && !string.IsNullOrEmpty(bindingContext.ModelName)
|
if (!boundSuccessfully && !string.IsNullOrEmpty(bindingContext.ModelName)
|
||||||
&& bindingContext.FallbackToEmptyPrefix)
|
&& bindingContext.FallbackToEmptyPrefix)
|
||||||
{
|
{
|
||||||
|
|
@ -40,7 +41,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
newBindingContext = CreateNewBindingContext(bindingContext,
|
newBindingContext = CreateNewBindingContext(bindingContext,
|
||||||
modelName: string.Empty,
|
modelName: string.Empty,
|
||||||
reuseValidationNode: false);
|
reuseValidationNode: false);
|
||||||
boundSuccessfully = TryBind(newBindingContext);
|
boundSuccessfully = await TryBind(newBindingContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!boundSuccessfully)
|
if (!boundSuccessfully)
|
||||||
|
|
@ -68,7 +69,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool TryBind([NotNull] ModelBindingContext bindingContext)
|
private async Task<bool> TryBind([NotNull] ModelBindingContext bindingContext)
|
||||||
{
|
{
|
||||||
// TODO: RuntimeHelpers.EnsureSufficientExecutionStack does not exist in the CoreCLR.
|
// TODO: RuntimeHelpers.EnsureSufficientExecutionStack does not exist in the CoreCLR.
|
||||||
// Protects against stack overflow for deeply nested model binding
|
// Protects against stack overflow for deeply nested model binding
|
||||||
|
|
@ -76,7 +77,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
|
|
||||||
foreach (var binder in Binders)
|
foreach (var binder in Binders)
|
||||||
{
|
{
|
||||||
if (binder.BindModel(bindingContext))
|
if (await binder.BindModelAsync(bindingContext))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.Contracts;
|
using System.Diagnostics.Contracts;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.DependencyInjection;
|
using Microsoft.AspNet.DependencyInjection;
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding.Internal;
|
using Microsoft.AspNet.Mvc.ModelBinding.Internal;
|
||||||
|
|
||||||
|
|
@ -18,16 +19,16 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
_activator = activator;
|
_activator = activator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool BindModel(ModelBindingContext bindingContext)
|
public Task<bool> BindModelAsync(ModelBindingContext bindingContext)
|
||||||
{
|
{
|
||||||
Type binderType = ResolveBinderType(bindingContext.ModelType);
|
Type binderType = ResolveBinderType(bindingContext.ModelType);
|
||||||
if (binderType != null)
|
if (binderType != null)
|
||||||
{
|
{
|
||||||
var binder = (IModelBinder)_activator.CreateInstance(_serviceProvider, binderType);
|
var binder = (IModelBinder)_activator.CreateInstance(_serviceProvider, binderType);
|
||||||
return binder.BindModel(bindingContext);
|
return binder.BindModelAsync(bindingContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return Task.FromResult(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Type ResolveBinderType(Type modelType)
|
private static Type ResolveBinderType(Type modelType)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using Microsoft.AspNet.Abstractions;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
|
|
@ -7,6 +7,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IModelBinder
|
public interface IModelBinder
|
||||||
{
|
{
|
||||||
bool BindModel(ModelBindingContext bindingContext);
|
Task<bool> BindModelAsync(ModelBindingContext bindingContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,31 +1,28 @@
|
||||||
using System.Collections.Generic;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding.Internal;
|
using Microsoft.AspNet.Mvc.ModelBinding.Internal;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
public sealed class KeyValuePairModelBinder<TKey, TValue> : IModelBinder
|
public sealed class KeyValuePairModelBinder<TKey, TValue> : IModelBinder
|
||||||
{
|
{
|
||||||
public bool BindModel(ModelBindingContext bindingContext)
|
public async Task<bool> BindModelAsync(ModelBindingContext bindingContext)
|
||||||
{
|
{
|
||||||
ModelBindingHelper.ValidateBindingContext(bindingContext, typeof(KeyValuePair<TKey, TValue>), allowNullModel: true);
|
ModelBindingHelper.ValidateBindingContext(bindingContext, typeof(KeyValuePair<TKey, TValue>), allowNullModel: true);
|
||||||
|
|
||||||
TKey key;
|
var keyResult = await TryBindStrongModel<TKey>(bindingContext, "key");
|
||||||
bool keyBindingSucceeded = TryBindStrongModel(bindingContext, "key", out key);
|
var valueResult = await TryBindStrongModel<TValue>(bindingContext, "value");
|
||||||
|
|
||||||
TValue value;
|
if (keyResult.Success && valueResult.Success)
|
||||||
bool valueBindingSucceeded = TryBindStrongModel(bindingContext, "value", out value);
|
|
||||||
|
|
||||||
if (keyBindingSucceeded && valueBindingSucceeded)
|
|
||||||
{
|
{
|
||||||
bindingContext.Model = new KeyValuePair<TKey, TValue>(key, value);
|
bindingContext.Model = new KeyValuePair<TKey, TValue>(keyResult.Model, valueResult.Model);
|
||||||
}
|
}
|
||||||
return keyBindingSucceeded || valueBindingSucceeded;
|
return keyResult.Success || valueResult.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Make this internal
|
internal async Task<BindResult<TModel>> TryBindStrongModel<TModel>(ModelBindingContext parentBindingContext,
|
||||||
public bool TryBindStrongModel<TModel>(ModelBindingContext parentBindingContext,
|
string propertyName)
|
||||||
string propertyName,
|
|
||||||
out TModel model)
|
|
||||||
{
|
{
|
||||||
ModelBindingContext propertyBindingContext = new ModelBindingContext(parentBindingContext)
|
ModelBindingContext propertyBindingContext = new ModelBindingContext(parentBindingContext)
|
||||||
{
|
{
|
||||||
|
|
@ -33,16 +30,28 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
ModelName = ModelBindingHelper.CreatePropertyModelName(parentBindingContext.ModelName, propertyName)
|
ModelName = ModelBindingHelper.CreatePropertyModelName(parentBindingContext.ModelName, propertyName)
|
||||||
};
|
};
|
||||||
|
|
||||||
if (propertyBindingContext.ModelBinder.BindModel(propertyBindingContext))
|
if (await propertyBindingContext.ModelBinder.BindModelAsync(propertyBindingContext))
|
||||||
{
|
{
|
||||||
object untypedModel = propertyBindingContext.Model;
|
object untypedModel = propertyBindingContext.Model;
|
||||||
model = ModelBindingHelper.CastOrDefault<TModel>(untypedModel);
|
var model = ModelBindingHelper.CastOrDefault<TModel>(untypedModel);
|
||||||
parentBindingContext.ValidationNode.ChildNodes.Add(propertyBindingContext.ValidationNode);
|
parentBindingContext.ValidationNode.ChildNodes.Add(propertyBindingContext.ValidationNode);
|
||||||
return true;
|
return new BindResult<TModel>(true, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
model = default(TModel);
|
return new BindResult<TModel>(false, default(TModel));
|
||||||
return false;
|
}
|
||||||
|
|
||||||
|
internal sealed class BindResult<TModel>
|
||||||
|
{
|
||||||
|
public BindResult(bool success, TModel model)
|
||||||
|
{
|
||||||
|
Success = success;
|
||||||
|
Model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Success { get; private set; }
|
||||||
|
|
||||||
|
public TModel Model { get; private set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,18 +4,19 @@ using System.ComponentModel;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding.Internal;
|
using Microsoft.AspNet.Mvc.ModelBinding.Internal;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
public class MutableObjectModelBinder : IModelBinder
|
public class MutableObjectModelBinder : IModelBinder
|
||||||
{
|
{
|
||||||
public virtual bool BindModel(ModelBindingContext bindingContext)
|
public virtual async Task<bool> BindModelAsync(ModelBindingContext bindingContext)
|
||||||
{
|
{
|
||||||
ModelBindingHelper.ValidateBindingContext(bindingContext);
|
ModelBindingHelper.ValidateBindingContext(bindingContext);
|
||||||
|
|
||||||
if (!CanBindType(bindingContext.ModelType) ||
|
if (!CanBindType(bindingContext.ModelType) ||
|
||||||
!bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName))
|
!await bindingContext.ValueProvider.ContainsPrefixAsync(bindingContext.ModelName))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -94,7 +95,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
ModelName = bindingContext.ModelName
|
ModelName = bindingContext.ModelName
|
||||||
};
|
};
|
||||||
|
|
||||||
bindingContext.ModelBinder.BindModel(dtoBindingContext);
|
bindingContext.ModelBinder.BindModelAsync(dtoBindingContext);
|
||||||
return (ComplexModelDto)dtoBindingContext.Model;
|
return (ComplexModelDto)dtoBindingContext.Model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,13 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Diagnostics.Contracts;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding.Internal;
|
using Microsoft.AspNet.Mvc.ModelBinding.Internal;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
public sealed class TypeConverterModelBinder : IModelBinder
|
public sealed class TypeConverterModelBinder : IModelBinder
|
||||||
{
|
{
|
||||||
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "The exception is recorded to be acted upon later.")]
|
public async Task<bool> BindModelAsync(ModelBindingContext bindingContext)
|
||||||
[SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.Web.Http.ValueProviders.ValueProviderResult.ConvertTo(System.Type)", Justification = "The ValueProviderResult already has the necessary context to perform a culture-aware conversion.")]
|
|
||||||
public bool BindModel(ModelBindingContext bindingContext)
|
|
||||||
{
|
{
|
||||||
ModelBindingHelper.ValidateBindingContext(bindingContext);
|
ModelBindingHelper.ValidateBindingContext(bindingContext);
|
||||||
|
|
||||||
|
|
@ -19,7 +17,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
|
var valueProviderResult = await bindingContext.ValueProvider.GetValueAsync(bindingContext.ModelName);
|
||||||
if (valueProviderResult == null)
|
if (valueProviderResult == null)
|
||||||
{
|
{
|
||||||
return false; // no entry
|
return false; // no entry
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding.Internal;
|
using Microsoft.AspNet.Mvc.ModelBinding.Internal;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
public sealed class TypeMatchModelBinder : IModelBinder
|
public sealed class TypeMatchModelBinder : IModelBinder
|
||||||
{
|
{
|
||||||
public bool BindModel(ModelBindingContext bindingContext)
|
public async Task<bool> BindModelAsync(ModelBindingContext bindingContext)
|
||||||
{
|
{
|
||||||
ValueProviderResult valueProviderResult = GetCompatibleValueProviderResult(bindingContext);
|
ValueProviderResult valueProviderResult = await GetCompatibleValueProviderResult(bindingContext);
|
||||||
if (valueProviderResult == null)
|
if (valueProviderResult == null)
|
||||||
{
|
{
|
||||||
// conversion would have failed
|
// conversion would have failed
|
||||||
|
|
@ -23,11 +24,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static ValueProviderResult GetCompatibleValueProviderResult(ModelBindingContext bindingContext)
|
internal static async Task<ValueProviderResult> GetCompatibleValueProviderResult(ModelBindingContext bindingContext)
|
||||||
{
|
{
|
||||||
ModelBindingHelper.ValidateBindingContext(bindingContext);
|
ModelBindingHelper.ValidateBindingContext(bindingContext);
|
||||||
|
|
||||||
ValueProviderResult valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
|
var valueProviderResult = await bindingContext.ValueProvider.GetValueAsync(bindingContext.ModelName);
|
||||||
if (valueProviderResult == null)
|
if (valueProviderResult == null)
|
||||||
{
|
{
|
||||||
return null; // the value doesn't exist
|
return null; // the value doesn't exist
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
|
|
@ -19,11 +20,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool ContainsPrefix(string prefix)
|
public virtual async Task<bool> ContainsPrefixAsync(string prefix)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < Count; i++)
|
for (int i = 0; i < Count; i++)
|
||||||
{
|
{
|
||||||
if (this[i].ContainsPrefix(prefix))
|
if (await this[i].ContainsPrefixAsync(prefix))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -31,7 +32,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual ValueProviderResult GetValue(string key)
|
public virtual async Task<ValueProviderResult> GetValueAsync(string key)
|
||||||
{
|
{
|
||||||
// Performance-sensitive
|
// Performance-sensitive
|
||||||
// Caching the count is faster for IList<T>
|
// Caching the count is faster for IList<T>
|
||||||
|
|
@ -39,7 +40,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
for (int i = 0; i < itemCount; i++)
|
for (int i = 0; i < itemCount; i++)
|
||||||
{
|
{
|
||||||
IValueProvider vp = Items[i];
|
IValueProvider vp = Items[i];
|
||||||
ValueProviderResult result = vp.GetValue(key);
|
ValueProviderResult result = await vp.GetValueAsync(key);
|
||||||
if (result != null)
|
if (result != null)
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
|
|
@ -13,17 +13,18 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
_values = values;
|
_values = values;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ContainsPrefix(string key)
|
public Task<bool> ContainsPrefixAsync(string key)
|
||||||
{
|
{
|
||||||
return _values.ContainsKey(key);
|
return Task.FromResult(_values.ContainsKey(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValueProviderResult GetValue([NotNull] string key)
|
public Task<ValueProviderResult> GetValueAsync([NotNull] string key)
|
||||||
{
|
{
|
||||||
object value;
|
object value;
|
||||||
if (_values.TryGetValue(key, out value))
|
if (_values.TryGetValue(key, out value))
|
||||||
{
|
{
|
||||||
return new ValueProviderResult(value, value.ToString(), CultureInfo.InvariantCulture);
|
var result = new ValueProviderResult(value, value.ToString(), CultureInfo.InvariantCulture);
|
||||||
|
return Task.FromResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding.Internal;
|
using Microsoft.AspNet.Mvc.ModelBinding.Internal;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
|
|
@ -20,16 +21,17 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
|
|
||||||
public object RawValue { get; private set; }
|
public object RawValue { get; private set; }
|
||||||
|
|
||||||
public bool ContainsPrefix(string prefix)
|
public Task<bool> ContainsPrefixAsync(string prefix)
|
||||||
{
|
{
|
||||||
return PrefixContainer.IsPrefixMatch(Name, prefix);
|
return Task.FromResult(PrefixContainer.IsPrefixMatch(Name, prefix));
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValueProviderResult GetValue(string key)
|
public Task<ValueProviderResult> GetValueAsync(string key)
|
||||||
{
|
{
|
||||||
return string.Equals(key, Name, StringComparison.OrdinalIgnoreCase)
|
var result = string.Equals(key, Name, StringComparison.OrdinalIgnoreCase) ?
|
||||||
? new ValueProviderResult(RawValue, Convert.ToString(RawValue, Culture), Culture)
|
new ValueProviderResult(RawValue, Convert.ToString(RawValue, Culture), Culture) :
|
||||||
: null;
|
null;
|
||||||
|
return Task.FromResult(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -11,13 +12,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="prefix">The prefix to search for.</param>
|
/// <param name="prefix">The prefix to search for.</param>
|
||||||
/// <returns>true if the collection contains the specified prefix; otherwise, false.</returns>
|
/// <returns>true if the collection contains the specified prefix; otherwise, false.</returns>
|
||||||
bool ContainsPrefix(string prefix);
|
Task<bool> ContainsPrefixAsync(string prefix);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieves a value object using the specified key.
|
/// Retrieves a value object using the specified key.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="key">The key of the value object to retrieve.</param>
|
/// <param name="key">The key of the value object to retrieve.</param>
|
||||||
/// <returns>The value object for the specified key. If the exact key is not found, null.</returns>
|
/// <returns>The value object for the specified key. If the exact key is not found, null.</returns>
|
||||||
ValueProviderResult GetValue(string key);
|
Task<ValueProviderResult> GetValueAsync(string key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Abstractions;
|
using Microsoft.AspNet.Abstractions;
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding.Internal;
|
using Microsoft.AspNet.Mvc.ModelBinding.Internal;
|
||||||
|
|
||||||
|
|
@ -46,9 +47,9 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool ContainsPrefix(string prefix)
|
public virtual Task<bool> ContainsPrefixAsync(string prefix)
|
||||||
{
|
{
|
||||||
return PrefixContainer.ContainsPrefix(prefix);
|
return Task.FromResult(PrefixContainer.ContainsPrefix(prefix));
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual IDictionary<string, string> GetKeysFromPrefix([NotNull] string prefix)
|
public virtual IDictionary<string, string> GetKeysFromPrefix([NotNull] string prefix)
|
||||||
|
|
@ -56,21 +57,25 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
return PrefixContainer.GetKeysFromPrefix(prefix);
|
return PrefixContainer.GetKeysFromPrefix(prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual Task<ValueProviderResult> GetValueAsync([NotNull] string key)
|
||||||
public virtual ValueProviderResult GetValue([NotNull] string key)
|
|
||||||
{
|
{
|
||||||
|
ValueProviderResult result;
|
||||||
var values = _values.GetValues(key);
|
var values = _values.GetValues(key);
|
||||||
if (values == null)
|
if (values == null)
|
||||||
{
|
{
|
||||||
return null;
|
result = null;
|
||||||
}
|
}
|
||||||
else if (values.Count == 1)
|
else if (values.Count == 1)
|
||||||
{
|
{
|
||||||
var value = (string)values[0];
|
var value = (string)values[0];
|
||||||
return new ValueProviderResult(value, value, _culture);
|
result = new ValueProviderResult(value, value, _culture);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = new ValueProviderResult(values, _values.Get(key), _culture);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ValueProviderResult(values, _values.Get(key), _culture);
|
return Task.FromResult(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#if NET45
|
#if NET45
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -7,7 +8,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
public class ArrayModelBinderTest
|
public class ArrayModelBinderTest
|
||||||
{
|
{
|
||||||
[Fact]
|
[Fact]
|
||||||
public void BindModel()
|
public async Task BindModel()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var valueProvider = new SimpleHttpValueProvider
|
var valueProvider = new SimpleHttpValueProvider
|
||||||
|
|
@ -19,7 +20,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
var binder = new ArrayModelBinder<int>();
|
var binder = new ArrayModelBinder<int>();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
bool retVal = binder.BindModel(bindingContext);
|
var retVal = await binder.BindModelAsync(bindingContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(retVal);
|
Assert.True(retVal);
|
||||||
|
|
@ -29,21 +30,21 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void GetBinder_ValueProviderDoesNotContainPrefix_ReturnsNull()
|
public async Task GetBinder_ValueProviderDoesNotContainPrefix_ReturnsNull()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
ModelBindingContext bindingContext = GetBindingContext(new SimpleHttpValueProvider());
|
ModelBindingContext bindingContext = GetBindingContext(new SimpleHttpValueProvider());
|
||||||
var binder = new ArrayModelBinder<int>();
|
var binder = new ArrayModelBinder<int>();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
bool bound = binder.BindModel(bindingContext);
|
var bound = await binder.BindModelAsync(bindingContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.False(bound);
|
Assert.False(bound);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void GetBinder_ModelMetadataReturnsReadOnly_ReturnsNull()
|
public async Task GetBinder_ModelMetadataReturnsReadOnly_ReturnsNull()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var valueProvider = new SimpleHttpValueProvider
|
var valueProvider = new SimpleHttpValueProvider
|
||||||
|
|
@ -55,7 +56,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
var binder = new ArrayModelBinder<int>();
|
var binder = new ArrayModelBinder<int>();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
bool bound = binder.BindModel(bindingContext);
|
var bound = await binder.BindModelAsync(bindingContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.False(bound);
|
Assert.False(bound);
|
||||||
|
|
@ -65,10 +66,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
{
|
{
|
||||||
var mockIntBinder = new Mock<IModelBinder>();
|
var mockIntBinder = new Mock<IModelBinder>();
|
||||||
mockIntBinder
|
mockIntBinder
|
||||||
.Setup(o => o.BindModel(It.IsAny<ModelBindingContext>()))
|
.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
|
||||||
.Returns((ModelBindingContext mbc) =>
|
.Returns(async (ModelBindingContext mbc) =>
|
||||||
{
|
{
|
||||||
var value = mbc.ValueProvider.GetValue(mbc.ModelName);
|
var value = await mbc.ValueProvider.GetValueAsync(mbc.ModelName);
|
||||||
if (value != null)
|
if (value != null)
|
||||||
{
|
{
|
||||||
mbc.Model = value.ConvertTo(mbc.ModelType);
|
mbc.Model = value.ConvertTo(mbc.ModelType);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
#if NET45
|
#if NET45
|
||||||
using Moq;
|
using Moq;
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -12,7 +13,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
{
|
{
|
||||||
#if NET45
|
#if NET45
|
||||||
[Fact]
|
[Fact]
|
||||||
public void BindComplexCollectionFromIndexes_FiniteIndexes()
|
public async Task BindComplexCollectionFromIndexes_FiniteIndexes()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var valueProvider = new SimpleHttpValueProvider
|
var valueProvider = new SimpleHttpValueProvider
|
||||||
|
|
@ -24,7 +25,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
var binder = new CollectionModelBinder<int>();
|
var binder = new CollectionModelBinder<int>();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var boundCollection = binder.BindComplexCollectionFromIndexes(bindingContext, new[] { "foo", "bar", "baz" });
|
var boundCollection = await binder.BindComplexCollectionFromIndexes(bindingContext, new[] { "foo", "bar", "baz" });
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(new[] { 42, 0, 200 }, boundCollection.ToArray());
|
Assert.Equal(new[] { 42, 0, 200 }, boundCollection.ToArray());
|
||||||
|
|
@ -32,7 +33,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void BindComplexCollectionFromIndexes_InfiniteIndexes()
|
public async Task BindComplexCollectionFromIndexes_InfiniteIndexes()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var valueProvider = new SimpleHttpValueProvider
|
var valueProvider = new SimpleHttpValueProvider
|
||||||
|
|
@ -45,7 +46,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
var binder = new CollectionModelBinder<int>();
|
var binder = new CollectionModelBinder<int>();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var boundCollection = binder.BindComplexCollectionFromIndexes(bindingContext, indexNames: null);
|
var boundCollection = await binder.BindComplexCollectionFromIndexes(bindingContext, indexNames: null);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(new[] { 42, 100 }, boundCollection.ToArray());
|
Assert.Equal(new[] { 42, 100 }, boundCollection.ToArray());
|
||||||
|
|
@ -53,7 +54,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void BindModel_ComplexCollection()
|
public async Task BindModel_ComplexCollection()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var valueProvider = new SimpleHttpValueProvider
|
var valueProvider = new SimpleHttpValueProvider
|
||||||
|
|
@ -67,14 +68,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
var binder = new CollectionModelBinder<int>();
|
var binder = new CollectionModelBinder<int>();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
bool retVal = binder.BindModel(bindingContext);
|
bool retVal = await binder.BindModelAsync(bindingContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(new[] { 42, 100, 200 }, ((List<int>)bindingContext.Model).ToArray());
|
Assert.Equal(new[] { 42, 100, 200 }, ((List<int>)bindingContext.Model).ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void BindModel_SimpleCollection()
|
public async Task BindModel_SimpleCollection()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var valueProvider = new SimpleHttpValueProvider
|
var valueProvider = new SimpleHttpValueProvider
|
||||||
|
|
@ -85,7 +86,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
var binder = new CollectionModelBinder<int>();
|
var binder = new CollectionModelBinder<int>();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
bool retVal = binder.BindModel(bindingContext);
|
bool retVal = await binder.BindModelAsync(bindingContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(retVal);
|
Assert.True(retVal);
|
||||||
|
|
@ -94,13 +95,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void BindSimpleCollection_RawValueIsEmptyCollection_ReturnsEmptyList()
|
public async Task BindSimpleCollection_RawValueIsEmptyCollection_ReturnsEmptyList()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var binder = new CollectionModelBinder<int>();
|
var binder = new CollectionModelBinder<int>();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var boundCollection = binder.BindSimpleCollection(bindingContext: null, rawValue: new object[0], culture: null);
|
var boundCollection = await binder.BindSimpleCollection(bindingContext: null, rawValue: new object[0], culture: null);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.NotNull(boundCollection);
|
Assert.NotNull(boundCollection);
|
||||||
|
|
@ -108,13 +109,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void BindSimpleCollection_RawValueIsNull_ReturnsNull()
|
public async Task BindSimpleCollection_RawValueIsNull_ReturnsNull()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var binder = new CollectionModelBinder<int>();
|
var binder = new CollectionModelBinder<int>();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var boundCollection = binder.BindSimpleCollection(bindingContext: null, rawValue: null, culture: null);
|
var boundCollection = await binder.BindSimpleCollection(bindingContext: null, rawValue: null, culture: null);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Null(boundCollection);
|
Assert.Null(boundCollection);
|
||||||
|
|
@ -122,7 +123,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
|
|
||||||
#if NET45
|
#if NET45
|
||||||
[Fact]
|
[Fact]
|
||||||
public void BindSimpleCollection_SubBindingSucceeds()
|
public async Task BindSimpleCollection_SubBindingSucceeds()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var culture = new CultureInfo("fr-FR");
|
var culture = new CultureInfo("fr-FR");
|
||||||
|
|
@ -130,18 +131,18 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
|
|
||||||
ModelValidationNode childValidationNode = null;
|
ModelValidationNode childValidationNode = null;
|
||||||
Mock.Get<IModelBinder>(bindingContext.ModelBinder)
|
Mock.Get<IModelBinder>(bindingContext.ModelBinder)
|
||||||
.Setup(o => o.BindModel(It.IsAny<ModelBindingContext>()))
|
.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
|
||||||
.Returns((ModelBindingContext mbc) =>
|
.Returns((ModelBindingContext mbc) =>
|
||||||
{
|
{
|
||||||
Assert.Equal("someName", mbc.ModelName);
|
Assert.Equal("someName", mbc.ModelName);
|
||||||
childValidationNode = mbc.ValidationNode;
|
childValidationNode = mbc.ValidationNode;
|
||||||
mbc.Model = 42;
|
mbc.Model = 42;
|
||||||
return true;
|
return Task.FromResult(true);
|
||||||
});
|
});
|
||||||
var modelBinder = new CollectionModelBinder<int>();
|
var modelBinder = new CollectionModelBinder<int>();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var boundCollection = modelBinder.BindSimpleCollection(bindingContext, new int[1], culture);
|
var boundCollection = await modelBinder.BindSimpleCollection(bindingContext, new int[1], culture);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(new[] { 42 }, boundCollection.ToArray());
|
Assert.Equal(new[] { 42 }, boundCollection.ToArray());
|
||||||
|
|
@ -166,10 +167,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
{
|
{
|
||||||
Mock<IModelBinder> mockIntBinder = new Mock<IModelBinder>();
|
Mock<IModelBinder> mockIntBinder = new Mock<IModelBinder>();
|
||||||
mockIntBinder
|
mockIntBinder
|
||||||
.Setup(o => o.BindModel(It.IsAny<ModelBindingContext>()))
|
.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
|
||||||
.Returns((ModelBindingContext mbc) =>
|
.Returns(async (ModelBindingContext mbc) =>
|
||||||
{
|
{
|
||||||
var value = mbc.ValueProvider.GetValue(mbc.ModelName);
|
var value = await mbc.ValueProvider.GetValueAsync(mbc.ModelName);
|
||||||
if (value != null)
|
if (value != null)
|
||||||
{
|
{
|
||||||
mbc.Model = value.ConvertTo(mbc.ModelType);
|
mbc.Model = value.ConvertTo(mbc.ModelType);
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.DependencyInjection;
|
using Microsoft.AspNet.DependencyInjection;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
@ -12,7 +13,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
public class CompositeModelBinderTest
|
public class CompositeModelBinderTest
|
||||||
{
|
{
|
||||||
[Fact]
|
[Fact]
|
||||||
public void BindModel_SuccessfulBind_RunsValidationAndReturnsModel()
|
public async Task BindModel_SuccessfulBind_RunsValidationAndReturnsModel()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var validationCalled = false;
|
var validationCalled = false;
|
||||||
|
|
@ -23,7 +24,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(int)),
|
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(int)),
|
||||||
ModelName = "someName",
|
ModelName = "someName",
|
||||||
ModelState = new ModelStateDictionary(),
|
ModelState = new ModelStateDictionary(),
|
||||||
ValueProvider = new SimpleValueProvider
|
ValueProvider = new SimpleHttpValueProvider
|
||||||
{
|
{
|
||||||
{ "someName", "dummyValue" }
|
{ "someName", "dummyValue" }
|
||||||
},
|
},
|
||||||
|
|
@ -32,7 +33,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
|
|
||||||
var mockIntBinder = new Mock<IModelBinder>();
|
var mockIntBinder = new Mock<IModelBinder>();
|
||||||
mockIntBinder
|
mockIntBinder
|
||||||
.Setup(o => o.BindModel(It.IsAny<ModelBindingContext>()))
|
.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
|
||||||
.Returns(
|
.Returns(
|
||||||
delegate(ModelBindingContext context)
|
delegate(ModelBindingContext context)
|
||||||
{
|
{
|
||||||
|
|
@ -42,13 +43,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
|
|
||||||
context.Model = 42;
|
context.Model = 42;
|
||||||
bindingContext.ValidationNode.Validating += delegate { validationCalled = true; };
|
bindingContext.ValidationNode.Validating += delegate { validationCalled = true; };
|
||||||
return true;
|
return Task.FromResult(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
var shimBinder = new CompositeModelBinder(mockIntBinder.Object);
|
var shimBinder = new CompositeModelBinder(mockIntBinder.Object);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var isBound = shimBinder.BindModel(bindingContext);
|
var isBound = await shimBinder.BindModelAsync(bindingContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(isBound);
|
Assert.True(isBound);
|
||||||
|
|
@ -59,7 +60,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void BindModel_SuccessfulBind_ComplexTypeFallback_RunsValidationAndReturnsModel()
|
public async Task BindModel_SuccessfulBind_ComplexTypeFallback_RunsValidationAndReturnsModel()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var validationCalled = false;
|
var validationCalled = false;
|
||||||
|
|
@ -71,7 +72,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(List<int>)),
|
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(List<int>)),
|
||||||
ModelName = "someName",
|
ModelName = "someName",
|
||||||
ModelState = new ModelStateDictionary(),
|
ModelState = new ModelStateDictionary(),
|
||||||
ValueProvider = new SimpleValueProvider
|
ValueProvider = new SimpleHttpValueProvider
|
||||||
{
|
{
|
||||||
{ "someOtherName", "dummyValue" }
|
{ "someOtherName", "dummyValue" }
|
||||||
},
|
},
|
||||||
|
|
@ -80,13 +81,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
|
|
||||||
var mockIntBinder = new Mock<IModelBinder>();
|
var mockIntBinder = new Mock<IModelBinder>();
|
||||||
mockIntBinder
|
mockIntBinder
|
||||||
.Setup(o => o.BindModel(It.IsAny<ModelBindingContext>()))
|
.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
|
||||||
.Returns(
|
.Returns(
|
||||||
delegate(ModelBindingContext mbc)
|
delegate(ModelBindingContext mbc)
|
||||||
{
|
{
|
||||||
if (!String.IsNullOrEmpty(mbc.ModelName))
|
if (!string.IsNullOrEmpty(mbc.ModelName))
|
||||||
{
|
{
|
||||||
return false;
|
return Task.FromResult(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert.Same(bindingContext.ModelMetadata, mbc.ModelMetadata);
|
Assert.Same(bindingContext.ModelMetadata, mbc.ModelMetadata);
|
||||||
|
|
@ -95,13 +96,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
|
|
||||||
mbc.Model = expectedModel;
|
mbc.Model = expectedModel;
|
||||||
mbc.ValidationNode.Validating += delegate { validationCalled = true; };
|
mbc.ValidationNode.Validating += delegate { validationCalled = true; };
|
||||||
return true;
|
return Task.FromResult(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
IModelBinder shimBinder = new CompositeModelBinder(mockIntBinder.Object);
|
IModelBinder shimBinder = new CompositeModelBinder(mockIntBinder.Object);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
bool isBound = shimBinder.BindModel(bindingContext);
|
var isBound = await shimBinder.BindModelAsync(bindingContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(isBound);
|
Assert.True(isBound);
|
||||||
|
|
@ -111,12 +112,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void BindModel_UnsuccessfulBind_BinderFails_ReturnsNull()
|
public async Task BindModel_UnsuccessfulBind_BinderFails_ReturnsNull()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var mockListBinder = new Mock<IModelBinder>();
|
var mockListBinder = new Mock<IModelBinder>();
|
||||||
mockListBinder.Setup(o => o.BindModel(It.IsAny<ModelBindingContext>()))
|
mockListBinder.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
|
||||||
.Returns(false)
|
.Returns(Task.FromResult(false))
|
||||||
.Verifiable();
|
.Verifiable();
|
||||||
|
|
||||||
var shimBinder = (IModelBinder)mockListBinder.Object;
|
var shimBinder = (IModelBinder)mockListBinder.Object;
|
||||||
|
|
@ -128,7 +129,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
};
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var isBound = shimBinder.BindModel(bindingContext);
|
var isBound = await shimBinder.BindModelAsync(bindingContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.False(isBound);
|
Assert.False(isBound);
|
||||||
|
|
@ -138,7 +139,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void BindModel_UnsuccessfulBind_SimpleTypeNoFallback_ReturnsNull()
|
public async Task BindModel_UnsuccessfulBind_SimpleTypeNoFallback_ReturnsNull()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var innerBinder = Mock.Of<IModelBinder>();
|
var innerBinder = Mock.Of<IModelBinder>();
|
||||||
|
|
@ -152,7 +153,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
};
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var isBound = shimBinder.BindModel(bindingContext);
|
var isBound = await shimBinder.BindModelAsync(bindingContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.False(isBound);
|
Assert.False(isBound);
|
||||||
|
|
@ -160,12 +161,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void BindModel_WithDefaultBinders_BindsSimpleType()
|
public async Task BindModel_WithDefaultBinders_BindsSimpleType()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var binder = CreateBinderWithDefaults();
|
var binder = CreateBinderWithDefaults();
|
||||||
|
|
||||||
var valueProvider = new SimpleValueProvider
|
var valueProvider = new SimpleHttpValueProvider
|
||||||
{
|
{
|
||||||
{ "firstName", "firstName-value"},
|
{ "firstName", "firstName-value"},
|
||||||
{ "lastName", "lastName-value"}
|
{ "lastName", "lastName-value"}
|
||||||
|
|
@ -173,7 +174,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
var bindingContext = CreateBindingContext(binder, valueProvider, typeof(SimplePropertiesModel));
|
var bindingContext = CreateBindingContext(binder, valueProvider, typeof(SimplePropertiesModel));
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var isBound = binder.BindModel(bindingContext);
|
var isBound = await binder.BindModelAsync(bindingContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(isBound);
|
Assert.True(isBound);
|
||||||
|
|
@ -183,12 +184,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void BindModel_WithDefaultBinders_BindsComplexType()
|
public async Task BindModel_WithDefaultBinders_BindsComplexType()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var binder = CreateBinderWithDefaults();
|
var binder = CreateBinderWithDefaults();
|
||||||
|
|
||||||
var valueProvider = new SimpleValueProvider
|
var valueProvider = new SimpleHttpValueProvider
|
||||||
{
|
{
|
||||||
{ "firstName", "firstName-value"},
|
{ "firstName", "firstName-value"},
|
||||||
{ "lastName", "lastName-value"},
|
{ "lastName", "lastName-value"},
|
||||||
|
|
@ -201,7 +202,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
var bindingContext = CreateBindingContext(binder, valueProvider, typeof(Person));
|
var bindingContext = CreateBindingContext(binder, valueProvider, typeof(Person));
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var isBound = binder.BindModel(bindingContext);
|
var isBound = await binder.BindModelAsync(bindingContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(isBound);
|
Assert.True(isBound);
|
||||||
|
|
@ -270,70 +271,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
|
|
||||||
public List<Person> Friends { get; set; }
|
public List<Person> Friends { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SimpleValueProvider : Dictionary<string, object>, IValueProvider
|
|
||||||
{
|
|
||||||
private readonly CultureInfo _culture;
|
|
||||||
|
|
||||||
public SimpleValueProvider()
|
|
||||||
: this(null)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public SimpleValueProvider(CultureInfo culture)
|
|
||||||
: base(StringComparer.OrdinalIgnoreCase)
|
|
||||||
{
|
|
||||||
_culture = culture ?? CultureInfo.InvariantCulture;
|
|
||||||
}
|
|
||||||
|
|
||||||
// copied from ValueProviderUtil
|
|
||||||
public bool ContainsPrefix(string prefix)
|
|
||||||
{
|
|
||||||
foreach (string key in Keys)
|
|
||||||
{
|
|
||||||
if (key != null)
|
|
||||||
{
|
|
||||||
if (prefix.Length == 0)
|
|
||||||
{
|
|
||||||
return true; // shortcut - non-null key matches empty prefix
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
if (key.Length == prefix.Length)
|
|
||||||
{
|
|
||||||
return true; // exact match
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (key[prefix.Length])
|
|
||||||
{
|
|
||||||
case '.': // known separator characters
|
|
||||||
case '[':
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false; // nothing found
|
|
||||||
}
|
|
||||||
|
|
||||||
public ValueProviderResult GetValue(string key)
|
|
||||||
{
|
|
||||||
object rawValue;
|
|
||||||
if (TryGetValue(key, out rawValue))
|
|
||||||
{
|
|
||||||
return new ValueProviderResult(rawValue, Convert.ToString(rawValue, _culture), _culture);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// value not found
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#if NET45
|
#if NET45
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -8,7 +9,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
public class DictionaryModelBinderTest
|
public class DictionaryModelBinderTest
|
||||||
{
|
{
|
||||||
[Fact]
|
[Fact]
|
||||||
public void BindModel()
|
public async Task BindModel()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var metadataProvider = new EmptyModelMetadataProvider();
|
var metadataProvider = new EmptyModelMetadataProvider();
|
||||||
|
|
@ -27,7 +28,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
var binder = new DictionaryModelBinder<int, string>();
|
var binder = new DictionaryModelBinder<int, string>();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
bool retVal = binder.BindModel(bindingContext);
|
bool retVal = await binder.BindModelAsync(bindingContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(retVal);
|
Assert.True(retVal);
|
||||||
|
|
@ -43,10 +44,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
{
|
{
|
||||||
Mock<IModelBinder> mockKvpBinder = new Mock<IModelBinder>();
|
Mock<IModelBinder> mockKvpBinder = new Mock<IModelBinder>();
|
||||||
mockKvpBinder
|
mockKvpBinder
|
||||||
.Setup(o => o.BindModel(It.IsAny<ModelBindingContext>()))
|
.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
|
||||||
.Returns((ModelBindingContext mbc) =>
|
.Returns(async (ModelBindingContext mbc) =>
|
||||||
{
|
{
|
||||||
var value = mbc.ValueProvider.GetValue(mbc.ModelName);
|
var value = await mbc.ValueProvider.GetValueAsync(mbc.ModelName);
|
||||||
if (value != null)
|
if (value != null)
|
||||||
{
|
{
|
||||||
mbc.Model = value.ConvertTo(mbc.ModelType);
|
mbc.Model = value.ConvertTo(mbc.ModelType);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#if NET45
|
#if NET45
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -9,7 +10,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
public class KeyValuePairModelBinderTest
|
public class KeyValuePairModelBinderTest
|
||||||
{
|
{
|
||||||
[Fact]
|
[Fact]
|
||||||
public void BindModel_MissingKey_ReturnsFalse()
|
public async Task BindModel_MissingKey_ReturnsFalse()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var valueProvider = new SimpleHttpValueProvider();
|
var valueProvider = new SimpleHttpValueProvider();
|
||||||
|
|
@ -17,7 +18,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
var binder = new KeyValuePairModelBinder<int, string>();
|
var binder = new KeyValuePairModelBinder<int, string>();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
bool retVal = binder.BindModel(bindingContext);
|
bool retVal = await binder.BindModelAsync(bindingContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.False(retVal);
|
Assert.False(retVal);
|
||||||
|
|
@ -26,7 +27,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void BindModel_MissingValue_ReturnsTrue()
|
public async Task BindModel_MissingValue_ReturnsTrue()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var valueProvider = new SimpleHttpValueProvider();
|
var valueProvider = new SimpleHttpValueProvider();
|
||||||
|
|
@ -34,7 +35,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
var binder = new KeyValuePairModelBinder<int, string>();
|
var binder = new KeyValuePairModelBinder<int, string>();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
bool retVal = binder.BindModel(bindingContext);
|
bool retVal = await binder.BindModelAsync(bindingContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(retVal);
|
Assert.True(retVal);
|
||||||
|
|
@ -43,7 +44,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void BindModel_SubBindingSucceeds()
|
public async Task BindModel_SubBindingSucceeds()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var innerBinder = new CompositeModelBinder(CreateStringBinder(), CreateIntBinder());
|
var innerBinder = new CompositeModelBinder(CreateStringBinder(), CreateIntBinder());
|
||||||
|
|
@ -53,7 +54,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
var binder = new KeyValuePairModelBinder<int, string>();
|
var binder = new KeyValuePairModelBinder<int, string>();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var retVal = binder.BindModel(bindingContext);
|
var retVal = await binder.BindModelAsync(bindingContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(retVal);
|
Assert.True(retVal);
|
||||||
|
|
@ -62,34 +63,33 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void TryBindStrongModel_BinderExists_BinderReturnsCorrectlyTypedObject_ReturnsTrue()
|
public async Task TryBindStrongModel_BinderExists_BinderReturnsCorrectlyTypedObject_ReturnsTrue()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
ModelBindingContext bindingContext = GetBindingContext(new SimpleHttpValueProvider());
|
ModelBindingContext bindingContext = GetBindingContext(new SimpleHttpValueProvider());
|
||||||
var binder = new KeyValuePairModelBinder<int, string>();
|
var binder = new KeyValuePairModelBinder<int, string>();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
int model;
|
var retVal = await binder.TryBindStrongModel<int>(bindingContext, "key");
|
||||||
var retVal = binder.TryBindStrongModel(bindingContext, "key", out model);
|
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(retVal);
|
Assert.True(retVal.Success);
|
||||||
Assert.Equal(42, model);
|
Assert.Equal(42, retVal.Model);
|
||||||
Assert.Single(bindingContext.ValidationNode.ChildNodes);
|
Assert.Single(bindingContext.ValidationNode.ChildNodes);
|
||||||
Assert.Empty(bindingContext.ModelState);
|
Assert.Empty(bindingContext.ModelState);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void TryBindStrongModel_BinderExists_BinderReturnsIncorrectlyTypedObject_ReturnsTrue()
|
public async Task TryBindStrongModel_BinderExists_BinderReturnsIncorrectlyTypedObject_ReturnsTrue()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var innerBinder = new Mock<IModelBinder>();
|
var innerBinder = new Mock<IModelBinder>();
|
||||||
innerBinder
|
innerBinder
|
||||||
.Setup(o => o.BindModel(It.IsAny<ModelBindingContext>()))
|
.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
|
||||||
.Returns((ModelBindingContext mbc) =>
|
.Returns((ModelBindingContext mbc) =>
|
||||||
{
|
{
|
||||||
Assert.Equal("someName.key", mbc.ModelName);
|
Assert.Equal("someName.key", mbc.ModelName);
|
||||||
return true;
|
return Task.FromResult(true);
|
||||||
});
|
});
|
||||||
var bindingContext = GetBindingContext(new SimpleHttpValueProvider(), innerBinder.Object);
|
var bindingContext = GetBindingContext(new SimpleHttpValueProvider(), innerBinder.Object);
|
||||||
|
|
||||||
|
|
@ -97,12 +97,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
var binder = new KeyValuePairModelBinder<int, string>();
|
var binder = new KeyValuePairModelBinder<int, string>();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
int model;
|
var retVal = await binder.TryBindStrongModel<int>(bindingContext, "key");
|
||||||
var retVal = binder.TryBindStrongModel(bindingContext, "key", out model);
|
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(retVal);
|
Assert.True(retVal.Success);
|
||||||
Assert.Equal(default(int), model);
|
Assert.Equal(default(int), retVal.Model);
|
||||||
Assert.Single(bindingContext.ValidationNode.ChildNodes);
|
Assert.Single(bindingContext.ValidationNode.ChildNodes);
|
||||||
Assert.Empty(bindingContext.ModelState);
|
Assert.Empty(bindingContext.ModelState);
|
||||||
}
|
}
|
||||||
|
|
@ -126,15 +125,15 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
{
|
{
|
||||||
var mockIntBinder = new Mock<IModelBinder>();
|
var mockIntBinder = new Mock<IModelBinder>();
|
||||||
mockIntBinder
|
mockIntBinder
|
||||||
.Setup(o => o.BindModel(It.IsAny<ModelBindingContext>()))
|
.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
|
||||||
.Returns((ModelBindingContext mbc) =>
|
.Returns((ModelBindingContext mbc) =>
|
||||||
{
|
{
|
||||||
if (mbc.ModelType == typeof(int))
|
if (mbc.ModelType == typeof(int))
|
||||||
{
|
{
|
||||||
mbc.Model = 42;
|
mbc.Model = 42;
|
||||||
return true;
|
return Task.FromResult(true);
|
||||||
}
|
}
|
||||||
return false;
|
return Task.FromResult(false);
|
||||||
});
|
});
|
||||||
return mockIntBinder.Object;
|
return mockIntBinder.Object;
|
||||||
}
|
}
|
||||||
|
|
@ -143,15 +142,15 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
{
|
{
|
||||||
var mockStringBinder = new Mock<IModelBinder>();
|
var mockStringBinder = new Mock<IModelBinder>();
|
||||||
mockStringBinder
|
mockStringBinder
|
||||||
.Setup(o => o.BindModel(It.IsAny<ModelBindingContext>()))
|
.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
|
||||||
.Returns((ModelBindingContext mbc) =>
|
.Returns((ModelBindingContext mbc) =>
|
||||||
{
|
{
|
||||||
if (mbc.ModelType == typeof(string))
|
if (mbc.ModelType == typeof(string))
|
||||||
{
|
{
|
||||||
mbc.Model = "some-value";
|
mbc.Model = "some-value";
|
||||||
return true;
|
return Task.FromResult(true);
|
||||||
}
|
}
|
||||||
return false;
|
return Task.FromResult(false);
|
||||||
});
|
});
|
||||||
return mockStringBinder.Object;
|
return mockStringBinder.Object;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Testing;
|
using Microsoft.AspNet.Testing;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
@ -13,12 +14,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
public class MutableObjectModelBinderTest
|
public class MutableObjectModelBinderTest
|
||||||
{
|
{
|
||||||
[Fact]
|
[Fact]
|
||||||
public void BindModel_InitsInstance()
|
public async Task BindModel_InitsInstance()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var mockValueProvider = new Mock<IValueProvider>();
|
var mockValueProvider = new Mock<IValueProvider>();
|
||||||
mockValueProvider.Setup(o => o.ContainsPrefix(It.IsAny<string>()))
|
mockValueProvider.Setup(o => o.ContainsPrefixAsync(It.IsAny<string>()))
|
||||||
.Returns(true);
|
.Returns(Task.FromResult(true));
|
||||||
|
|
||||||
var mockDtoBinder = new Mock<IModelBinder>();
|
var mockDtoBinder = new Mock<IModelBinder>();
|
||||||
var bindingContext = new ModelBindingContext
|
var bindingContext = new ModelBindingContext
|
||||||
|
|
@ -32,11 +33,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
};
|
};
|
||||||
|
|
||||||
mockDtoBinder
|
mockDtoBinder
|
||||||
.Setup(o => o.BindModel(It.IsAny<ModelBindingContext>()))
|
.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
|
||||||
.Returns((ModelBindingContext mbc) =>
|
.Returns((ModelBindingContext mbc) =>
|
||||||
{
|
{
|
||||||
// just return the DTO unchanged
|
// just return the DTO unchanged
|
||||||
return true;
|
return Task.FromResult(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
var testableBinder = new Mock<TestableMutableObjectModelBinder> { CallBase = true };
|
var testableBinder = new Mock<TestableMutableObjectModelBinder> { CallBase = true };
|
||||||
|
|
@ -45,7 +46,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||||
.Returns(new ModelMetadata[0]).Verifiable();
|
.Returns(new ModelMetadata[0]).Verifiable();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var retValue = testableBinder.Object.BindModel(bindingContext);
|
var retValue = await testableBinder.Object.BindModelAsync(bindingContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(retValue);
|
Assert.True(retValue);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
|
|
@ -11,7 +12,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
[InlineData(typeof(object))]
|
[InlineData(typeof(object))]
|
||||||
[InlineData(typeof(Calendar))]
|
[InlineData(typeof(Calendar))]
|
||||||
[InlineData(typeof(TestClass))]
|
[InlineData(typeof(TestClass))]
|
||||||
public void BindModel_ReturnsFalse_IfTypeCannotBeConverted(Type destinationType)
|
public async Task BindModel_ReturnsFalse_IfTypeCannotBeConverted(Type destinationType)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var bindingContext = GetBindingContext(destinationType);
|
var bindingContext = GetBindingContext(destinationType);
|
||||||
|
|
@ -23,7 +24,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
var binder = new TypeConverterModelBinder();
|
var binder = new TypeConverterModelBinder();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var retVal = binder.BindModel(bindingContext);
|
var retVal = await binder.BindModelAsync(bindingContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.False(retVal);
|
Assert.False(retVal);
|
||||||
|
|
@ -36,7 +37,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
[InlineData(typeof(DateTimeOffset))]
|
[InlineData(typeof(DateTimeOffset))]
|
||||||
[InlineData(typeof(double))]
|
[InlineData(typeof(double))]
|
||||||
[InlineData(typeof(DayOfWeek))]
|
[InlineData(typeof(DayOfWeek))]
|
||||||
public void BindModel_ReturnsTrue_IfTypeCanBeConverted(Type destinationType)
|
public async Task BindModel_ReturnsTrue_IfTypeCanBeConverted(Type destinationType)
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var bindingContext = GetBindingContext(destinationType);
|
var bindingContext = GetBindingContext(destinationType);
|
||||||
|
|
@ -48,14 +49,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
var binder = new TypeConverterModelBinder();
|
var binder = new TypeConverterModelBinder();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var retVal = binder.BindModel(bindingContext);
|
var retVal = await binder.BindModelAsync(bindingContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(retVal);
|
Assert.True(retVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void BindModel_Error_FormatExceptionsTurnedIntoStringsInModelState()
|
public async Task BindModel_Error_FormatExceptionsTurnedIntoStringsInModelState()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
ModelBindingContext bindingContext = GetBindingContext(typeof(int));
|
ModelBindingContext bindingContext = GetBindingContext(typeof(int));
|
||||||
|
|
@ -67,7 +68,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
TypeConverterModelBinder binder = new TypeConverterModelBinder();
|
TypeConverterModelBinder binder = new TypeConverterModelBinder();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
bool retVal = binder.BindModel(bindingContext);
|
bool retVal = await binder.BindModelAsync(bindingContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(retVal);
|
Assert.True(retVal);
|
||||||
|
|
@ -77,7 +78,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void BindModel_NullValueProviderResult_ReturnsFalse()
|
public async Task BindModel_NullValueProviderResult_ReturnsFalse()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
ModelBindingContext bindingContext = GetBindingContext(typeof(int));
|
ModelBindingContext bindingContext = GetBindingContext(typeof(int));
|
||||||
|
|
@ -85,7 +86,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
TypeConverterModelBinder binder = new TypeConverterModelBinder();
|
TypeConverterModelBinder binder = new TypeConverterModelBinder();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
bool retVal = binder.BindModel(bindingContext);
|
bool retVal = await binder.BindModelAsync(bindingContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.False(retVal, "BindModel should have returned null.");
|
Assert.False(retVal, "BindModel should have returned null.");
|
||||||
|
|
@ -93,7 +94,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void BindModel_ValidValueProviderResult_ConvertEmptyStringsToNull()
|
public async Task BindModel_ValidValueProviderResult_ConvertEmptyStringsToNull()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
ModelBindingContext bindingContext = GetBindingContext(typeof(string));
|
ModelBindingContext bindingContext = GetBindingContext(typeof(string));
|
||||||
|
|
@ -105,7 +106,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
TypeConverterModelBinder binder = new TypeConverterModelBinder();
|
TypeConverterModelBinder binder = new TypeConverterModelBinder();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
bool retVal = binder.BindModel(bindingContext);
|
bool retVal = await binder.BindModelAsync(bindingContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(retVal);
|
Assert.True(retVal);
|
||||||
|
|
@ -114,7 +115,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void BindModel_ValidValueProviderResult_ReturnsModel()
|
public async Task BindModel_ValidValueProviderResult_ReturnsModel()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
ModelBindingContext bindingContext = GetBindingContext(typeof(int));
|
ModelBindingContext bindingContext = GetBindingContext(typeof(int));
|
||||||
|
|
@ -126,7 +127,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
TypeConverterModelBinder binder = new TypeConverterModelBinder();
|
TypeConverterModelBinder binder = new TypeConverterModelBinder();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
bool retVal = binder.BindModel(bindingContext);
|
bool retVal = await binder.BindModelAsync(bindingContext);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(retVal);
|
Assert.True(retVal);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
{
|
{
|
||||||
|
|
@ -20,7 +21,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
// copied from ValueProviderUtil
|
// copied from ValueProviderUtil
|
||||||
public bool ContainsPrefix(string prefix)
|
public Task<bool> ContainsPrefixAsync(string prefix)
|
||||||
{
|
{
|
||||||
foreach (string key in Keys)
|
foreach (string key in Keys)
|
||||||
{
|
{
|
||||||
|
|
@ -28,14 +29,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
{
|
{
|
||||||
if (prefix.Length == 0)
|
if (prefix.Length == 0)
|
||||||
{
|
{
|
||||||
return true; // shortcut - non-null key matches empty prefix
|
return Task.FromResult(true); // shortcut - non-null key matches empty prefix
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
|
if (key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
if (key.Length == prefix.Length)
|
if (key.Length == prefix.Length)
|
||||||
{
|
{
|
||||||
return true; // exact match
|
return Task.FromResult(true); // exact match
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -43,28 +44,26 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
{
|
{
|
||||||
case '.': // known separator characters
|
case '.': // known separator characters
|
||||||
case '[':
|
case '[':
|
||||||
return true;
|
return Task.FromResult(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false; // nothing found
|
return Task.FromResult(false); // nothing found
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValueProviderResult GetValue(string key)
|
public Task<ValueProviderResult> GetValueAsync(string key)
|
||||||
{
|
{
|
||||||
|
ValueProviderResult result = null;
|
||||||
object rawValue;
|
object rawValue;
|
||||||
if (TryGetValue(key, out rawValue))
|
if (TryGetValue(key, out rawValue))
|
||||||
{
|
{
|
||||||
return new ValueProviderResult(rawValue, Convert.ToString(rawValue, _culture), _culture);
|
result = new ValueProviderResult(rawValue, Convert.ToString(rawValue, _culture), _culture);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// value not found
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Task.FromResult(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Abstractions;
|
using Microsoft.AspNet.Abstractions;
|
||||||
using Microsoft.AspNet.PipelineCore.Collections;
|
using Microsoft.AspNet.PipelineCore.Collections;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
@ -20,52 +21,52 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ContainsPrefix_WithEmptyCollection_ReturnsFalseForEmptyPrefix()
|
public async Task ContainsPrefix_WithEmptyCollection_ReturnsFalseForEmptyPrefix()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var backingStore = new ReadableStringCollection(new Dictionary<string, string[]>());
|
var backingStore = new ReadableStringCollection(new Dictionary<string, string[]>());
|
||||||
var valueProvider = new ReadableStringCollectionValueProvider(backingStore, null);
|
var valueProvider = new ReadableStringCollectionValueProvider(backingStore, null);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
bool result = valueProvider.ContainsPrefix("");
|
var result = await valueProvider.ContainsPrefixAsync("");
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.False(result);
|
Assert.False(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ContainsPrefix_WithNonEmptyCollection_ReturnsTrueForEmptyPrefix()
|
public async Task ContainsPrefix_WithNonEmptyCollection_ReturnsTrueForEmptyPrefix()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var valueProvider = new ReadableStringCollectionValueProvider(_backingStore, null);
|
var valueProvider = new ReadableStringCollectionValueProvider(_backingStore, null);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
bool result = valueProvider.ContainsPrefix("");
|
var result = await valueProvider.ContainsPrefixAsync("");
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.True(result);
|
Assert.True(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ContainsPrefix_WithNonEmptyCollection_ReturnsTrueForKnownPrefixes()
|
public async Task ContainsPrefix_WithNonEmptyCollection_ReturnsTrueForKnownPrefixes()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var valueProvider = new ReadableStringCollectionValueProvider(_backingStore, null);
|
var valueProvider = new ReadableStringCollectionValueProvider(_backingStore, null);
|
||||||
|
|
||||||
// Act & Assert
|
// Act & Assert
|
||||||
Assert.True(valueProvider.ContainsPrefix("foo"));
|
Assert.True(await valueProvider.ContainsPrefixAsync("foo"));
|
||||||
Assert.True(valueProvider.ContainsPrefix("bar"));
|
Assert.True(await valueProvider.ContainsPrefixAsync("bar"));
|
||||||
Assert.True(valueProvider.ContainsPrefix("bar.baz"));
|
Assert.True(await valueProvider.ContainsPrefixAsync("bar.baz"));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ContainsPrefix_WithNonEmptyCollection_ReturnsFalseForUnknownPrefix()
|
public async Task ContainsPrefix_WithNonEmptyCollection_ReturnsFalseForUnknownPrefix()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var valueProvider = new ReadableStringCollectionValueProvider(_backingStore, null);
|
var valueProvider = new ReadableStringCollectionValueProvider(_backingStore, null);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
bool result = valueProvider.ContainsPrefix("biff");
|
var result = await valueProvider.ContainsPrefixAsync("biff");
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.False(result);
|
Assert.False(result);
|
||||||
|
|
@ -115,14 +116,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void GetValue_SingleValue()
|
public async Task GetValue_SingleValue()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var culture = new CultureInfo("fr-FR");
|
var culture = new CultureInfo("fr-FR");
|
||||||
var valueProvider = new ReadableStringCollectionValueProvider(_backingStore, culture);
|
var valueProvider = new ReadableStringCollectionValueProvider(_backingStore, culture);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
ValueProviderResult vpResult = valueProvider.GetValue("bar.baz");
|
var vpResult = await valueProvider.GetValueAsync("bar.baz");
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.NotNull(vpResult);
|
Assert.NotNull(vpResult);
|
||||||
|
|
@ -132,14 +133,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void GetValue_MultiValue()
|
public async Task GetValue_MultiValue()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var culture = new CultureInfo("fr-FR");
|
var culture = new CultureInfo("fr-FR");
|
||||||
var valueProvider = new ReadableStringCollectionValueProvider(_backingStore, culture);
|
var valueProvider = new ReadableStringCollectionValueProvider(_backingStore, culture);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
ValueProviderResult vpResult = valueProvider.GetValue("foo");
|
var vpResult = await valueProvider.GetValueAsync("foo");
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.NotNull(vpResult);
|
Assert.NotNull(vpResult);
|
||||||
|
|
@ -153,7 +154,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
//[Theory]
|
//[Theory]
|
||||||
//[InlineData("null_value")]
|
//[InlineData("null_value")]
|
||||||
//[InlineData("prefix.null_value")]
|
//[InlineData("prefix.null_value")]
|
||||||
//public void GetValue_NullValue(string key)
|
//public async Task GetValue_NullValue(string key)
|
||||||
//{
|
//{
|
||||||
// // Arrange
|
// // Arrange
|
||||||
// var culture = new CultureInfo("fr-FR");
|
// var culture = new CultureInfo("fr-FR");
|
||||||
|
|
@ -170,7 +171,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
//}
|
//}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void GetValue_NullMultipleValue()
|
public async Task GetValue_NullMultipleValue()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var backingStore = new ReadableStringCollection(
|
var backingStore = new ReadableStringCollection(
|
||||||
|
|
@ -182,7 +183,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
var valueProvider = new ReadableStringCollectionValueProvider(backingStore, culture);
|
var valueProvider = new ReadableStringCollectionValueProvider(backingStore, culture);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
ValueProviderResult vpResult = valueProvider.GetValue("key");
|
var vpResult = await valueProvider.GetValueAsync("key");
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(new[] { null, null, "value" }, vpResult.RawValue as IEnumerable<string>);
|
Assert.Equal(new[] { null, null, "value" }, vpResult.RawValue as IEnumerable<string>);
|
||||||
|
|
@ -190,13 +191,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void GetValue_ReturnsNullIfKeyNotFound()
|
public async Task GetValue_ReturnsNullIfKeyNotFound()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var valueProvider = new ReadableStringCollectionValueProvider(_backingStore, null);
|
var valueProvider = new ReadableStringCollectionValueProvider(_backingStore, null);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
ValueProviderResult vpResult = valueProvider.GetValue("bar");
|
var vpResult = await valueProvider.GetValueAsync("bar");
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Null(vpResult);
|
Assert.Null(vpResult);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue