Make ValueProviderResult a string-ish struct

This commit is contained in:
Ryan Nowak 2015-08-18 15:02:58 -07:00
parent 02cc82a055
commit 6d365e9a32
73 changed files with 2135 additions and 1806 deletions

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="AspNetVNext" value="https://www.myget.org/F/aspnetlitedev/api/v2" />

View File

@ -3,17 +3,29 @@
namespace Microsoft.AspNet.Mvc.ModelBinding
{
/// <summary>
/// An entry in a <see cref="ModelStateDictionary"/>.
/// </summary>
public class ModelState
{
private readonly ModelErrorCollection _errors = new ModelErrorCollection();
/// <summary>
/// Gets the raw value from the request associated with this entry.
/// </summary>
public object RawValue { get; set; }
public ValueProviderResult Value { get; set; }
/// <summary>
/// Gets the set of values contained in <see cref="RawValue"/>, joined into a comma-separated string.
/// </summary>
public string AttemptedValue { get; set; }
public ModelErrorCollection Errors
{
get { return _errors; }
}
/// <summary>
/// Gets the <see cref="ModelErrorCollection"/> for this entry.
/// </summary>
public ModelErrorCollection Errors { get; } = new ModelErrorCollection();
/// <summary>
/// Gets or sets the <see cref="ModelValidationState"/> for this entry.
/// </summary>
public ModelValidationState ValidationState { get; set; }
}
}

View File

@ -4,6 +4,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Microsoft.AspNet.Mvc.Abstractions;
using Microsoft.Framework.Internal;
@ -213,6 +214,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
// Convert FormatExceptions to Invalid value messages.
ModelState modelState;
TryGetValue(key, out modelState);
string errorMessage;
if (modelState == null)
{
@ -221,7 +223,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
else
{
errorMessage = Resources.FormatModelError_InvalidValue_MessageWithModelValue(
modelState.Value.AttemptedValue,
modelState.AttemptedValue,
key);
}
@ -359,14 +361,50 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
}
/// <summary>
/// Sets the value for the <see cref="ModelState"/> with the specified <paramref name="key"/> to the
/// specified <paramref name="value"/>.
/// Sets the of <see cref="ModelState.RawValue"/> and <see cref="ModelState.AttemptedValue"/> for
/// the <see cref="ModelState"/> with the specified <paramref name="key"/>.
/// </summary>
/// <param name="key">The key for the <see cref="ModelState"/> entry.</param>
/// <param name="value">The value to assign.</param>
public void SetModelValue([NotNull] string key, [NotNull] ValueProviderResult value)
/// <param name="rawvalue">The raw value for the <see cref="ModelState"/> entry.</param>
/// <param name="attemptedValue">
/// The values of <param name="rawValue"/> in a comma-separated <see cref="string"/>.
/// </param>
public void SetModelValue([NotNull] string key, object rawValue, string attemptedValue)
{
GetModelStateForKey(key).Value = value;
var modelState = GetModelStateForKey(key);
modelState.RawValue = rawValue;
modelState.AttemptedValue = attemptedValue;
}
/// <summary>
/// Sets the value for the <see cref="ModelState"/> with the specified <paramref name="key"/>.
/// </summary>
/// <param name="key">The key for the <see cref="ModelState"/> entry</param>
/// <param name="valueProviderResult">
/// A <see cref="ValueProviderResult"/> with data for the <see cref="ModelState"/> entry.
/// </param>
public void SetModelValue([NotNull] string key, ValueProviderResult valueProviderResult)
{
// Avoid creating a new array for rawvalue if there's only one value.
object rawValue;
if (valueProviderResult == ValueProviderResult.None)
{
rawValue = null;
}
else if (valueProviderResult.Value != null)
{
rawValue = valueProviderResult.Value;
}
else if (valueProviderResult.Length == 1)
{
rawValue = valueProviderResult.Values[0];
}
else
{
rawValue = valueProviderResult.Values;
}
SetModelValue(key, rawValue, (string)valueProviderResult);
}
/// <summary>

View File

@ -3,227 +3,353 @@
using System;
using System.Collections;
using System.ComponentModel;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.ExceptionServices;
using Microsoft.AspNet.Mvc.Abstractions;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Mvc.ModelBinding
{
/// <summary>
/// Result of an <see cref="IValueProvider.GetValueAsync"/> operation.
/// Result of an <see cref="IValueProvider.GetValueAsync(string)"/> operation.
/// </summary>
public class ValueProviderResult
/// <remarks>
/// <para>
/// <see cref="ValueProviderResult"/> can represent a single submitted value or multiple submitted values.
/// </para>
/// <para>
/// Use <see cref="FirstValue"/> to consume only a single value, regardless of whether a single value or
/// multiple values were submitted.
/// </para>
/// <para>
/// Treat <see cref="ValueProviderResult"/> as an <see cref="IEnumerable{string}"/> to consume all values,
/// regardless of whether a single value or multiple values were submitted.
/// </para>
/// </remarks>
public struct ValueProviderResult : IEquatable<ValueProviderResult>, IEnumerable<string>
{
private static readonly CultureInfo _staticCulture = CultureInfo.InvariantCulture;
private static readonly CultureInfo _invariantCulture = CultureInfo.InvariantCulture;
/// <summary>
/// Instantiates a new instance of the <see cref="ValueProviderResult"/> class with given
/// <paramref name="rawValue"/>. Initializes <see cref="Culture"/> to
/// <see cref="CultureInfo.InvariantCulture"/>.
/// A <see cref="ValueProviderResult"/> that represents a lack of data.
/// </summary>
/// <param name="rawValue">The <see cref="RawValue"/> value of the new instance.</param>
public ValueProviderResult(object rawValue)
: this(rawValue, attemptedValue: null, culture: _staticCulture)
public static ValueProviderResult None = new ValueProviderResult(new string[0]);
/// <summary>
/// Creates a new <see cref="ValueProviderResult"/> using <see cref="CultureInfo.InvariantCulture"/>.
/// </summary>
/// <param name="value">The submitted value.</param>
public ValueProviderResult(string value)
: this(value, _invariantCulture)
{
}
/// <summary>
/// Instantiates a new instance of the <see cref="ValueProviderResult"/> class with given
/// <paramref name="rawValue"/>, <paramref name="attemptedValue"/>, and <paramref name="culture"/>.
/// Creates a new <see cref="ValueProviderResult"/>.
/// </summary>
/// <param name="rawValue">The <see cref="RawValue"/> value of the new instance.</param>
/// <param name="attemptedValue">The <see cref="AttemptedValue"/> value of the new instance.</param>
/// <param name="culture">The <see cref="Culture"/> value of the new instance.</param>
public ValueProviderResult(object rawValue, string attemptedValue, CultureInfo culture)
/// <param name="value">The submitted value.</param>
/// <param name="culture">The <see cref="CultureInfo"/> associated with this value.</param>
public ValueProviderResult(string value, CultureInfo culture)
{
RawValue = rawValue;
AttemptedValue = attemptedValue;
Culture = culture ?? _staticCulture;
}
/// <summary>
/// <see cref="string"/> conversion of <see cref="RawValue"/>.
/// </summary>
/// <remarks>
/// Used in helpers that generate <c>&lt;textarea&gt;</c> elements as well as some error messages.
/// </remarks>
public string AttemptedValue { get; }
/// <summary>
/// <see cref="CultureInfo"/> to use in <see cref="ConvertTo(Type)"/> or
/// <see cref="ConvertTo(Type, CultureInfo)"/> if passed <see cref="CultureInfo"/> is <c>null</c>.
/// </summary>
public CultureInfo Culture { get; }
/// <summary>
/// The provided <see cref="object"/>.
/// </summary>
public object RawValue { get; }
/// <summary>
/// Converts <see cref="RawValue"/> to the given <paramref name="type"/>. Uses <see cref="Culture"/> for
/// <see cref="TypeConverter"/> operations.
/// </summary>
/// <param name="type">The target <see cref="Type"/> of the conversion.</param>
/// <returns>
/// <see cref="RawValue"/> converted to the given <paramref name="type"/>. <c>null</c> if the conversion fails.
/// </returns>
public object ConvertTo(Type type)
{
return ConvertTo(type, culture: null);
}
/// <summary>
/// Converts <see cref="RawValue"/> to the given <paramref name="type"/> using the given
/// <paramref name="culture"/>.
/// </summary>
/// <param name="type">The target <see cref="Type"/> of the conversion.</param>
/// <param name="culture">
/// The <see cref="CultureInfo"/> to use for <see cref="TypeConverter"/> operations. Uses
/// <see cref="Culture"/> if this parameter is <c>null</c>.
/// </param>
/// <returns>
/// <see cref="RawValue"/> converted to the given <paramref name="type"/> using the given
/// <paramref name="culture"/>. <c>null</c> if the conversion fails.
/// </returns>
public virtual object ConvertTo([NotNull] Type type, CultureInfo culture)
{
var value = RawValue;
if (value == null)
{
// treat null route parameters as though they were the default value for the type
return type.GetTypeInfo().IsValueType ? Activator.CreateInstance(type) :
null;
Value = null;
Values = None.Values;
}
if (value.GetType().IsAssignableFrom(type))
else
{
return value;
Value = value;
Values = null;
}
var cultureToUse = culture ?? Culture;
return UnwrapPossibleArrayType(cultureToUse, value, type);
Culture = culture ?? _invariantCulture;
}
private object UnwrapPossibleArrayType(CultureInfo culture, object value, Type destinationType)
/// <summary>
/// Creates a new <see cref="ValueProviderResult"/> using <see cref="CultureInfo.InvariantCulture"/>.
/// </summary>
/// <param name="values">The submitted values.</param>
public ValueProviderResult(string[] values)
: this(values, _invariantCulture)
{
// array conversion results in four cases, as below
var valueAsArray = value as Array;
if (destinationType.IsArray)
}
/// <summary>
/// Creates a new <see cref="ValueProviderResult"/>.
/// </summary>
/// <param name="values">The submitted values.</param>
/// <param name="culture">The <see cref="CultureInfo"/> associated with these values.</param>
public ValueProviderResult(string[] values, CultureInfo culture)
{
if (values == null)
{
var destinationElementType = destinationType.GetElementType();
if (valueAsArray != null)
{
// case 1: both destination + source type are arrays, so convert each element
var converted = (IList)Array.CreateInstance(destinationElementType, valueAsArray.Length);
for (var i = 0; i < valueAsArray.Length; i++)
{
converted[i] = ConvertSimpleType(culture, valueAsArray.GetValue(i), destinationElementType);
}
return converted;
}
else
{
// case 2: destination type is array but source is single element, so wrap element in
// array + convert
var element = ConvertSimpleType(culture, value, destinationElementType);
var converted = (IList)Array.CreateInstance(destinationElementType, 1);
converted[0] = element;
return converted;
}
Value = null;
Values = None.Values;
}
else if (valueAsArray != null)
else
{
// case 3: destination type is single element but source is array, so extract first element + convert
if (valueAsArray.Length > 0)
Value = null;
Values = values;
}
Culture = culture;
}
/// <summary>
/// Gets or sets the <see cref="CultureInfo"/> associated with the values.
/// </summary>
public CultureInfo Culture { get; private set; }
/// <summary>
/// Gets or sets a single value. Will be <c>null</c> if multiple values are present.
/// </summary>
public string Value { get; private set; }
/// <summary>
/// Gets or sets an array of values. Will be <c>null</c> if only a single value was provided.
/// </summary>
public string[] Values { get; private set; }
/// <summary>
/// Gets the first value based on the order values were provided in the request. Use <see cref="FirstValue"/>
/// to get a single value for processing regarless of whether a single or multiple values were provided
/// in the request.
/// </summary>
public string FirstValue
{
get
{
if (Value != null)
{
value = valueAsArray.GetValue(0);
return ConvertSimpleType(culture, value, destinationType);
return Value;
}
else if (Values != null && Values.Length > 0)
{
return Values[0];
}
else
{
// case 3(a): source is empty array, so can't perform conversion
return null;
}
}
// case 4: both destination + source type are single elements, so convert
return ConvertSimpleType(culture, value, destinationType);
}
private object ConvertSimpleType(CultureInfo culture, object value, Type destinationType)
/// <summary>
/// Gets the number of submitted values.
/// </summary>
public int Length
{
if (value == null || value.GetType().IsAssignableFrom(destinationType))
get
{
return value;
}
// In case of a Nullable object, we try again with its underlying type.
destinationType = UnwrapNullableType(destinationType);
// if this is a user-input value but the user didn't type anything, return no value
var valueAsString = value as string;
if (valueAsString != null && string.IsNullOrWhiteSpace(valueAsString))
{
return null;
}
var converter = TypeDescriptor.GetConverter(destinationType);
var canConvertFrom = converter.CanConvertFrom(value.GetType());
if (!canConvertFrom)
{
converter = TypeDescriptor.GetConverter(value.GetType());
}
if (!(canConvertFrom || converter.CanConvertTo(destinationType)))
{
// EnumConverter cannot convert integer, so we verify manually
if (destinationType.GetTypeInfo().IsEnum &&
(value is int ||
value is uint ||
value is long ||
value is ulong ||
value is short ||
value is ushort ||
value is byte ||
value is sbyte))
if (Values != null)
{
return Enum.ToObject(destinationType, value);
return Values.Length;
}
throw new InvalidOperationException(
Resources.FormatValueProviderResult_NoConverterExists(value.GetType(), destinationType));
}
try
{
return canConvertFrom
? converter.ConvertFrom(null, culture, value)
: converter.ConvertTo(null, culture, value, destinationType);
}
catch (Exception ex)
{
if (ex is FormatException)
else if (Value != null)
{
throw ex;
return 1;
}
else
{
// TypeConverter throws System.Exception wrapping the FormatException,
// so we throw the inner exception.
ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
// this code is never reached because the previous line is throwing;
throw;
return 0;
}
}
}
private static Type UnwrapNullableType(Type destinationType)
/// <inheritdoc />
public override bool Equals(object obj)
{
return Nullable.GetUnderlyingType(destinationType) ?? destinationType;
var other = obj as ValueProviderResult?;
return other.HasValue ? Equals(other.Value) : false;
}
/// <inheritdoc />
public bool Equals(ValueProviderResult other)
{
if (Length != other.Length)
{
return false;
}
else
{
var x = (string[])this;
var y = (string[])other;
for (var i = 0; i < x.Length; i++)
{
if (!string.Equals(x[i], y[i], StringComparison.Ordinal))
{
return false;
}
}
return true;
}
}
/// <inheritdoc />
public override int GetHashCode()
{
return ((string)this)?.GetHashCode() ?? 0;
}
/// <inheritdoc />
public override string ToString()
{
return (string)this;
}
/// <summary>
/// Gets an <see cref="Enumerator"/> for this <see cref="ValueProviderResult"/>.
/// </summary>
/// <returns>An <see cref="Enumerator"/>.</returns>
public Enumerator GetEnumerator()
{
return new Enumerator(this);
}
/// <inheritdoc />
IEnumerator<string> IEnumerable<string>.GetEnumerator()
{
return GetEnumerator();
}
/// <inheritdoc />
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
/// <summary>
/// Converts the provided <see cref="ValueProviderResult"/> into a comma-separated string containing all
/// submitted values.
/// </summary>
/// <param name="result">The <see cref="ValueProviderResult"/>.</param>
public static explicit operator string(ValueProviderResult result)
{
if (result.Values == null)
{
return result.Value;
}
else if (result.Values.Length == 0)
{
return null;
}
else if (result.Values.Length == 1)
{
return result.Values[0];
}
else
{
return string.Join(",", result.Values);
}
}
/// <summary>
/// Converts the provided <see cref="ValueProviderResult"/> into a an array of <see cref="string"/> containing
/// all submitted values.
/// </summary>
/// <param name="result">The <see cref="ValueProviderResult"/>.</param>
public static explicit operator string[](ValueProviderResult result)
{
if (result.Values != null)
{
return result.Values;
}
else if (result.Value != null)
{
return new string[] { result.Value };
}
else
{
return None.Values;
}
}
/// <summary>
/// Compares two <see cref="ValueProviderResult"/> objects for equality.
/// </summary>
/// <param name="x">A <see cref="ValueProviderResult"/>.</param>
/// <param name="y">A <see cref="ValueProviderResult"/>.</param>
/// <returns><c>true</c> if the values are equal, otherwise <c>false</c>.</returns>
public static bool operator ==(ValueProviderResult x, ValueProviderResult y)
{
return x.Equals(y);
}
/// <summary>
/// Compares two <see cref="ValueProviderResult"/> objects for inequality.
/// </summary>
/// <param name="x">A <see cref="ValueProviderResult"/>.</param>
/// <param name="y">A <see cref="ValueProviderResult"/>.</param>
/// <returns><c>false</c> if the values are equal, otherwise <c>true</c>.</returns>
public static bool operator !=(ValueProviderResult x, ValueProviderResult y)
{
return !x.Equals(y);
}
/// <summary>
/// An enumerator for <see cref="ValueProviderResult"/>.
/// </summary>
public struct Enumerator : IEnumerator<string>
{
private readonly ValueProviderResult _result;
private readonly int _length;
private int _index;
/// <summary>
/// Creates a new <see cref="Enumerator"/>.
/// </summary>
/// <param name="result">The <see cref="ValueProviderResult"/>.</param>
public Enumerator(ValueProviderResult result)
{
_result = result;
_index = -1;
_length = result.Length;
Current = null;
}
/// <inheritdoc />
public string Current { get; private set; }
/// <inheritdoc />
object IEnumerator.Current => Current;
/// <inheritdoc />
public void Dispose()
{
}
/// <inheritdoc />
public bool MoveNext()
{
++_index;
if (_index < _length)
{
if (_result.Values != null)
{
Debug.Assert(_index < _result.Values.Length);
Current = _result.Values[_index];
return true;
}
else if (_result.Value != null && _index == 0)
{
Current = _result.Value;
return true;
}
else
{
return false;
}
}
Current = null;
return false;
}
/// <inheritdoc />
public void Reset()
{
_index = -1;
}
}
}
}

View File

@ -74,38 +74,6 @@ namespace Microsoft.AspNet.Mvc.Abstractions
return GetString("Validation_InvalidFieldCannotBeReset_ToSkipped");
}
/// <summary>
/// Cannot convert value '{0}' to enum type '{1}'.
/// </summary>
internal static string ValueProviderResult_CannotConvertEnum
{
get { return GetString("ValueProviderResult_CannotConvertEnum"); }
}
/// <summary>
/// Cannot convert value '{0}' to enum type '{1}'.
/// </summary>
internal static string FormatValueProviderResult_CannotConvertEnum(object p0, object p1)
{
return string.Format(CultureInfo.CurrentCulture, GetString("ValueProviderResult_CannotConvertEnum"), p0, p1);
}
/// <summary>
/// The parameter conversion from type '{0}' to type '{1}' failed because no type converter can convert between these types.
/// </summary>
internal static string ValueProviderResult_NoConverterExists
{
get { return GetString("ValueProviderResult_NoConverterExists"); }
}
/// <summary>
/// The parameter conversion from type '{0}' to type '{1}' failed because no type converter can convert between these types.
/// </summary>
internal static string FormatValueProviderResult_NoConverterExists(object p0, object p1)
{
return string.Format(CultureInfo.CurrentCulture, GetString("ValueProviderResult_NoConverterExists"), p0, p1);
}
/// <summary>
/// The maximum number of allowed model errors has been reached.
/// </summary>

View File

@ -129,12 +129,6 @@
<data name="Validation_InvalidFieldCannotBeReset_ToSkipped" xml:space="preserve">
<value>A field previously marked invalid should not be marked skipped.</value>
</data>
<data name="ValueProviderResult_CannotConvertEnum" xml:space="preserve">
<value>Cannot convert value '{0}' to enum type '{1}'.</value>
</data>
<data name="ValueProviderResult_NoConverterExists" xml:space="preserve">
<value>The parameter conversion from type '{0}' to type '{1}' failed because no type converter can convert between these types.</value>
</data>
<data name="ModelStateDictionary_MaxModelStateErrors" xml:space="preserve">
<value>The maximum number of allowed model errors has been reached.</value>
</data>

View File

@ -58,6 +58,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
var previousCount = bindingContext.ModelState.ErrorCount;
var model = await formatter.ReadAsync(formatterContext);
bindingContext.ModelState.SetModelValue(modelBindingKey, rawValue: model, attemptedValue: null);
if (bindingContext.ModelState.ErrorCount != previousCount)
{
// Formatter added an error. Do not use the model it returned. As above, tell the model binding
@ -65,9 +67,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
return new ModelBindingResult(modelBindingKey);
}
var valueProviderResult = new ValueProviderResult(rawValue: model);
bindingContext.ModelState.SetModelValue(modelBindingKey, valueProviderResult);
var validationNode = new ModelValidationNode(modelBindingKey, bindingContext.ModelMetadata, model)
{
ValidateAllProperties = true

View File

@ -23,7 +23,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
// Check for missing data case 1: There was no <input ... /> element containing this data.
var valueProviderResult = await bindingContext.ValueProvider.GetValueAsync(bindingContext.ModelName);
if (valueProviderResult == null)
if (valueProviderResult == ValueProviderResult.None)
{
return new ModelBindingResult(model: null, key: bindingContext.ModelName, isModelSet: false);
}
@ -31,7 +31,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);
// Check for missing data case 2: There was an <input ... /> element but it was left blank.
var value = valueProviderResult.AttemptedValue;
var value = valueProviderResult.FirstValue;
if (string.IsNullOrEmpty(value))
{
return new ModelBindingResult(model: null, key: bindingContext.ModelName, isModelSet: false);

View File

@ -56,31 +56,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
var valueProviderResult = await bindingContext.ValueProvider.GetValueAsync(bindingContext.ModelName);
CollectionResult result;
if (valueProviderResult == null)
if (valueProviderResult == ValueProviderResult.None)
{
result = await BindComplexCollection(bindingContext);
}
else
{
if (valueProviderResult.RawValue == null)
{
// Value exists but is null. Handle similarly to fallback case above. This avoids a
// ModelBindingResult with IsModelSet = true but ValidationNode = null.
model = bindingContext.Model ?? CreateEmptyCollection(bindingContext.ModelType);
var validationNode =
new ModelValidationNode(bindingContext.ModelName, bindingContext.ModelMetadata, model);
return new ModelBindingResult(
model,
bindingContext.ModelName,
isModelSet: true,
validationNode: validationNode);
}
result = await BindSimpleCollection(
bindingContext,
valueProviderResult.RawValue,
valueProviderResult.Culture);
result = await BindSimpleCollection(bindingContext, valueProviderResult);
}
var boundCollection = result.Model;
@ -94,6 +76,15 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
CopyToModel(model, boundCollection);
}
if (valueProviderResult != ValueProviderResult.None)
{
// If we did simple binding, then modelstate should be updated to reflect what we bound for ModelName.
// If we did complex binding, there will already be an entry for each index.
bindingContext.ModelState.SetModelValue(
bindingContext.ModelName,
valueProviderResult);
}
return new ModelBindingResult(
model,
bindingContext.ModelName,
@ -147,8 +138,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
// Internal for testing.
internal async Task<CollectionResult> BindSimpleCollection(
ModelBindingContext bindingContext,
object rawValue,
CultureInfo culture)
ValueProviderResult values)
{
var boundCollection = new List<TElement>();
@ -159,8 +149,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
bindingContext.ModelName,
bindingContext.ModelMetadata,
boundCollection);
var rawValueArray = RawValueToObjectArray(rawValue);
foreach (var rawValueElement in rawValueArray)
foreach (var value in values)
{
var innerBindingContext = ModelBindingContext.GetChildModelBindingContext(
bindingContext,
@ -169,7 +158,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
innerBindingContext.ValueProvider = new CompositeValueProvider
{
// our temporary provider goes at the front of the list
new ElementalValueProvider(bindingContext.ModelName, rawValueElement, culture),
new ElementalValueProvider(bindingContext.ModelName, value, values.Culture),
bindingContext.ValueProvider
};
@ -183,8 +172,9 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
{
validationNode.ChildNodes.Add(result.ValidationNode);
}
boundCollection.Add(ModelBindingHelper.CastOrDefault<TElement>(boundValue));
}
boundCollection.Add(ModelBindingHelper.CastOrDefault<TElement>(boundValue));
}
return new CollectionResult
@ -364,7 +354,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
IEnumerable<string> indexNames = null;
if (valueProviderResult != null)
{
var indexes = (string[])valueProviderResult.ConvertTo(typeof(string[]));
var indexes = (string[])valueProviderResult;
if (indexes != null && indexes.Length > 0)
{
indexNames = indexes;

View File

@ -86,12 +86,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
{
var valueProvider = Items[i];
var result = await valueProvider.GetValueAsync(key);
if (result != null)
if (result != ValueProviderResult.None)
{
return result;
}
}
return null;
return ValueProviderResult.None;
}
/// <inheritdoc />

View File

@ -30,21 +30,23 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
_values = values;
}
protected PrefixContainer PrefixContainer
{
get
{
if (_prefixContainer == null)
{
_prefixContainer = new PrefixContainer(_values.Keys);
}
return _prefixContainer;
}
}
/// <inheritdoc />
public override Task<bool> ContainsPrefixAsync(string key)
{
var prefixContainer = GetOrCreatePrefixContainer();
return Task.FromResult(prefixContainer.ContainsPrefix(key));
}
private PrefixContainer GetOrCreatePrefixContainer()
{
if (_prefixContainer == null)
{
_prefixContainer = new PrefixContainer(_values.Keys);
}
return _prefixContainer;
return Task.FromResult(PrefixContainer.ContainsPrefix(key));
}
/// <inheritdoc />
@ -54,12 +56,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
ValueProviderResult result;
if (_values.TryGetValue(key, out value))
{
var attemptedValue = value != null ? value.ToString() : null;
result = new ValueProviderResult(value, attemptedValue, CultureInfo.InvariantCulture);
var stringValue = value as string ?? value?.ToString() ?? string.Empty;
result = new ValueProviderResult(stringValue, CultureInfo.InvariantCulture);
}
else
{
result = null;
result = ValueProviderResult.None;
}
return Task.FromResult(result);

View File

@ -65,15 +65,18 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
var modelBinder = bindingContext.OperationBindingContext.ModelBinder;
var validationNode = result.ValidationNode;
foreach (var key in keys)
foreach (var kvp in keys)
{
var dictionaryKey = ConvertFromString(key.Key);
valueBindingContext.ModelName = key.Value;
// Use InvariantCulture to convert the key since ExpressionHelper.GetExpressionText() would use
// that culture when rendering a form.
var convertedKey = ModelBindingHelper.ConvertTo<TKey>(kvp.Key, culture: null);
valueBindingContext.ModelName = kvp.Value;
var valueResult = await modelBinder.BindModelAsync(valueBindingContext);
// Always add an entry to the dictionary but validate only if binding was successful.
model[dictionaryKey] = ModelBindingHelper.CastOrDefault<TValue>(valueResult?.Model);
model[convertedKey] = ModelBindingHelper.CastOrDefault<TValue>(valueResult?.Model);
if (valueResult != null && valueResult.IsModelSet)
{
validationNode.ChildNodes.Add(valueResult.ValidationNode);
@ -116,14 +119,5 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
return CreateInstance(targetType);
}
private static TKey ConvertFromString(string keyString)
{
// Use InvariantCulture to convert string since ExpressionHelper.GetExpressionText() used that culture.
var keyResult = new ValueProviderResult(keyString);
var keyObject = keyResult.ConvertTo(typeof(TKey));
return ModelBindingHelper.CastOrDefault<TKey>(keyObject);
}
}
}

View File

@ -7,33 +7,36 @@ using System.Threading.Tasks;
namespace Microsoft.AspNet.Mvc.ModelBinding
{
// Represents a value provider that contains a single value.
internal sealed class ElementalValueProvider : IValueProvider
public class ElementalValueProvider : IValueProvider
{
public ElementalValueProvider(string name, object rawValue, CultureInfo culture)
public ElementalValueProvider(string key, string value, CultureInfo culture)
{
Name = name;
RawValue = rawValue;
Key = key;
Value = value;
Culture = culture;
}
public CultureInfo Culture { get; private set; }
public CultureInfo Culture { get; }
public string Name { get; private set; }
public string Key { get; }
public object RawValue { get; private set; }
public string Value { get; }
public Task<bool> ContainsPrefixAsync(string prefix)
{
return Task.FromResult(PrefixContainer.IsPrefixMatch(prefix, Name));
return Task.FromResult(PrefixContainer.IsPrefixMatch(prefix, Key));
}
public Task<ValueProviderResult> GetValueAsync(string key)
{
var result = string.Equals(key, Name, StringComparison.OrdinalIgnoreCase) ?
new ValueProviderResult(RawValue, Convert.ToString(RawValue, Culture), Culture) :
null;
return Task.FromResult(result);
if (string.Equals(key, Key, StringComparison.OrdinalIgnoreCase))
{
return Task.FromResult(new ValueProviderResult(Value, Culture));
}
else
{
return Task.FromResult(ValueProviderResult.None);
}
}
}
}

View File

@ -48,8 +48,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
SuppressValidation = true,
};
var valueProviderResult = new ValueProviderResult(rawValue: value);
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);
bindingContext.ModelState.SetModelValue(
bindingContext.ModelName,
rawValue: null,
attemptedValue: null);
}
return new ModelBindingResult(

View File

@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
#if DNXCORE50
using System.Reflection;
#endif
@ -61,9 +61,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
bindingContext.ModelMetadata,
model);
var attemptedValue = (model as string) ?? request.Headers.Get(headerName);
var valueProviderResult = new ValueProviderResult(model, attemptedValue, CultureInfo.InvariantCulture);
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);
bindingContext.ModelState.SetModelValue(
bindingContext.ModelName,
request.Headers.GetCommaSeparatedValues(headerName).ToArray(),
request.Headers.Get(headerName));
}
return Task.FromResult(

View File

@ -73,16 +73,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
string[] values;
if (dictionary.TryGetValue(key, out values) && values != null && values.Length > 0)
{
// Success.
if (values.Length == 1)
{
return new ValueProviderResult(values[0], values[0], Culture);
}
return new ValueProviderResult(values, string.Join(",", values), Culture);
return new ValueProviderResult(values, Culture);
}
return null;
return ValueProviderResult.None;
}
private async Task<IDictionary<string, string[]>> GetDictionary()

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.Framework.Internal;
@ -85,16 +86,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
ValueProviderResult result;
if (values == null)
{
result = null;
}
else if (values.Count == 1)
{
var value = (string)values[0];
result = new ValueProviderResult(value, value, _culture);
result = ValueProviderResult.None;
}
else
{
result = new ValueProviderResult(values, _values.Get(key), _culture);
result = new ValueProviderResult(values.ToArray(), _culture);
}
return result;

View File

@ -8,12 +8,10 @@ using Microsoft.AspNet.Mvc.Core;
namespace Microsoft.AspNet.Mvc.ModelBinding
{
public sealed class TypeConverterModelBinder : IModelBinder
public class SimpleTypeModelBinder : IModelBinder
{
public async Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext)
{
ModelBindingHelper.ValidateBindingContext(bindingContext);
if (bindingContext.ModelMetadata.IsComplexType)
{
// this type cannot be converted
@ -21,38 +19,48 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
}
var valueProviderResult = await bindingContext.ValueProvider.GetValueAsync(bindingContext.ModelName);
if (valueProviderResult == null)
if (valueProviderResult == ValueProviderResult.None)
{
// no entry
return null;
}
object newModel;
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);
try
{
newModel = valueProviderResult.ConvertTo(bindingContext.ModelType);
ModelBindingHelper.ReplaceEmptyStringWithNull(bindingContext.ModelMetadata, ref newModel);
var model = valueProviderResult.ConvertTo(bindingContext.ModelType);
if (bindingContext.ModelType == typeof(string))
{
var modelAsString = model as string;
if (bindingContext.ModelMetadata.ConvertEmptyStringToNull &&
string.IsNullOrWhiteSpace(modelAsString))
{
model = null;
}
}
var isModelSet = true;
// When converting newModel a null value may indicate a failed conversion for an otherwise required
// model (can't set a ValueType to null). This detects if a null model value is acceptable given the
// current bindingContext. If not, an error is logged.
if (newModel == null && !AllowsNullValue(bindingContext.ModelType))
if (model == null && !AllowsNullValue(bindingContext.ModelType))
{
bindingContext.ModelState.TryAddModelError(
bindingContext.ModelName,
Resources.FormatCommon_ValueNotValidForProperty(newModel));
Resources.FormatCommon_ValueNotValidForProperty(model));
isModelSet = false;
}
// Include a ModelValidationNode if binding succeeded.
var validationNode = isModelSet ?
new ModelValidationNode(bindingContext.ModelName, bindingContext.ModelMetadata, newModel) :
new ModelValidationNode(bindingContext.ModelName, bindingContext.ModelMetadata, model) :
null;
return new ModelBindingResult(newModel, bindingContext.ModelName, isModelSet, validationNode);
return new ModelBindingResult(model, bindingContext.ModelName, isModelSet, validationNode);
}
catch (Exception ex)
{

View File

@ -1,67 +0,0 @@
// 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.Reflection;
using System.Threading.Tasks;
using Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Mvc.ModelBinding
{
public sealed class TypeMatchModelBinder : IModelBinder
{
public async Task<ModelBindingResult> BindModelAsync(ModelBindingContext bindingContext)
{
var valueProviderResult = await GetCompatibleValueProviderResult(bindingContext);
if (valueProviderResult == null)
{
// conversion would have failed
return null;
}
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult);
var model = valueProviderResult.RawValue;
ModelBindingHelper.ReplaceEmptyStringWithNull(bindingContext.ModelMetadata, ref model);
var validationNode = new ModelValidationNode(
bindingContext.ModelName,
bindingContext.ModelMetadata,
model);
return new ModelBindingResult(
model,
bindingContext.ModelName,
isModelSet: true,
validationNode: validationNode);
}
internal static async Task<ValueProviderResult> GetCompatibleValueProviderResult(ModelBindingContext context)
{
ModelBindingHelper.ValidateBindingContext(context);
var valueProviderResult = await context.ValueProvider.GetValueAsync(context.ModelName);
if (valueProviderResult == null)
{
return null; // the value doesn't exist
}
if (!IsCompatibleWith(context.ModelType, valueProviderResult.RawValue))
{
return null; // value is of incompatible type
}
return valueProviderResult;
}
private static bool IsCompatibleWith([NotNull] Type type, object value)
{
if (value == null)
{
return !type.GetTypeInfo().IsValueType || Nullable.GetUnderlyingType(type) != null;
}
else
{
return type.GetTypeInfo().IsAssignableFrom(value.GetType().GetTypeInfo());
}
}
}
}

View File

@ -0,0 +1,42 @@
// 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 Microsoft.Framework.Internal;
namespace Microsoft.AspNet.Mvc.ModelBinding
{
/// <summary>
/// Extensions methods for <see cref="ValueProviderResult"/>.
/// </summary>
public static class ValueProviderResultExtensions
{
/// <summary>
/// Attempts to convert the values in <paramref name="result"/> to the specified type.
/// </summary>
/// <typeparam name="T">The <see cref="Type"/> for conversion.</typeparam>
/// <param name="result">The <see cref="ValueProviderResult"/>.</param>
/// <returns>
/// The converted value, or the default value of <typeparamref name="T"/> if the value could not be converted.
/// </returns>
public static T ConvertTo<T>(this ValueProviderResult result)
{
var valueToConvert = (object)result.Values ?? (object)result.Value;
return ModelBindingHelper.ConvertTo<T>(valueToConvert, result.Culture);
}
/// <summary>
/// Attempts to convert the values in <paramref name="result"/> to the specified type.
/// </summary>
/// <param name="result">The <see cref="ValueProviderResult"/>.</param>
/// <param name="type">The <see cref="Type"/> for conversion.</param>
/// <returns>
/// The converted value, or the default value of <paramref name="type"/> if the value could not be converted.
/// </returns>
public static object ConvertTo(this ValueProviderResult result, [NotNull] Type type)
{
var valueToConvert = (object)result.Values ?? (object)result.Value;
return ModelBindingHelper.ConvertTo(valueToConvert, type, result.Culture);
}
}
}

View File

@ -2,10 +2,14 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.ExceptionServices;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Mvc.Core;
@ -488,16 +492,6 @@ namespace Microsoft.AspNet.Mvc
return (model is TModel) ? (TModel)model : default(TModel);
}
internal static void ReplaceEmptyStringWithNull(ModelMetadata modelMetadata, ref object model)
{
if (model is string &&
modelMetadata.ConvertEmptyStringToNull &&
string.IsNullOrWhiteSpace(model as string))
{
model = null;
}
}
public static object ConvertValuesToCollectionType<T>(Type modelType, IList<T> values)
{
// There's a limited set of collection types we can support here.
@ -539,5 +533,196 @@ namespace Microsoft.AspNet.Mvc
return null;
}
}
/// <summary>
/// Converts the provided <paramref name="value"/> to a value of <see cref="Type"/> <typeparamref name="T"/>
/// using the <see cref="CultureInfo.InvariantCulture"/>.
/// </summary>
/// <typeparam name="T">The <see cref="Type"/> for conversion.</typeparam>
/// <param name="value">The value to convert."/></param>
/// <returns>
/// The converted value or the default value of <typeparamref name="T"/> if the value could not be converted.
/// </returns>
public static T ConvertTo<T>(object value)
{
return ConvertTo<T>(value, culture: null);
}
/// <summary>
/// Converts the provided <paramref name="value"/> to a value of <see cref="Type"/> <typeparamref name="T"/>.
/// </summary>
/// <typeparam name="T">The <see cref="Type"/> for conversion.</typeparam>
/// <param name="value">The value to convert."/></param>
/// <param name="culture">The <see cref="CultureInfo"/> for conversion.</param>
/// <returns>
/// The converted value or the default value of <typeparamref name="T"/> if the value could not be converted.
/// </returns>
public static T ConvertTo<T>(object value, CultureInfo culture)
{
var converted = ConvertTo(value, typeof(T), culture);
return converted == null ? default(T) : (T)converted;
}
/// <summary>
/// Converts the provided <paramref name="value"/> to a value of <see cref="Type"/> <param name="type"/>
/// using the <see cref="CultureInfo.InvariantCulture"/>.
/// </summary>
/// <param name="value">The value to convert."/></param>
/// <param name="type">The <see cref="Type"/> for conversion.</param>
/// <returns>
/// The converted value or <c>null</c> if the value could not be converted.
/// </returns>
public static object ConvertTo(object value, [NotNull] Type type)
{
return ConvertTo(value, type, culture: null);
}
/// <summary>
/// Converts the provided <paramref name="value"/> to a value of <see cref="Type"/> <paramref name="type"/>.
/// </summary>
/// <param name="value">The value to convert."/></param>
/// <param name="type">The <see cref="Type"/> for conversion.</param>
/// <param name="culture">The <see cref="CultureInfo"/> for conversion.</param>
/// <returns>
/// The converted value or <c>null</c> if the value could not be converted.
/// </returns>
public static object ConvertTo(object value, [NotNull] Type type, CultureInfo culture)
{
if (value == null)
{
// For value types, treat null values as though they were the default value for the type.
return type.GetTypeInfo().IsValueType ? Activator.CreateInstance(type) : null;
}
if (value.GetType().IsAssignableFrom(type))
{
return value;
}
var cultureToUse = culture ?? CultureInfo.InvariantCulture;
return UnwrapPossibleArrayType(value, type, cultureToUse);
}
private static object UnwrapPossibleArrayType(object value, Type destinationType, CultureInfo culture)
{
// array conversion results in four cases, as below
var valueAsArray = value as Array;
if (destinationType.IsArray)
{
var destinationElementType = destinationType.GetElementType();
if (valueAsArray != null)
{
// case 1: both destination + source type are arrays, so convert each element
var converted = (IList)Array.CreateInstance(destinationElementType, valueAsArray.Length);
for (var i = 0; i < valueAsArray.Length; i++)
{
converted[i] = ConvertSimpleType(valueAsArray.GetValue(i), destinationElementType, culture);
}
return converted;
}
else
{
// case 2: destination type is array but source is single element, so wrap element in
// array + convert
var element = ConvertSimpleType(value, destinationElementType, culture);
var converted = (IList)Array.CreateInstance(destinationElementType, 1);
converted[0] = element;
return converted;
}
}
else if (valueAsArray != null)
{
// case 3: destination type is single element but source is array, so extract first element + convert
if (valueAsArray.Length > 0)
{
value = valueAsArray.GetValue(0);
return ConvertSimpleType(value, destinationType, culture);
}
else
{
// case 3(a): source is empty array, so can't perform conversion
return null;
}
}
// case 4: both destination + source type are single elements, so convert
return ConvertSimpleType(value, destinationType, culture);
}
private static object ConvertSimpleType(object value, Type destinationType, CultureInfo culture)
{
if (value == null || value.GetType().IsAssignableFrom(destinationType))
{
return value;
}
// In case of a Nullable object, we try again with its underlying type.
destinationType = UnwrapNullableType(destinationType);
// if this is a user-input value but the user didn't type anything, return no value
var valueAsString = value as string;
if (valueAsString != null && string.IsNullOrWhiteSpace(valueAsString))
{
return null;
}
var converter = TypeDescriptor.GetConverter(destinationType);
var canConvertFrom = converter.CanConvertFrom(value.GetType());
if (!canConvertFrom)
{
converter = TypeDescriptor.GetConverter(value.GetType());
}
if (!(canConvertFrom || converter.CanConvertTo(destinationType)))
{
// EnumConverter cannot convert integer, so we verify manually
if (destinationType.GetTypeInfo().IsEnum &&
(value is int ||
value is uint ||
value is long ||
value is ulong ||
value is short ||
value is ushort ||
value is byte ||
value is sbyte))
{
return Enum.ToObject(destinationType, value);
}
throw new InvalidOperationException(
Resources.FormatValueProviderResult_NoConverterExists(value.GetType(), destinationType));
}
try
{
return canConvertFrom
? converter.ConvertFrom(null, culture, value)
: converter.ConvertTo(null, culture, value, destinationType);
}
catch (FormatException)
{
throw;
}
catch (Exception ex)
{
if (ex.InnerException == null)
{
throw;
}
else
{
// TypeConverter throws System.Exception wrapping the FormatException,
// so we throw the inner exception.
ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
// This code is never reached because the previous line will always throw.
throw;
}
}
}
private static Type UnwrapNullableType(Type destinationType)
{
return Nullable.GetUnderlyingType(destinationType) ?? destinationType;
}
}
}

View File

@ -28,8 +28,7 @@ namespace Microsoft.AspNet.Mvc
options.ModelBinders.Add(new ServicesModelBinder());
options.ModelBinders.Add(new BodyModelBinder());
options.ModelBinders.Add(new HeaderModelBinder());
options.ModelBinders.Add(new TypeConverterModelBinder());
options.ModelBinders.Add(new TypeMatchModelBinder());
options.ModelBinders.Add(new SimpleTypeModelBinder());
options.ModelBinders.Add(new CancellationTokenModelBinder());
options.ModelBinders.Add(new ByteArrayModelBinder());
options.ModelBinders.Add(new FormFileModelBinder());

View File

@ -1162,6 +1162,38 @@ namespace Microsoft.AspNet.Mvc.Core
return string.Format(CultureInfo.CurrentCulture, GetString("ValidatableObjectAdapter_IncompatibleType"), p0, p1);
}
/// <summary>
/// Cannot convert value '{0}' to enum type '{1}'.
/// </summary>
internal static string ValueProviderResult_CannotConvertEnum
{
get { return GetString("ValueProviderResult_CannotConvertEnum"); }
}
/// <summary>
/// Cannot convert value '{0}' to enum type '{1}'.
/// </summary>
internal static string FormatValueProviderResult_CannotConvertEnum(object p0, object p1)
{
return string.Format(CultureInfo.CurrentCulture, GetString("ValueProviderResult_CannotConvertEnum"), p0, p1);
}
/// <summary>
/// The parameter conversion from type '{0}' to type '{1}' failed because no type converter can convert between these types.
/// </summary>
internal static string ValueProviderResult_NoConverterExists
{
get { return GetString("ValueProviderResult_NoConverterExists"); }
}
/// <summary>
/// The parameter conversion from type '{0}' to type '{1}' failed because no type converter can convert between these types.
/// </summary>
internal static string FormatValueProviderResult_NoConverterExists(object p0, object p1)
{
return string.Format(CultureInfo.CurrentCulture, GetString("ValueProviderResult_NoConverterExists"), p0, p1);
}
private static string GetString(string name, params string[] formatterNames)
{
var value = _resourceManager.GetString(name);

View File

@ -342,4 +342,10 @@
<data name="ValidatableObjectAdapter_IncompatibleType" xml:space="preserve">
<value>The model object inside the metadata claimed to be compatible with '{0}', but was actually '{1}'.</value>
</data>
<data name="ValueProviderResult_CannotConvertEnum" xml:space="preserve">
<value>Cannot convert value '{0}' to enum type '{1}'.</value>
</data>
<data name="ValueProviderResult_NoConverterExists" xml:space="preserve">
<value>The parameter conversion from type '{0}' to type '{1}' failed because no type converter can convert between these types.</value>
</data>
</root>

View File

@ -506,9 +506,9 @@ namespace Microsoft.AspNet.Mvc.Rendering
viewContext.ViewData.ModelState.TryGetValue(fullName, out modelState);
var value = string.Empty;
if (modelState != null && modelState.Value != null)
if (modelState != null && modelState.AttemptedValue != null)
{
value = modelState.Value.AttemptedValue;
value = modelState.AttemptedValue;
}
else if (modelExplorer.Model != null)
{
@ -940,9 +940,9 @@ namespace Microsoft.AspNet.Mvc.Rendering
internal static object GetModelStateValue(ViewContext viewContext, string key, Type destinationType)
{
ModelState modelState;
if (viewContext.ViewData.ModelState.TryGetValue(key, out modelState) && modelState.Value != null)
if (viewContext.ViewData.ModelState.TryGetValue(key, out modelState) && modelState.RawValue != null)
{
return modelState.Value.ConvertTo(destinationType, culture: null);
return ModelBindingHelper.ConvertTo(modelState.RawValue, destinationType, culture: null);
}
return null;

View File

@ -24,8 +24,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
return string.Empty;
}
var attemptedValue = (modelState.Value != null) ? modelState.Value.AttemptedValue : "null";
var attemptedValue = modelState.AttemptedValue ?? "null";
return Resources.FormatCommon_ValueNotValidForProperty(attemptedValue);
}

View File

@ -18,7 +18,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
// Arrange
var modelState = new ModelState
{
Value = GetValueProviderResult("value"),
ValidationState = validationState
};
@ -40,7 +39,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
// Arrange
var modelState = new ModelState
{
Value = GetValueProviderResult("value"),
ValidationState = ModelValidationState.Valid
};
@ -63,7 +61,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
// Arrange
var modelState = new ModelState
{
Value = GetValueProviderResult("value"),
ValidationState = ModelValidationState.Invalid
};
@ -89,7 +86,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
// Arrange
var modelState = new ModelState
{
Value = GetValueProviderResult("value"),
ValidationState = validationState
};
@ -126,7 +122,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
// Arrange
var modelState = new ModelState
{
Value = GetValueProviderResult("value"),
ValidationState = ModelValidationState.Invalid
};
@ -148,10 +143,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
public void CopyConstructor_CopiesModelStateData()
{
// Arrange
var modelState = new ModelState
{
Value = GetValueProviderResult("value")
};
var modelState = new ModelState();
var source = new ModelStateDictionary
{
{ "key", modelState }
@ -211,7 +203,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
// Arrange
var oldDictionary = new ModelStateDictionary()
{
{ "foo", new ModelState() { Value = GetValueProviderResult("bar", "bar") } }
{ "foo", new ModelState() { RawValue = "bar" } }
};
// Act
@ -219,7 +211,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
// Assert
Assert.Single(newDictionary);
Assert.Equal("bar", newDictionary["foo"].Value.ConvertTo(typeof(string)));
Assert.Equal("bar", newDictionary["foo"].RawValue);
}
[Fact]
@ -238,7 +230,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
[Fact]
public void GetValidationState_ReturnsValidationStateForKey_IgnoresChildren()
{
// Arrange
// Arrange
var msd = new ModelStateDictionary();
msd.AddModelError("foo.bar", "error text");
@ -277,7 +269,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
// Arrange
var validState = new ModelState
{
Value = new ValueProviderResult(rawValue: null),
ValidationState = ModelValidationState.Valid
};
var msd = new ModelStateDictionary
@ -316,7 +307,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
// Arrange
var validState = new ModelState
{
Value = new ValueProviderResult(rawValue: null),
ValidationState = ModelValidationState.Valid
};
var msd = new ModelStateDictionary
@ -337,12 +327,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
// Arrange
var errorState = new ModelState
{
Value = GetValueProviderResult("quux", "quux"),
ValidationState = ModelValidationState.Invalid
};
var validState = new ModelState
{
Value = GetValueProviderResult("bar", "bar"),
ValidationState = ModelValidationState.Valid
};
errorState.Errors.Add("some error");
@ -370,13 +358,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
{ "foo", new ModelState
{
ValidationState = ModelValidationState.Valid,
Value = GetValueProviderResult("bar", "bar")
}
},
{ "baz", new ModelState
{
ValidationState = ModelValidationState.Skipped,
Value = GetValueProviderResult("quux", "bar")
}
}
};
@ -396,12 +382,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
// Arrange
var errorState = new ModelState
{
Value = GetValueProviderResult("quux", "quux"),
ValidationState = ModelValidationState.Invalid
};
var validState = new ModelState
{
Value = GetValueProviderResult("bar", "bar"),
ValidationState = ModelValidationState.Valid
};
errorState.Errors.Add("some error");
@ -409,7 +393,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
{
{ "foo", validState },
{ "baz", errorState },
{ "qux", new ModelState { Value = GetValueProviderResult() }}
{ "qux", new ModelState() }
};
// Act
@ -457,14 +441,15 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
var dictionary = new ModelStateDictionary();
// Act
dictionary.SetModelValue("some key", GetValueProviderResult("some value", "some value"));
dictionary.SetModelValue("some key", new string[] { "some value" }, "some value");
// Assert
Assert.Single(dictionary);
var modelState = dictionary["some key"];
Assert.Empty(modelState.Errors);
Assert.Equal("some value", modelState.Value.ConvertTo(typeof(string)));
Assert.Equal(new string[] { "some value" }, modelState.RawValue);
Assert.Equal("some value", modelState.AttemptedValue);
}
[Fact]
@ -476,7 +461,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
var ex = new Exception();
// Act
dictionary.SetModelValue("some key", GetValueProviderResult("some value", "some value"));
dictionary.SetModelValue("some key", new string[] { "some value" }, "some value");
// Assert
Assert.Single(dictionary);
@ -484,7 +469,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
Assert.Single(modelState.Errors);
Assert.Equal("some error", modelState.Errors[0].ErrorMessage);
Assert.Equal("some value", modelState.Value.ConvertTo(typeof(string)));
Assert.Equal(new string[] { "some value" }, modelState.RawValue);
Assert.Equal("some value", modelState.AttemptedValue);
}
[Fact]
@ -492,7 +478,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
{
// Arrange
var dictionary = new ModelStateDictionary();
dictionary.SetModelValue("user.Name", GetValueProviderResult());
dictionary.SetModelValue("user.Name", new string[] { "some value" }, "some value");
// Act
var validationState = dictionary.GetFieldValidationState("not-user");
@ -507,7 +493,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
// Arrange
var dictionary = new ModelStateDictionary();
dictionary["user.Address"] = new ModelState { ValidationState = ModelValidationState.Valid };
dictionary.SetModelValue("user.Name", GetValueProviderResult());
dictionary.SetModelValue("user.Name", new string[] { "some value" }, "some value");
dictionary.AddModelError("user.Age", "Age is not a valid int");
// Act
@ -745,7 +731,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
// Arrange
var expected = "The value 'some value' is not valid for key.";
var dictionary = new ModelStateDictionary();
dictionary.SetModelValue("key", GetValueProviderResult());
dictionary.SetModelValue("key", new string[] { "some value" }, "some value");
// Act
dictionary.TryAddModelError("key", new FormatException());
@ -760,7 +746,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
{
// Arrange
var dictionary = new ModelStateDictionary();
dictionary.SetModelValue("key", GetValueProviderResult());
dictionary.SetModelValue("key", new string[] { "some value" }, "some value");
// Act
dictionary.TryAddModelError("key", new InvalidOperationException());
@ -905,12 +891,5 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
Assert.Equal(0, dictionary["Property4"].Errors.Count);
Assert.Equal(ModelValidationState.Unvalidated, dictionary["Property4"].ValidationState);
}
private static ValueProviderResult GetValueProviderResult(object rawValue = null, string attemptedValue = null)
{
return new ValueProviderResult(rawValue ?? "some value",
attemptedValue ?? "some value",
CultureInfo.InvariantCulture);
}
}
}

View File

@ -1,9 +1,6 @@
// Copyright (c) .NET Foundation. All rights reserved.
// 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.Globalization;
using Xunit;
namespace Microsoft.AspNet.Mvc.ModelBinding
@ -11,563 +8,190 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
public class ValueProviderResultTest
{
[Fact]
public void ConvertTo_ReturnsNullForReferenceTypes_WhenValueIsNull()
public void Construct_With_NullString()
{
var valueProviderResult = new ValueProviderResult(rawValue: null);
// Arrange & Act
var result = new ValueProviderResult((string)null);
var convertedValue = valueProviderResult.ConvertTo(typeof(string));
Assert.Null(convertedValue);
// Assert
Assert.Equal(0, result.Length);
Assert.Null(result.Value);
Assert.Empty(result.Values);
Assert.Null(result.FirstValue);
Assert.Equal(ValueProviderResult.None, result);
Assert.Null((string)result);
Assert.Empty((string[])result);
}
[Fact]
public void ConvertTo_ReturnsDefaultForValueTypes_WhenValueIsNull()
public void Construct_With_NullArray()
{
var valueProviderResult = new ValueProviderResult(rawValue: null);
// Arrange & Act
var result = new ValueProviderResult((string[])null);
var convertedValue = valueProviderResult.ConvertTo(typeof(int));
Assert.Equal(0, convertedValue);
// Assert
Assert.Equal(0, result.Length);
Assert.Null(result.Value);
Assert.Empty(result.Values);
Assert.Null(result.FirstValue);
Assert.Equal(ValueProviderResult.None, result);
Assert.Null((string)result);
Assert.Empty((string[])result);
}
[Fact]
public void ConvertToCanConvertArraysToSingleElements()
public void Construct_With_None()
{
// Arrange
var valueProviderResult = new ValueProviderResult(
new int[] { 1, 20, 42 },
string.Empty,
CultureInfo.InvariantCulture);
// Act
var converted = (string)valueProviderResult.ConvertTo(typeof(string));
// Arrange & Act
var result = ValueProviderResult.None;
// Assert
Assert.Equal("1", converted);
Assert.Equal(0, result.Length);
Assert.Null(result.Value);
Assert.Empty(result.Values);
Assert.Null(result.FirstValue);
Assert.Equal(ValueProviderResult.None, result);
Assert.Null((string)result);
Assert.Empty((string[])result);
}
[Fact]
public void ConvertToCanConvertSingleElementsToArrays()
public void Construct_With_String()
{
// Arrange
var valueProviderResult = new ValueProviderResult(42, string.Empty, CultureInfo.InvariantCulture);
// Act
var converted = (string[])valueProviderResult.ConvertTo(typeof(string[]));
// Arrange & Act
var result = new ValueProviderResult("Hi There");
// Assert
Assert.NotNull(converted);
var result = Assert.Single(converted);
Assert.Equal("42", result);
Assert.Equal(1, result.Length);
Assert.Equal("Hi There", result.Value);
Assert.Null(result.Values);
Assert.Equal("Hi There", result.FirstValue);
Assert.NotEqual(ValueProviderResult.None, result);
Assert.Equal("Hi There", (string)result);
Assert.Equal(new string[] { "Hi There" }, (string[])result);
}
[Fact]
public void ConvertToCanConvertSingleElementsToSingleElements()
public void Construct_With_Array()
{
// Arrange
var valueProviderResult = new ValueProviderResult(42, string.Empty, CultureInfo.InvariantCulture);
// Act
var converted = (string)valueProviderResult.ConvertTo(typeof(string));
// Arrange & Act
var result = new ValueProviderResult(new string[] { "Hi", "There" });
// Assert
Assert.NotNull(converted);
Assert.Equal("42", converted);
}
[Fact]
public void ConvertingNullStringToNullableIntReturnsNull()
{
// Arrange
object original = null;
var valueProviderResult = new ValueProviderResult(original, string.Empty, CultureInfo.InvariantCulture);
// Act
var returned = (int?)valueProviderResult.ConvertTo(typeof(int?));
// Assert
Assert.Equal(returned, null);
}
[Fact]
public void ConvertingWhiteSpaceStringToNullableIntReturnsNull()
{
// Arrange
var original = " ";
var valueProviderResult = new ValueProviderResult(original, string.Empty, CultureInfo.InvariantCulture);
// Act
var returned = (int?)valueProviderResult.ConvertTo(typeof(int?));
// Assert
Assert.Equal(returned, null);
}
[Fact]
public void ConvertToReturnsNullIfArrayElementValueIsNull()
{
// Arrange
var valueProviderResult = new ValueProviderResult(rawValue: new string[] { null });
// Act
var outValue = valueProviderResult.ConvertTo(typeof(int));
// Assert
Assert.Null(outValue);
}
[Fact]
public void ConvertToReturnsNullIfTryingToConvertEmptyArrayToSingleElement()
{
// Arrange
var valueProviderResult = new ValueProviderResult(new int[0], string.Empty, CultureInfo.InvariantCulture);
// Act
var outValue = valueProviderResult.ConvertTo(typeof(int));
// Assert
Assert.Null(outValue);
}
[Theory]
[InlineData("")]
[InlineData(" \t \r\n ")]
public void ConvertToReturnsNullIfTrimmedValueIsEmptyString(object value)
{
// Arrange
var valueProviderResult = new ValueProviderResult(rawValue: value);
// Act
var outValue = valueProviderResult.ConvertTo(typeof(int));
// Assert
Assert.Null(outValue);
}
[Fact]
public void ConvertToReturnsNullIfTrimmedValueIsEmptyString()
{
// Arrange
var valueProviderResult = new ValueProviderResult(rawValue: null);
// Act
var outValue = valueProviderResult.ConvertTo(typeof(int[]));
// Assert
Assert.Null(outValue);
}
[Fact]
public void ConvertToReturnsValueIfArrayElementIsIntegerAndDestinationTypeIsEnum()
{
// Arrange
var result = new ValueProviderResult(rawValue: new object[] { 1 });
// Act
var outValue = result.ConvertTo(typeof(IntEnum));
// Assert
Assert.Equal(outValue, IntEnum.Value1);
}
[Theory]
[InlineData(1, typeof(IntEnum), IntEnum.Value1)]
[InlineData(1L, typeof(LongEnum), LongEnum.Value1)]
[InlineData(long.MaxValue, typeof(LongEnum), LongEnum.MaxValue)]
[InlineData(1U, typeof(UnsignedIntEnum), UnsignedIntEnum.Value1)]
[InlineData(1UL, typeof(IntEnum), IntEnum.Value1)]
[InlineData((byte)1, typeof(ByteEnum), ByteEnum.Value1)]
[InlineData(byte.MaxValue, typeof(ByteEnum), ByteEnum.MaxValue)]
[InlineData((sbyte)1, typeof(ByteEnum), ByteEnum.Value1)]
[InlineData((short)1, typeof(IntEnum), IntEnum.Value1)]
[InlineData((ushort)1, typeof(IntEnum), IntEnum.Value1)]
[InlineData(int.MaxValue, typeof(IntEnum?), IntEnum.MaxValue)]
[InlineData(null, typeof(IntEnum?), null)]
[InlineData(1L, typeof(LongEnum?), LongEnum.Value1)]
[InlineData(null, typeof(LongEnum?), null)]
[InlineData(uint.MaxValue, typeof(UnsignedIntEnum?), UnsignedIntEnum.MaxValue)]
[InlineData((byte)1, typeof(ByteEnum?), ByteEnum.Value1)]
[InlineData(null, typeof(ByteEnum?), null)]
[InlineData((ushort)1, typeof(LongEnum?), LongEnum.Value1)]
public void ConvertToReturnsValueIfArrayElementIsAnyIntegerTypeAndDestinationTypeIsEnum(
object input,
Type enumType,
object expected)
{
// Arrange
var result = new ValueProviderResult(rawValue: new object[] { input });
// Act
var outValue = result.ConvertTo(enumType);
// Assert
Assert.Equal(expected, outValue);
}
[Fact]
public void ConvertToReturnsValueIfArrayElementIsStringValueAndDestinationTypeIsEnum()
{
// Arrange
var valueProviderResult = new ValueProviderResult(rawValue: new object[] { "1" });
// Act
var outValue = valueProviderResult.ConvertTo(typeof(IntEnum));
// Assert
Assert.Equal(outValue, IntEnum.Value1);
}
[Fact]
public void ConvertToReturnsValueIfArrayElementIsStringKeyAndDestinationTypeIsEnum()
{
// Arrange
var valueProviderResult = new ValueProviderResult(rawValue: new object[] { "Value1" });
// Act
var outValue = valueProviderResult.ConvertTo(typeof(IntEnum));
// Assert
Assert.Equal(outValue, IntEnum.Value1);
}
[Fact]
public void ConvertToReturnsValueIfElementIsStringAndDestinationIsNullableInteger()
{
// Arrange
var valueProviderResult = new ValueProviderResult(rawValue: "12");
// Act
var outValue = valueProviderResult.ConvertTo(typeof(int?));
// Assert
Assert.Equal(12, outValue);
}
[Fact]
public void ConvertToReturnsValueIfElementIsStringAndDestinationIsNullableDouble()
{
// Arrange
var valueProviderResult = new ValueProviderResult(rawValue: "12.5");
// Act
var outValue = valueProviderResult.ConvertTo(typeof(double?));
// Assert
Assert.Equal(12.5, outValue);
}
[Fact]
public void ConvertToReturnsValueIfElementIsDecimalAndDestinationIsNullableInteger()
{
// Arrange
var valueProviderResult = new ValueProviderResult(rawValue: 12M);
// Act
var outValue = valueProviderResult.ConvertTo(typeof(int?));
// Assert
Assert.Equal(12, outValue);
}
[Fact]
public void ConvertToReturnsValueIfElementIsDecimalAndDestinationIsNullableDouble()
{
// Arrange
var valueProviderResult = new ValueProviderResult(rawValue: 12.5M);
// Act
var outValue = valueProviderResult.ConvertTo(typeof(double?));
// Assert
Assert.Equal(12.5, outValue);
}
[Fact]
public void ConvertToReturnsValueIfElementIsDecimalDoubleAndDestinationIsNullableInteger()
{
// Arrange
var valueProviderResult = new ValueProviderResult(rawValue: 12.5M);
// Act
var outValue = valueProviderResult.ConvertTo(typeof(int?));
// Assert
Assert.Equal(12, outValue);
}
[Fact]
public void ConvertToReturnsValueIfElementIsDecimalDoubleAndDestinationIsNullableLong()
{
// Arrange
var valueProviderResult = new ValueProviderResult(rawValue: 12.5M);
// Act
var outValue = valueProviderResult.ConvertTo(typeof(long?));
// Assert
Assert.Equal(12L, outValue);
}
[Fact]
public void ConvertToReturnsValueIfArrayElementInstanceOfDestinationType()
{
// Arrange
var valueProviderResult = new ValueProviderResult(rawValue: new object[] { "some string" });
// Act
var outValue = valueProviderResult.ConvertTo(typeof(string));
// Assert
Assert.Equal("some string", outValue);
}
[Theory]
[InlineData(new object[] { new[] { 1, 0 } })]
[InlineData(new object[] { new[] { "Value1", "Value0" } })]
[InlineData(new object[] { new[] { "Value1", "value0" } })]
public void ConvertTo_ConvertsEnumArrays(object value)
{
// Arrange
var valueProviderResult = new ValueProviderResult(rawValue: value);
// Act
var outValue = valueProviderResult.ConvertTo(typeof(IntEnum[]));
// Assert
var result = Assert.IsType<IntEnum[]>(outValue);
Assert.Equal(2, result.Length);
Assert.Equal(IntEnum.Value1, result[0]);
Assert.Equal(IntEnum.Value0, result[1]);
}
[Theory]
[InlineData(new object[] { new[] { 1, 2 }, new[] { FlagsEnum.Value1, FlagsEnum.Value2 } })]
[InlineData(new object[] { new[] { "Value1", "Value2" }, new[] { FlagsEnum.Value1, FlagsEnum.Value2 } })]
[InlineData(new object[] { new[] { 5, 2 }, new[] { FlagsEnum.Value1 | FlagsEnum.Value4, FlagsEnum.Value2 } })]
public void ConvertTo_ConvertsFlagsEnumArrays(object value, FlagsEnum[] expected)
{
// Arrange
var valueProviderResult = new ValueProviderResult(rawValue: value);
// Act
var outValue = valueProviderResult.ConvertTo(typeof(FlagsEnum[]));
// Assert
var result = Assert.IsType<FlagsEnum[]>(outValue);
Assert.Equal(2, result.Length);
Assert.Equal(expected[0], result[0]);
Assert.Equal(expected[1], result[1]);
Assert.Null(result.Value);
Assert.Equal(new string[] { "Hi", "There" }, result.Values);
Assert.Equal("Hi", result.FirstValue);
Assert.NotEqual(ValueProviderResult.None, result);
Assert.Equal("Hi,There", (string)result);
Assert.Equal(new string[] { "Hi", "There" }, (string[])result);
}
[Fact]
public void ConvertToReturnsValueIfInstanceOfDestinationType()
public void Enumerator_WithString()
{
// Arrange
var original = new[] { "some string" };
var valueProviderResult = new ValueProviderResult(rawValue: original);
// Act
var outValue = valueProviderResult.ConvertTo(typeof(string[]));
// Assert
Assert.Same(original, outValue);
}
[Theory]
[InlineData(typeof(int))]
[InlineData(typeof(double?))]
[InlineData(typeof(IntEnum?))]
public void ConvertToThrowsIfConverterThrows(Type destinationType)
{
// Arrange
var valueProviderResult = new ValueProviderResult(rawValue: "this-is-not-a-valid-value");
var result = new ValueProviderResult("Hi There");
// Act & Assert
var ex = Assert.Throws(typeof(FormatException), () => valueProviderResult.ConvertTo(destinationType));
Assert.Equal<string>(new string[] { "Hi There", }, result);
}
[Fact]
public void ConvertToThrowsIfNoConverterExists()
public void Enumerator_WithArray()
{
// Arrange
var valueProviderResult = new ValueProviderResult(rawValue: "x");
var destinationType = typeof(MyClassWithoutConverter);
var result = new ValueProviderResult(new string[] { "Hi", "There" });
// Act & Assert
var ex = Assert.Throws<InvalidOperationException>(() => valueProviderResult.ConvertTo(destinationType));
Assert.Equal("The parameter conversion from type 'System.String' to type " +
"'Microsoft.AspNet.Mvc.ModelBinding.ValueProviderResultTest+MyClassWithoutConverter' " +
"failed because no type converter can convert between these types.",
ex.Message);
Assert.Equal<string>(new string[] { "Hi", "There" }, result);
}
[Fact]
public void ConvertToUsesProvidedCulture()
{
// Arrange
var original = "12,5";
var valueProviderResult = new ValueProviderResult(
rawValue: original,
attemptedValue: null,
culture: new CultureInfo("en-GB"));
var frCulture = new CultureInfo("fr-FR");
// Act
var cultureResult = valueProviderResult.ConvertTo(typeof(decimal), frCulture);
// Assert
Assert.Equal(12.5M, cultureResult);
Assert.Throws<FormatException>(() => valueProviderResult.ConvertTo(typeof(decimal)));
}
[Fact]
public void CulturePropertyDefaultsToInvariantCulture()
{
// Arrange
var result = new ValueProviderResult(rawValue: null, attemptedValue: null, culture: null);
// Act & assert
Assert.Same(CultureInfo.InvariantCulture, result.Culture);
}
[Theory]
[MemberData(nameof(IntrinsicConversionData))]
public void ConvertToCanConvertIntrinsics<T>(object initialValue, T expectedValue)
{
// Arrange
var result = new ValueProviderResult(initialValue, string.Empty, CultureInfo.InvariantCulture);
// Act & Assert
Assert.Equal(expectedValue, result.ConvertTo(typeof(T)));
}
public static IEnumerable<object[]> IntrinsicConversionData
public static TheoryData<ValueProviderResult, ValueProviderResult, bool> EqualsData
{
get
{
yield return new object[] { 42, 42L };
yield return new object[] { 42, (short)42 };
yield return new object[] { 42, (float)42.0 };
yield return new object[] { 42, (double)42.0 };
yield return new object[] { 42M, 42 };
yield return new object[] { 42L, 42 };
yield return new object[] { 42, (byte)42 };
yield return new object[] { (short)42, 42 };
yield return new object[] { (float)42.0, 42 };
yield return new object[] { (double)42.0, 42 };
yield return new object[] { (byte)42, 42 };
yield return new object[] { "2008-01-01", new DateTime(2008, 01, 01) };
yield return new object[] { "00:00:20", TimeSpan.FromSeconds(20) };
yield return new object[]
return new TheoryData<ValueProviderResult, ValueProviderResult, bool>()
{
"c6687d3a-51f9-4159-8771-a66d2b7d7038",
Guid.Parse("c6687d3a-51f9-4159-8771-a66d2b7d7038")
{
new ValueProviderResult("Hi"),
new ValueProviderResult("Hi"),
true
},
{
new ValueProviderResult("Hi"),
new ValueProviderResult(new string[] { "Hi"}),
true
},
{
new ValueProviderResult(new string[] { "Hi"}),
new ValueProviderResult("Hi"),
true
},
{
new ValueProviderResult(new string[] { "Hi"}),
new ValueProviderResult(new string[] { "Hi"}),
true
},
{
new ValueProviderResult(new string[] { "Hi", "There"}),
new ValueProviderResult(new string[] { "Hi", "There"}),
true
},
{
new ValueProviderResult("Hi,There"),
new ValueProviderResult(new string[] { "Hi", "There"}),
false
},
{
new ValueProviderResult(new string[] { "Hi", string.Empty }),
new ValueProviderResult(new string[] { "Hi", "There"}),
false
},
{
new ValueProviderResult(new string[] { "Hi", "There" }),
new ValueProviderResult(new string[] { "Hi", "ThEre"}),
false
},
{
new ValueProviderResult(new string[] { "Hi", }),
new ValueProviderResult(new string[] { "Hi", string.Empty }),
false
},
{
new ValueProviderResult(),
new ValueProviderResult((string)null),
true
},
{
new ValueProviderResult(),
new ValueProviderResult("hi"),
false
},
};
}
}
[Theory]
[InlineData(typeof(TimeSpan))]
[InlineData(typeof(DateTime))]
[InlineData(typeof(DateTimeOffset))]
[InlineData(typeof(Guid))]
[InlineData(typeof(IntEnum))]
public void ConvertTo_Throws_IfValueIsNotStringData(Type destinationType)
[MemberData(nameof(EqualsData))]
public void Operator_Equals(ValueProviderResult x, ValueProviderResult y, bool expected)
{
// Arrange
var result = new ValueProviderResult(
new MyClassWithoutConverter(),
string.Empty,
CultureInfo.InvariantCulture);
var result = x == y;
// Act
var ex = Assert.Throws<InvalidOperationException>(() => result.ConvertTo(destinationType));
// Assert
var expectedMessage = string.Format("The parameter conversion from type '{0}' to type '{1}' " +
"failed because no type converter can convert between these types.",
typeof(MyClassWithoutConverter), destinationType);
Assert.Equal(expectedMessage, ex.Message);
}
[Fact]
public void ConvertTo_Throws_IfDestinationTypeIsNotConvertible()
{
// Arrange
var value = "Hello world";
var destinationType = typeof(MyClassWithoutConverter);
var result = new ValueProviderResult(value, string.Empty, CultureInfo.InvariantCulture);
// Act
var ex = Assert.Throws<InvalidOperationException>(() => result.ConvertTo(destinationType));
// Assert
var expectedMessage = string.Format("The parameter conversion from type '{0}' to type '{1}' " +
"failed because no type converter can convert between these types.",
value.GetType(), typeof(MyClassWithoutConverter));
Assert.Equal(expectedMessage, ex.Message);
// Act & Assert
Assert.Equal(expected, result);
}
[Theory]
[InlineData(new object[] { 2, FlagsEnum.Value2 })]
[InlineData(new object[] { 5, FlagsEnum.Value1 | FlagsEnum.Value4 })]
[InlineData(new object[] { 15, FlagsEnum.Value1 | FlagsEnum.Value2 | FlagsEnum.Value4 | FlagsEnum.Value8 })]
[InlineData(new object[] { 16, (FlagsEnum)16 })]
[InlineData(new object[] { 0, (FlagsEnum)0 })]
[InlineData(new object[] { null, (FlagsEnum)0 })]
[InlineData(new object[] { "Value1,Value2", (FlagsEnum)3 })]
[InlineData(new object[] { "Value1,Value2,value4, value8", (FlagsEnum)15 })]
public void ConvertTo_ConvertsEnumFlags(object value, object expected)
[MemberData(nameof(EqualsData))]
public void Operator_NotEquals(ValueProviderResult x, ValueProviderResult y, bool expected)
{
// Arrange
var valueProviderResult = new ValueProviderResult(rawValue: value);
var result = x != y;
// Act
var outValue = (FlagsEnum)valueProviderResult.ConvertTo(typeof(FlagsEnum));
// Assert
Assert.Equal(expected, outValue);
}
private class MyClassWithoutConverter
{
}
private enum IntEnum
{
Value0 = 0,
Value1 = 1,
MaxValue = int.MaxValue
}
private enum LongEnum : long
{
Value0 = 0L,
Value1 = 1L,
MaxValue = long.MaxValue
}
private enum UnsignedIntEnum : uint
{
Value0 = 0U,
Value1 = 1U,
MaxValue = uint.MaxValue
}
private enum ByteEnum : byte
{
Value0 = 0,
Value1 = 1,
MaxValue = byte.MaxValue
}
[Flags]
public enum FlagsEnum
{
Value1 = 1,
Value2 = 2,
Value4 = 4,
Value8 = 8
// Act & Assert
Assert.NotEqual(expected, result);
}
}
}

View File

@ -16,7 +16,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
public async Task BindModelAsync_ValueProviderContainPrefix_Succeeds()
{
// Arrange
var valueProvider = new SimpleHttpValueProvider
var valueProvider = new SimpleValueProvider
{
{ "someName[0]", "42" },
{ "someName[1]", "84" },
@ -138,7 +138,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
public async Task BindModelAsync_ModelMetadataReadOnly_ReturnsNull(int[] model)
{
// Arrange
var valueProvider = new SimpleHttpValueProvider
var valueProvider = new SimpleValueProvider
{
{ "someName[0]", "42" },
{ "someName[1]", "84" },
@ -161,7 +161,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
{
// Arrange
var arrayLength = model.Length;
var valueProvider = new SimpleHttpValueProvider
var valueProvider = new SimpleValueProvider
{
{ "someName[0]", "42" },
{ "someName[1]", "84" },
@ -196,7 +196,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
.Returns(async (ModelBindingContext mbc) =>
{
var value = await mbc.ValueProvider.GetValueAsync(mbc.ModelName);
if (value != null)
if (value != ValueProviderResult.None)
{
var model = value.ConvertTo(mbc.ModelType);
return new ModelBindingResult(model, key: null, isModelSet: true);

View File

@ -17,7 +17,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
public async Task BindModelSetsModelToNullOnNullOrEmptyString(string value)
{
// Arrange
var valueProvider = new SimpleHttpValueProvider()
var valueProvider = new SimpleValueProvider()
{
{ "foo", value }
};
@ -36,15 +36,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
var modelState = Assert.Single(bindingContext.ModelState);
Assert.Equal("foo", modelState.Key);
Assert.NotNull(modelState.Value.Value);
Assert.Equal(value, modelState.Value.Value.RawValue);
Assert.Equal(string.Empty, modelState.Value.RawValue);
}
[Fact]
public async Task BindModel()
{
// Arrange
var valueProvider = new SimpleHttpValueProvider()
var valueProvider = new SimpleValueProvider()
{
{ "foo", "Fys1" }
};
@ -67,7 +66,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
// Arrange
var expected = "The value '\"Fys1\"' is not valid for foo.";
var valueProvider = new SimpleHttpValueProvider()
var valueProvider = new SimpleValueProvider()
{
{ "foo", "\"Fys1\"" }
};
@ -89,7 +88,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
public async Task BindModel_ReturnsWithIsModelSetFalse_WhenValueNotFound()
{
// Arrange
var valueProvider = new SimpleHttpValueProvider()
var valueProvider = new SimpleValueProvider()
{
{ "someName", "" }
};

View File

@ -53,7 +53,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
{
ModelMetadata = metadataProvider.GetMetadataForType(modelType),
ModelName = "someName",
ValueProvider = new SimpleHttpValueProvider(),
ValueProvider = new SimpleValueProvider(),
OperationBindingContext = new OperationBindingContext
{
ModelBinder = new CancellationTokenModelBinder(),

View File

@ -23,7 +23,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
public async Task BindComplexCollectionFromIndexes_FiniteIndexes()
{
// Arrange
var valueProvider = new SimpleHttpValueProvider
var valueProvider = new SimpleValueProvider
{
{ "someName[foo]", "42" },
{ "someName[baz]", "200" }
@ -45,7 +45,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
public async Task BindComplexCollectionFromIndexes_InfiniteIndexes()
{
// Arrange
var valueProvider = new SimpleHttpValueProvider
var valueProvider = new SimpleValueProvider
{
{ "someName[0]", "42" },
{ "someName[1]", "100" },
@ -70,7 +70,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
public async Task BindModel_ComplexCollection_Succeeds(bool isReadOnly)
{
// Arrange
var valueProvider = new SimpleHttpValueProvider
var valueProvider = new SimpleValueProvider
{
{ "someName.index", new[] { "foo", "bar", "baz" } },
{ "someName[foo]", "42" },
@ -100,7 +100,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
public async Task BindModel_ComplexCollection_BindingContextModelNonNull_Succeeds(bool isReadOnly)
{
// Arrange
var valueProvider = new SimpleHttpValueProvider
var valueProvider = new SimpleValueProvider
{
{ "someName.index", new[] { "foo", "bar", "baz" } },
{ "someName[foo]", "42" },
@ -132,7 +132,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
public async Task BindModel_SimpleCollection_Succeeds(bool isReadOnly)
{
// Arrange
var valueProvider = new SimpleHttpValueProvider
var valueProvider = new SimpleValueProvider
{
{ "someName", new[] { "42", "100", "200" } }
};
@ -149,8 +149,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
var list = Assert.IsAssignableFrom<IList<int>>(result.Model);
Assert.Equal(new[] { 42, 100, 200 }, list.ToArray());
Assert.True(modelState.IsValid);
}
[Theory]
@ -159,7 +157,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
public async Task BindModel_SimpleCollection_BindingContextModelNonNull_Succeeds(bool isReadOnly)
{
// Arrange
var valueProvider = new SimpleHttpValueProvider
var valueProvider = new SimpleValueProvider
{
{ "someName", new[] { "42", "100", "200" } }
};
@ -178,8 +176,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
Assert.Same(list, result.Model);
Assert.Equal(new[] { 42, 100, 200 }, list.ToArray());
Assert.True(modelState.IsValid);
}
[Fact]
@ -187,7 +183,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
{
// Arrange
var binder = new CollectionModelBinder<int>();
var valueProvider = new SimpleHttpValueProvider
var valueProvider = new SimpleValueProvider
{
{ "someName", null },
};
@ -205,8 +201,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
var model = Assert.IsType<List<int>>(result.Model);
Assert.Empty(model);
Assert.True(modelState.IsValid);
}
#endif
@ -225,7 +219,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
};
// Act
var boundCollection = await binder.BindSimpleCollection(context, rawValue: new object[0], culture: null);
var boundCollection = await binder.BindSimpleCollection(context, new ValueProviderResult(new string[0]));
// Assert
Assert.NotNull(boundCollection.Model);
@ -392,7 +386,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
{
// Arrange
var culture = new CultureInfo("fr-FR");
var bindingContext = GetModelBindingContext(new SimpleHttpValueProvider());
var bindingContext = GetModelBindingContext(new SimpleValueProvider());
ModelValidationNode childValidationNode = null;
Mock.Get<IModelBinder>(bindingContext.OperationBindingContext.ModelBinder)
.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
@ -405,7 +399,9 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
var modelBinder = new CollectionModelBinder<int>();
// Act
var boundCollection = await modelBinder.BindSimpleCollection(bindingContext, new int[1], culture);
var boundCollection = await modelBinder.BindSimpleCollection(
bindingContext,
new ValueProviderResult(new string[] { "0" }));
// Assert
Assert.Equal(new[] { 42 }, boundCollection.Model.ToArray());
@ -442,11 +438,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
.Returns(async (ModelBindingContext mbc) =>
{
var value = await mbc.ValueProvider.GetValueAsync(mbc.ModelName);
if (value != null)
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, true, modelValidationNode);
return new ModelBindingResult(model, mbc.ModelName, model != null, modelValidationNode);
}
return null;

View File

@ -24,7 +24,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(int)),
ModelName = "someName",
ModelState = new ModelStateDictionary(),
ValueProvider = new SimpleHttpValueProvider
ValueProvider = new SimpleValueProvider
{
{ "someName", "dummyValue" }
},
@ -71,7 +71,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(List<int>)),
ModelName = "someName",
ModelState = new ModelStateDictionary(),
ValueProvider = new SimpleHttpValueProvider
ValueProvider = new SimpleValueProvider
{
{ "someOtherName", "dummyValue" }
},
@ -121,7 +121,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(List<int>)),
ModelName = "someName",
ModelState = new ModelStateDictionary(),
ValueProvider = new SimpleHttpValueProvider
ValueProvider = new SimpleValueProvider
{
{ "someOtherName", "dummyValue" }
},
@ -155,7 +155,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(List<int>)),
ModelName = "someName",
ModelState = new ModelStateDictionary(),
ValueProvider = new SimpleHttpValueProvider
ValueProvider = new SimpleValueProvider
{
{ "someOtherName", "dummyValue" }
},
@ -201,7 +201,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(List<int>)),
ModelName = "someName",
ModelState = new ModelStateDictionary(),
ValueProvider = new SimpleHttpValueProvider
ValueProvider = new SimpleValueProvider
{
{ "someOtherName", "dummyValue" }
},
@ -238,7 +238,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(List<int>)),
ModelName = "someName",
ModelState = new ModelStateDictionary(),
ValueProvider = new SimpleHttpValueProvider
ValueProvider = new SimpleValueProvider
{
{ "someOtherName", "dummyValue" }
},
@ -276,7 +276,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(typeof(List<int>)),
ModelName = "someName",
ModelState = new ModelStateDictionary(),
ValueProvider = new SimpleHttpValueProvider
ValueProvider = new SimpleValueProvider
{
{ "someOtherName", "dummyValue" }
},
@ -357,7 +357,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
// Arrange
var binder = CreateBinderWithDefaults();
var valueProvider = new SimpleHttpValueProvider
var valueProvider = new SimpleValueProvider
{
{ "firstName", "firstName-value"},
{ "lastName", "lastName-value"}
@ -400,7 +400,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
// Arrange
var binder = CreateBinderWithDefaults();
var valueProvider = new SimpleHttpValueProvider
var valueProvider = new SimpleValueProvider
{
{ "firstName", "firstName-value"},
{ "lastName", "lastName-value"},
@ -436,7 +436,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
public async Task BindModel_DoesNotAddAValidationNode_IfModelIsNotSet()
{
// Arrange
var valueProvider = new SimpleHttpValueProvider();
var valueProvider = new SimpleValueProvider();
var mockBinder = new Mock<IModelBinder>();
mockBinder
.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
@ -465,7 +465,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
.Returns(Task.FromResult<ModelBindingResult>(null));
var binder = CreateCompositeBinder(mockBinder.Object);
var valueProvider = new SimpleHttpValueProvider();
var valueProvider = new SimpleValueProvider();
var bindingContext = CreateBindingContext(binder, valueProvider, typeof(SimplePropertiesModel));
// Act
@ -479,7 +479,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
public async Task BindModel_UsesTheValidationNodeOnModelBindingResult_IfPresent()
{
// Arrange
var valueProvider = new SimpleHttpValueProvider();
var valueProvider = new SimpleValueProvider();
ModelValidationNode validationNode = null;
var mockBinder = new Mock<IModelBinder>();
@ -531,10 +531,9 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
{
var binders = new IModelBinder[]
{
new TypeMatchModelBinder(),
new ByteArrayModelBinder(),
new GenericModelBinder(),
new TypeConverterModelBinder(),
new SimpleTypeModelBinder(),
new MutableObjectModelBinder()
};

View File

@ -24,7 +24,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
var result = await provider.GetValueAsync("not-test-key");
// Assert
Assert.Null(result);
Assert.Equal(ValueProviderResult.None, result);
}
[Fact]
@ -41,7 +41,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
var result = await provider.GetValueAsync("test-key");
// Assert
Assert.Equal("test-value", result.RawValue);
Assert.Equal("test-value", (string)result);
}
[Fact]
@ -58,9 +58,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
var result = await provider.GetValueAsync("test-key");
// Assert
Assert.NotNull(result);
Assert.Null(result.RawValue);
Assert.Null(result.AttemptedValue);
Assert.Equal(string.Empty, (string)result);
}
[Theory]
@ -103,7 +101,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
var result = await valueProvider.GetValueAsync(prefix);
// Assert
Assert.Equal(expectedValue, (string)result.AttemptedValue);
Assert.Equal(expectedValue, (string)result);
}
[Fact]
@ -121,7 +119,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
var result = await valueProvider.GetValueAsync("bar");
// Assert
Assert.Null(result);
Assert.Equal(ValueProviderResult.None, result);
}
[Fact]

View File

@ -21,7 +21,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
public async Task BindModel_Succeeds(bool isReadOnly)
{
// Arrange
var bindingContext = GetModelBindingContext(isReadOnly);
var values = new Dictionary<string, KeyValuePair<int, string>>()
{
{ "someName[0]", new KeyValuePair<int, string>(42, "forty-two") },
{ "someName[1]", new KeyValuePair<int, string>(84, "eighty-four") },
};
var bindingContext = GetModelBindingContext(isReadOnly, values);
var modelState = bindingContext.ModelState;
var binder = new DictionaryModelBinder<int, string>();
@ -43,10 +49,16 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
[Theory]
[InlineData(false)]
[InlineData(true)]
public async Task BindModel_BindingContextModelNonNull_Succeeds(bool isReadOnly)
public async Task BindModel_WithExistingModel_Succeeds(bool isReadOnly)
{
// Arrange
var bindingContext = GetModelBindingContext(isReadOnly);
var values = new Dictionary<string, KeyValuePair<int, string>>()
{
{ "someName[0]", new KeyValuePair<int, string>(42, "forty-two") },
{ "someName[1]", new KeyValuePair<int, string>(84, "eighty-four") },
};
var bindingContext = GetModelBindingContext(isReadOnly, values);
var modelState = bindingContext.ModelState;
var dictionary = new Dictionary<int, string>();
bindingContext.Model = dictionary;
@ -430,8 +442,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
{
var binders = new IModelBinder[]
{
new TypeConverterModelBinder(),
new TypeMatchModelBinder(),
new SimpleTypeModelBinder(),
new MutableObjectModelBinder(),
};
@ -465,49 +476,51 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
return new TestValueProvider(BindingSource.Form, backingStore);
}
private static ModelBindingContext GetModelBindingContext(bool isReadOnly)
private static ModelBindingContext GetModelBindingContext(
bool isReadOnly,
IDictionary<string, KeyValuePair<int, string>> values)
{
var metadataProvider = new TestModelMetadataProvider();
metadataProvider.ForType<IDictionary<int, string>>().BindingDetails(bd => bd.IsReadOnly = isReadOnly);
var valueProvider = new SimpleHttpValueProvider
var binder = new Mock<IModelBinder>();
binder
.Setup(mb => mb.BindModelAsync(It.IsAny<ModelBindingContext>()))
.Returns<ModelBindingContext>(mbc =>
{
KeyValuePair<int, string> value;
if (values.TryGetValue(mbc.ModelName, out value))
{
return Task.FromResult(new ModelBindingResult(value, mbc.ModelName, isModelSet: true));
}
else
{
return Task.FromResult<ModelBindingResult>(null);
}
});
var valueProvider = new SimpleValueProvider();
foreach (var kvp in values)
{
{ "someName[0]", new KeyValuePair<int, string>(42, "forty-two") },
{ "someName[1]", new KeyValuePair<int, string>(84, "eighty-four") },
};
valueProvider.Add(kvp.Key, string.Empty);
}
var bindingContext = new ModelBindingContext
{
ModelMetadata = metadataProvider.GetMetadataForType(typeof(IDictionary<int, string>)),
ModelName = "someName",
ValueProvider = valueProvider,
OperationBindingContext = new OperationBindingContext
{
ModelBinder = CreateKvpBinder(),
MetadataProvider = metadataProvider
}
ModelBinder = binder.Object,
MetadataProvider = metadataProvider,
ValueProvider = valueProvider,
},
ValueProvider = valueProvider,
};
return bindingContext;
}
private static IModelBinder CreateKvpBinder()
{
Mock<IModelBinder> mockKvpBinder = new Mock<IModelBinder>();
mockKvpBinder
.Setup(o => o.BindModelAsync(It.IsAny<ModelBindingContext>()))
.Returns(async (ModelBindingContext mbc) =>
{
var value = await mbc.ValueProvider.GetValueAsync(mbc.ModelName);
if (value != null)
{
var model = value.ConvertTo(mbc.ModelType);
return new ModelBindingResult(model, key: null, isModelSet: true);
}
return null;
});
return mockKvpBinder.Object;
}
private class ModelWithDictionaryProperties
{
// A Dictionary<string, string> instance cannot be assigned to this property.

View File

@ -19,9 +19,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
{
// Arrange
var culture = new CultureInfo("en-US");
var elementalValueProvider = new ElementalValueProvider(elementName,
new object(),
culture);
var elementalValueProvider = new ElementalValueProvider(
elementName,
"hi",
culture);
// Act
var containsPrefix = await elementalValueProvider.ContainsPrefixAsync(prefix);
@ -39,9 +40,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
{
// Arrange
var culture = new CultureInfo("en-US");
var elementalValueProvider = new ElementalValueProvider(elementName,
new object(),
culture);
var elementalValueProvider = new ElementalValueProvider(
elementName,
"hi",
culture);
// Act
var containsPrefix = await elementalValueProvider.ContainsPrefixAsync(prefix);
@ -51,18 +53,17 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
}
[Fact]
public async Task GetValueAsync_NameDoesNotMatch_ReturnsNull()
public async Task GetValueAsync_NameDoesNotMatch_ReturnsEmptyResult()
{
// Arrange
var culture = new CultureInfo("fr-FR");
var rawValue = new DateTime(2001, 1, 2);
var valueProvider = new ElementalValueProvider("foo", rawValue, culture);
var valueProvider = new ElementalValueProvider("foo", "hi", culture);
// Act
var vpResult = await valueProvider.GetValueAsync("bar");
var result = await valueProvider.GetValueAsync("bar");
// Assert
Assert.Null(vpResult);
Assert.Equal(ValueProviderResult.None, result);
}
[Theory]
@ -73,17 +74,15 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
{
// Arrange
var culture = new CultureInfo("fr-FR");
var rawValue = new DateTime(2001, 1, 2);
var valueProvider = new ElementalValueProvider("foo", rawValue, culture);
var valueProvider = new ElementalValueProvider("foo", "hi", culture);
// Act
var vpResult = await valueProvider.GetValueAsync(name);
var result = await valueProvider.GetValueAsync(name);
// Assert
Assert.NotNull(vpResult);
Assert.Equal(rawValue, vpResult.RawValue);
Assert.Equal("02/01/2001 00:00:00", vpResult.AttemptedValue);
Assert.Equal(culture, vpResult.Culture);
Assert.NotNull(result);
Assert.Equal("hi", (string)result);
Assert.Equal(culture, result.Culture);
}
}
}

View File

@ -167,8 +167,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
// Assert
Assert.NotNull(result);
Assert.Equal("someOtherValue", result.RawValue);
Assert.Equal("someOtherValue", result.AttemptedValue);
Assert.Equal("someOtherValue", (string)result);
Assert.Equal(culture, result.Culture);
}
@ -184,8 +183,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
// Assert
Assert.NotNull(result);
Assert.Equal(new[] { "someValue1", "someValue2" }, (IList<string>)result.RawValue);
Assert.Equal("someValue1,someValue2", result.AttemptedValue);
Assert.Equal(new[] { "someValue1", "someValue2" }, result.Values);
Assert.Equal("someValue1,someValue2", (string)result);
Assert.Equal(culture, result.Culture);
}
@ -202,7 +201,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
var result = await valueProvider.GetValueAsync(key);
// Assert
Assert.Null(result);
Assert.Equal(ValueProviderResult.None, result);
}
[Fact]
@ -220,8 +219,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
var result = await valueProvider.GetValueAsync("key");
// Assert
Assert.Equal(new[] { null, null, "value" }, result.RawValue as IEnumerable<string>);
Assert.Equal(",,value", result.AttemptedValue);
Assert.Equal(new[] { null, null, "value" }, result.Values);
Assert.Equal(",,value", (string)result);
}
[Fact]
@ -234,7 +233,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
var result = await valueProvider.GetValueAsync("prefix");
// Assert
Assert.Null(result);
Assert.Equal(ValueProviderResult.None, result);
}
[Fact]

View File

@ -110,10 +110,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
var result = await valueProvider.GetValueAsync(key);
// Assert
Assert.NotNull(result);
Assert.NotNull(result.RawValue);
var value = Assert.IsType<string>(result.RawValue);
Assert.Equal("found", value);
Assert.Equal("found", (string)result);
}
private static ValueProviderFactoryContext CreateContext(

View File

@ -19,7 +19,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
public async Task BindModel_MissingKey_ReturnsResult_AndAddsModelValidationError()
{
// Arrange
var valueProvider = new SimpleHttpValueProvider();
var valueProvider = new SimpleValueProvider();
// Create string binder to create the value but not the key.
var bindingContext = GetBindingContext(valueProvider, CreateStringBinder());
@ -42,7 +42,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
public async Task BindModel_MissingValue_ReturnsResult_AndAddsModelValidationError()
{
// Arrange
var valueProvider = new SimpleHttpValueProvider();
var valueProvider = new SimpleValueProvider();
// Create int binder to create the value but not the key.
var bindingContext = GetBindingContext(valueProvider, CreateIntBinder());
@ -64,7 +64,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
public async Task BindModel_MissingKeyAndMissingValue_DoNotAddModelStateError()
{
// Arrange
var valueProvider = new SimpleHttpValueProvider();
var valueProvider = new SimpleValueProvider();
// Create int binder to create the value but not the key.
var bindingContext = GetBindingContext(valueProvider);
@ -89,7 +89,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
{
// Arrange
var innerBinder = new CompositeModelBinder(new[] { CreateStringBinder(), CreateIntBinder() });
var valueProvider = new SimpleHttpValueProvider();
var valueProvider = new SimpleValueProvider();
var bindingContext = GetBindingContext(valueProvider, innerBinder);
var binder = new KeyValuePairModelBinder<int, string>();
@ -134,7 +134,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
Assert.Equal("someName.key", context.ModelName);
return Task.FromResult(innerResult);
});
var bindingContext = GetBindingContext(new SimpleHttpValueProvider(), innerBinder.Object);
var bindingContext = GetBindingContext(new SimpleValueProvider(), innerBinder.Object);
var binder = new KeyValuePairModelBinder<int, string>();
var modelValidationNodeList = new List<ModelValidationNode>();
@ -238,7 +238,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
{
HttpContext = new DefaultHttpContext(),
MetadataProvider = new TestModelMetadataProvider(),
ModelBinder = new TypeMatchModelBinder(),
ModelBinder = new SimpleTypeModelBinder(),
}
};

View File

@ -18,7 +18,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
ModelMetadata = new TestModelMetadataProvider().GetMetadataForType(typeof(object)),
ModelName = "theName",
ModelState = new ModelStateDictionary(),
ValueProvider = new SimpleHttpValueProvider()
ValueProvider = new SimpleValueProvider()
};
var metadataProvider = new TestModelMetadataProvider();

View File

@ -9,7 +9,7 @@ using Xunit;
namespace Microsoft.AspNet.Mvc.ModelBinding.Test
{
public class TypeConverterModelBinderTest
public class SimpleTypeModelBinderTest
{
[Theory]
[InlineData(typeof(object))]
@ -19,12 +19,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
{
// Arrange
var bindingContext = GetBindingContext(destinationType);
bindingContext.ValueProvider = new SimpleHttpValueProvider
bindingContext.ValueProvider = new SimpleValueProvider
{
{ "theModelName", "some-value" }
};
var binder = new TypeConverterModelBinder();
var binder = new SimpleTypeModelBinder();
// Act
var retVal = await binder.BindModelAsync(bindingContext);
@ -53,12 +53,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
// Arrange
var bindingContext = GetBindingContext(destinationType);
bindingContext.ValueProvider = new SimpleHttpValueProvider
bindingContext.ValueProvider = new SimpleValueProvider
{
{ "theModelName", "some-value" }
};
var binder = new TypeConverterModelBinder();
var binder = new SimpleTypeModelBinder();
// Act
var retVal = await binder.BindModelAsync(bindingContext);
@ -79,11 +79,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
{
// Arrange
var bindingContext = GetBindingContext(destinationType);
bindingContext.ValueProvider = new SimpleHttpValueProvider
bindingContext.ValueProvider = new SimpleValueProvider
{
{ "theModelName", string.Empty }
};
var binder = new TypeConverterModelBinder();
var binder = new SimpleTypeModelBinder();
// Act
var result = await binder.BindModelAsync(bindingContext);
@ -104,19 +104,19 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
// Arrange
var message = "The value 'not an integer' is not valid for theModelName.";
var bindingContext = GetBindingContext(typeof(int));
bindingContext.ValueProvider = new SimpleHttpValueProvider
bindingContext.ValueProvider = new SimpleValueProvider
{
{ "theModelName", "not an integer" }
};
var binder = new TypeConverterModelBinder();
var binder = new SimpleTypeModelBinder();
// Act
var retVal = await binder.BindModelAsync(bindingContext);
var result = await binder.BindModelAsync(bindingContext);
// Assert
Assert.NotNull(retVal);
Assert.Null(retVal.Model);
Assert.NotNull(result);
Assert.Null(result.Model);
Assert.False(bindingContext.ModelState.IsValid);
var error = Assert.Single(bindingContext.ModelState["theModelName"].Errors);
Assert.Equal(message, error.ErrorMessage);
@ -127,7 +127,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
{
// Arrange
var bindingContext = GetBindingContext(typeof(int));
var binder = new TypeConverterModelBinder();
var binder = new SimpleTypeModelBinder();
// Act
var retVal = await binder.BindModelAsync(bindingContext);
@ -142,12 +142,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
{
// Arrange
var bindingContext = GetBindingContext(typeof(string));
bindingContext.ValueProvider = new SimpleHttpValueProvider
bindingContext.ValueProvider = new SimpleValueProvider
{
{ "theModelName", string.Empty }
};
var binder = new TypeConverterModelBinder();
var binder = new SimpleTypeModelBinder();
// Act
var retVal = await binder.BindModelAsync(bindingContext);
@ -163,12 +163,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
{
// Arrange
var bindingContext = GetBindingContext(typeof(int));
bindingContext.ValueProvider = new SimpleHttpValueProvider
bindingContext.ValueProvider = new SimpleValueProvider
{
{ "theModelName", "42" }
};
var binder = new TypeConverterModelBinder();
var binder = new SimpleTypeModelBinder();
// Act
var retVal = await binder.BindModelAsync(bindingContext);
@ -185,7 +185,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(modelType),
ModelName = "theModelName",
ValueProvider = new SimpleHttpValueProvider() // empty
ValueProvider = new SimpleValueProvider() // empty
};
}

View File

@ -8,16 +8,16 @@ using System.Threading.Tasks;
namespace Microsoft.AspNet.Mvc.ModelBinding.Test
{
public sealed class SimpleHttpValueProvider : Dictionary<string, object>, IValueProvider
public sealed class SimpleValueProvider : Dictionary<string, object>, IValueProvider
{
private readonly CultureInfo _culture;
public SimpleHttpValueProvider()
public SimpleValueProvider()
: this(null)
{
}
public SimpleHttpValueProvider(CultureInfo culture)
public SimpleValueProvider(CultureInfo culture)
: base(StringComparer.OrdinalIgnoreCase)
{
_culture = culture ?? CultureInfo.InvariantCulture;
@ -59,11 +59,28 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
public Task<ValueProviderResult> GetValueAsync(string key)
{
ValueProviderResult result = null;
ValueProviderResult result = ValueProviderResult.None;
object rawValue;
if (TryGetValue(key, out rawValue))
{
result = new ValueProviderResult(rawValue, Convert.ToString(rawValue, _culture), _culture);
if (rawValue != null && rawValue.GetType().IsArray)
{
var array = (Array)rawValue;
var stringValues = new string[array.Length];
for (var i = 0; i < array.Length; i++)
{
stringValues[i] = array.GetValue(i) as string ?? Convert.ToString(array.GetValue(i), _culture);
}
result = new ValueProviderResult(stringValues, _culture);
}
else
{
var stringValue = rawValue as string ?? Convert.ToString(rawValue, _culture) ?? string.Empty;
result = new ValueProviderResult(stringValue, _culture);
}
}
return Task.FromResult(result);

View File

@ -1,121 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved. See License.txt in the project root for license information.
using System;
using System.Threading.Tasks;
using Xunit;
namespace Microsoft.AspNet.Mvc.ModelBinding.Test
{
public class TypeMatchModelBinderTest
{
[Fact]
public async Task BindModel_InvalidValueProviderResult_ReturnsNull()
{
// Arrange
var bindingContext = GetBindingContext();
bindingContext.ValueProvider = new SimpleHttpValueProvider
{
{ "theModelName", "not an integer" }
};
var binder = new TypeMatchModelBinder();
var modelState = bindingContext.ModelState;
// Act
var result = await binder.BindModelAsync(bindingContext);
// Assert
Assert.Null(result);
Assert.Empty(modelState.Keys);
Assert.True(modelState.IsValid);
}
[Fact]
public async Task BindModel_ValidValueProviderResult_ReturnsNotNull()
{
// Arrange
var bindingContext = GetBindingContext();
bindingContext.ValueProvider = new SimpleHttpValueProvider
{
{ "theModelName", 42 }
};
var binder = new TypeMatchModelBinder();
var modelState = bindingContext.ModelState;
// Act
var result = await binder.BindModelAsync(bindingContext);
// Assert
Assert.NotNull(result);
Assert.True(result.IsModelSet);
Assert.Equal(42, result.Model);
var key = Assert.Single(modelState.Keys);
Assert.Equal("theModelName", key);
Assert.Equal("42", modelState[key].Value.AttemptedValue);
Assert.Equal(42, modelState[key].Value.RawValue);
}
[Fact]
public async Task GetCompatibleValueProviderResult_ValueProviderResultRawValueIncorrect_ReturnsNull()
{
// Arrange
var bindingContext = GetBindingContext();
bindingContext.ValueProvider = new SimpleHttpValueProvider
{
{ "theModelName", "not an integer" }
};
// Act
var vpResult = await TypeMatchModelBinder.GetCompatibleValueProviderResult(bindingContext);
// Assert
Assert.Null(vpResult); // Raw value is the wrong type
}
[Fact]
public async Task GetCompatibleValueProviderResult_ValueProviderResultValid_ReturnsValueProviderResult()
{
// Arrange
var bindingContext = GetBindingContext();
bindingContext.ValueProvider = new SimpleHttpValueProvider
{
{ "theModelName", 42 }
};
// Act
var vpResult = await TypeMatchModelBinder.GetCompatibleValueProviderResult(bindingContext);
// Assert
Assert.NotNull(vpResult);
}
[Fact]
public async Task GetCompatibleValueProviderResult_ValueProviderReturnsNull_ReturnsNull()
{
// Arrange
var bindingContext = GetBindingContext();
bindingContext.ValueProvider = new SimpleHttpValueProvider();
// Act
var vpResult = await TypeMatchModelBinder.GetCompatibleValueProviderResult(bindingContext);
// Assert
Assert.Null(vpResult); // No key matched
}
private static ModelBindingContext GetBindingContext()
{
return GetBindingContext(typeof(int));
}
private static ModelBindingContext GetBindingContext(Type modelType)
{
return new ModelBindingContext
{
ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(modelType),
ModelName = "theModelName"
};
}
}
}

View File

@ -495,8 +495,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Validation
var validationContext = testValidationContext.ModelValidationContext;
// Set the value on model state as a model binder would.
var valueProviderResult = new ValueProviderResult(rawValue: "password");
validationContext.ModelState.SetModelValue("user.Password", valueProviderResult);
validationContext.ModelState.SetModelValue("user.Password", new string[] { "password" }, "password");
var validator = new DefaultObjectValidator(
testValidationContext.ExcludeFilters,
testValidationContext.ModelMetadataProvider);
@ -517,7 +516,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Validation
Assert.Equal("user.Password", entry.Key);
Assert.Empty(entry.Value.Errors);
Assert.Equal(entry.Value.ValidationState, ModelValidationState.Skipped);
Assert.Same(valueProviderResult, entry.Value.Value);
Assert.Equal(new string[] { "password" }, entry.Value.RawValue);
Assert.Same("password", entry.Value.AttemptedValue);
}
private class Person2

View File

@ -5,6 +5,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
@ -68,7 +69,7 @@ namespace Microsoft.AspNet.Mvc.Test
var expectedMessage = PlatformNormalizer.NormalizeContent("The MyProperty field is required.");
var binders = new IModelBinder[]
{
new TypeConverterModelBinder(),
new SimpleTypeModelBinder(),
new MutableObjectModelBinder()
};
@ -107,7 +108,7 @@ namespace Microsoft.AspNet.Mvc.Test
// Arrange
var binders = new IModelBinder[]
{
new TypeConverterModelBinder(),
new SimpleTypeModelBinder(),
new MutableObjectModelBinder()
};
@ -181,7 +182,7 @@ namespace Microsoft.AspNet.Mvc.Test
// Arrange
var binders = new IModelBinder[]
{
new TypeConverterModelBinder(),
new SimpleTypeModelBinder(),
new MutableObjectModelBinder()
};
@ -270,7 +271,7 @@ namespace Microsoft.AspNet.Mvc.Test
// Arrange
var binders = new IModelBinder[]
{
new TypeConverterModelBinder(),
new SimpleTypeModelBinder(),
new MutableObjectModelBinder()
};
@ -322,7 +323,7 @@ namespace Microsoft.AspNet.Mvc.Test
// Arrange
var binders = new IModelBinder[]
{
new TypeConverterModelBinder(),
new SimpleTypeModelBinder(),
new MutableObjectModelBinder()
};
@ -528,7 +529,7 @@ namespace Microsoft.AspNet.Mvc.Test
// Arrange
var binders = new IModelBinder[]
{
new TypeConverterModelBinder(),
new SimpleTypeModelBinder(),
new MutableObjectModelBinder()
};
@ -619,7 +620,7 @@ namespace Microsoft.AspNet.Mvc.Test
// Arrange
var binders = new IModelBinder[]
{
new TypeConverterModelBinder(),
new SimpleTypeModelBinder(),
new MutableObjectModelBinder()
};
@ -876,6 +877,514 @@ namespace Microsoft.AspNet.Mvc.Test
public string Name { get; set; }
public Address Address { get; set; }
}
[Fact]
public void ConvertTo_ReturnsNullForReferenceTypes_WhenValueIsNull()
{
var convertedValue = ModelBindingHelper.ConvertTo(null, typeof(string));
Assert.Null(convertedValue);
}
[Fact]
public void ConvertTo_ReturnsDefaultForValueTypes_WhenValueIsNull()
{
var convertedValue = ModelBindingHelper.ConvertTo(null, typeof(int));
Assert.Equal(0, convertedValue);
}
[Fact]
public void ConvertToCanConvertArraysToSingleElements()
{
// Arrange
var value = new int[] { 1, 20, 42 };
// Act
var converted = ModelBindingHelper.ConvertTo(value, typeof(string));
// Assert
Assert.Equal("1", converted);
}
[Fact]
public void ConvertToCanConvertSingleElementsToArrays()
{
// Arrange
var value = 42;
// Act
var converted = ModelBindingHelper.ConvertTo<string[]>(value);
// Assert
Assert.NotNull(converted);
var result = Assert.Single(converted);
Assert.Equal("42", result);
}
[Fact]
public void ConvertToCanConvertSingleElementsToSingleElements()
{
// Arrange
// Act
var converted = ModelBindingHelper.ConvertTo<string>(42);
// Assert
Assert.NotNull(converted);
Assert.Equal("42", converted);
}
[Fact]
public void ConvertingNullStringToNullableIntReturnsNull()
{
// Arrange
// Act
var returned = ModelBindingHelper.ConvertTo<int?>(null);
// Assert
Assert.Equal(returned, null);
}
[Fact]
public void ConvertingWhiteSpaceStringToNullableIntReturnsNull()
{
// Arrange
var original = " ";
// Act
var returned = ModelBindingHelper.ConvertTo<int?>(original);
// Assert
Assert.Equal(returned, null);
}
[Fact]
public void ConvertToReturnsNullIfArrayElementValueIsNull()
{
// Arrange
// Act
var outValue = ModelBindingHelper.ConvertTo(new string[] { null }, typeof(int));
// Assert
Assert.Null(outValue);
}
[Fact]
public void ConvertToReturnsNullIfTryingToConvertEmptyArrayToSingleElement()
{
// Arrange
// Act
var outValue = ModelBindingHelper.ConvertTo(new int[0], typeof(int));
// Assert
Assert.Null(outValue);
}
[Theory]
[InlineData("")]
[InlineData(" \t \r\n ")]
public void ConvertToReturnsNullIfTrimmedValueIsEmptyString(object value)
{
// Arrange
// Act
var outValue = ModelBindingHelper.ConvertTo(value, typeof(int));
// Assert
Assert.Null(outValue);
}
[Fact]
public void ConvertToReturnsNullIfTrimmedValueIsEmptyString()
{
// Arrange
// Act
var outValue = ModelBindingHelper.ConvertTo(null, typeof(int[]));
// Assert
Assert.Null(outValue);
}
[Fact]
public void ConvertToReturnsValueIfArrayElementIsIntegerAndDestinationTypeIsEnum()
{
// Arrange
// Act
var outValue = ModelBindingHelper.ConvertTo(new object[] { 1 }, typeof(IntEnum));
// Assert
Assert.Equal(outValue, IntEnum.Value1);
}
[Theory]
[InlineData(1, typeof(IntEnum), IntEnum.Value1)]
[InlineData(1L, typeof(LongEnum), LongEnum.Value1)]
[InlineData(long.MaxValue, typeof(LongEnum), LongEnum.MaxValue)]
[InlineData(1U, typeof(UnsignedIntEnum), UnsignedIntEnum.Value1)]
[InlineData(1UL, typeof(IntEnum), IntEnum.Value1)]
[InlineData((byte)1, typeof(ByteEnum), ByteEnum.Value1)]
[InlineData(byte.MaxValue, typeof(ByteEnum), ByteEnum.MaxValue)]
[InlineData((sbyte)1, typeof(ByteEnum), ByteEnum.Value1)]
[InlineData((short)1, typeof(IntEnum), IntEnum.Value1)]
[InlineData((ushort)1, typeof(IntEnum), IntEnum.Value1)]
[InlineData(int.MaxValue, typeof(IntEnum?), IntEnum.MaxValue)]
[InlineData(null, typeof(IntEnum?), null)]
[InlineData(1L, typeof(LongEnum?), LongEnum.Value1)]
[InlineData(null, typeof(LongEnum?), null)]
[InlineData(uint.MaxValue, typeof(UnsignedIntEnum?), UnsignedIntEnum.MaxValue)]
[InlineData((byte)1, typeof(ByteEnum?), ByteEnum.Value1)]
[InlineData(null, typeof(ByteEnum?), null)]
[InlineData((ushort)1, typeof(LongEnum?), LongEnum.Value1)]
public void ConvertToReturnsValueIfArrayElementIsAnyIntegerTypeAndDestinationTypeIsEnum(
object input,
Type enumType,
object expected)
{
// Arrange
// Act
var outValue = ModelBindingHelper.ConvertTo(new object[] { input }, enumType);
// Assert
Assert.Equal(expected, outValue);
}
[Fact]
public void ConvertToReturnsValueIfArrayElementIsStringValueAndDestinationTypeIsEnum()
{
// Arrange
// Act
var outValue = ModelBindingHelper.ConvertTo(new object[] { "1" }, typeof(IntEnum));
// Assert
Assert.Equal(outValue, IntEnum.Value1);
}
[Fact]
public void ConvertToReturnsValueIfArrayElementIsStringKeyAndDestinationTypeIsEnum()
{
// Arrange
// Act
var outValue = ModelBindingHelper.ConvertTo(new object[] { "Value1" }, typeof(IntEnum));
// Assert
Assert.Equal(outValue, IntEnum.Value1);
}
[Fact]
public void ConvertToReturnsValueIfElementIsStringAndDestinationIsNullableInteger()
{
// Arrange
// Act
var outValue = ModelBindingHelper.ConvertTo("12", typeof(int?));
// Assert
Assert.Equal(12, outValue);
}
[Fact]
public void ConvertToReturnsValueIfElementIsStringAndDestinationIsNullableDouble()
{
// Arrange
// Act
var outValue = ModelBindingHelper.ConvertTo("12.5", typeof(double?));
// Assert
Assert.Equal(12.5, outValue);
}
[Fact]
public void ConvertToReturnsValueIfElementIsDecimalAndDestinationIsNullableInteger()
{
// Arrange
// Act
var outValue = ModelBindingHelper.ConvertTo(12M, typeof(int?));
// Assert
Assert.Equal(12, outValue);
}
[Fact]
public void ConvertToReturnsValueIfElementIsDecimalAndDestinationIsNullableDouble()
{
// Arrange
// Act
var outValue = ModelBindingHelper.ConvertTo(12.5M, typeof(double?));
// Assert
Assert.Equal(12.5, outValue);
}
[Fact]
public void ConvertToReturnsValueIfElementIsDecimalDoubleAndDestinationIsNullableInteger()
{
// Arrange
// Act
var outValue = ModelBindingHelper.ConvertTo(12M, typeof(int?));
// Assert
Assert.Equal(12, outValue);
}
[Fact]
public void ConvertToReturnsValueIfElementIsDecimalDoubleAndDestinationIsNullableLong()
{
// Arrange
// Act
var outValue = ModelBindingHelper.ConvertTo(12M, typeof(long?));
// Assert
Assert.Equal(12L, outValue);
}
[Fact]
public void ConvertToReturnsValueIfArrayElementInstanceOfDestinationType()
{
// Arrange
// Act
var outValue = ModelBindingHelper.ConvertTo(new object[] { "some string" }, typeof(string));
// Assert
Assert.Equal("some string", outValue);
}
[Theory]
[InlineData(new object[] { new[] { 1, 0 } })]
[InlineData(new object[] { new[] { "Value1", "Value0" } })]
[InlineData(new object[] { new[] { "Value1", "value0" } })]
public void ConvertTo_ConvertsEnumArrays(object value)
{
// Arrange
// Act
var outValue = ModelBindingHelper.ConvertTo(value, typeof(IntEnum[]));
// Assert
var result = Assert.IsType<IntEnum[]>(outValue);
Assert.Equal(2, result.Length);
Assert.Equal(IntEnum.Value1, result[0]);
Assert.Equal(IntEnum.Value0, result[1]);
}
[Theory]
[InlineData(new object[] { new[] { 1, 2 }, new[] { FlagsEnum.Value1, FlagsEnum.Value2 } })]
[InlineData(new object[] { new[] { "Value1", "Value2" }, new[] { FlagsEnum.Value1, FlagsEnum.Value2 } })]
[InlineData(new object[] { new[] { 5, 2 }, new[] { FlagsEnum.Value1 | FlagsEnum.Value4, FlagsEnum.Value2 } })]
public void ConvertTo_ConvertsFlagsEnumArrays(object value, FlagsEnum[] expected)
{
// Arrange
// Act
var outValue = ModelBindingHelper.ConvertTo(value, typeof(FlagsEnum[]));
// Assert
var result = Assert.IsType<FlagsEnum[]>(outValue);
Assert.Equal(2, result.Length);
Assert.Equal(expected[0], result[0]);
Assert.Equal(expected[1], result[1]);
}
[Fact]
public void ConvertToReturnsValueIfInstanceOfDestinationType()
{
// Arrange
var original = new[] { "some string" };
// Act
var outValue = ModelBindingHelper.ConvertTo(original, typeof(string[]));
// Assert
Assert.Same(original, outValue);
}
[Theory]
[InlineData(typeof(int))]
[InlineData(typeof(double?))]
[InlineData(typeof(IntEnum?))]
public void ConvertToThrowsIfConverterThrows(Type destinationType)
{
// Arrange
// Act & Assert
var ex = Assert.Throws<FormatException>(
() => ModelBindingHelper.ConvertTo("this-is-not-a-valid-value", destinationType));
}
[Fact]
public void ConvertToThrowsIfNoConverterExists()
{
// Arrange
var destinationType = typeof(MyClassWithoutConverter);
// Act & Assert
var ex = Assert.Throws<InvalidOperationException>(
() => ModelBindingHelper.ConvertTo("x", destinationType));
Assert.Equal("The parameter conversion from type 'System.String' to type " +
$"'{typeof(MyClassWithoutConverter).FullName}' " +
"failed because no type converter can convert between these types.",
ex.Message);
}
[Fact]
public void ConvertToUsesProvidedCulture()
{
// Arrange
// Act
var cultureResult = ModelBindingHelper.ConvertTo("12,5", typeof(decimal), new CultureInfo("fr-FR"));
// Assert
Assert.Equal(12.5M, cultureResult);
Assert.Throws<FormatException>(
() => ModelBindingHelper.ConvertTo("12,5", typeof(decimal), new CultureInfo("en-GB")));
}
[Theory]
[MemberData(nameof(IntrinsicConversionData))]
public void ConvertToCanConvertIntrinsics<T>(object initialValue, T expectedValue)
{
// Arrange
// Act & Assert
Assert.Equal(expectedValue, ModelBindingHelper.ConvertTo(initialValue, typeof(T)));
}
public static IEnumerable<object[]> IntrinsicConversionData
{
get
{
yield return new object[] { 42, 42L };
yield return new object[] { 42, (short)42 };
yield return new object[] { 42, (float)42.0 };
yield return new object[] { 42, (double)42.0 };
yield return new object[] { 42M, 42 };
yield return new object[] { 42L, 42 };
yield return new object[] { 42, (byte)42 };
yield return new object[] { (short)42, 42 };
yield return new object[] { (float)42.0, 42 };
yield return new object[] { (double)42.0, 42 };
yield return new object[] { (byte)42, 42 };
yield return new object[] { "2008-01-01", new DateTime(2008, 01, 01) };
yield return new object[] { "00:00:20", TimeSpan.FromSeconds(20) };
yield return new object[]
{
"c6687d3a-51f9-4159-8771-a66d2b7d7038",
Guid.Parse("c6687d3a-51f9-4159-8771-a66d2b7d7038")
};
}
}
[Theory]
[InlineData(typeof(TimeSpan))]
[InlineData(typeof(DateTime))]
[InlineData(typeof(DateTimeOffset))]
[InlineData(typeof(Guid))]
[InlineData(typeof(IntEnum))]
public void ConvertTo_Throws_IfValueIsNotStringData(Type destinationType)
{
// Arrange
// Act
var ex = Assert.Throws<InvalidOperationException>(
() => ModelBindingHelper.ConvertTo(new MyClassWithoutConverter(), destinationType));
// Assert
var expectedMessage = string.Format("The parameter conversion from type '{0}' to type '{1}' " +
"failed because no type converter can convert between these types.",
typeof(MyClassWithoutConverter), destinationType);
Assert.Equal(expectedMessage, ex.Message);
}
[Fact]
public void ConvertTo_Throws_IfDestinationTypeIsNotConvertible()
{
// Arrange
var value = "Hello world";
var destinationType = typeof(MyClassWithoutConverter);
// Act
var ex = Assert.Throws<InvalidOperationException>(
() => ModelBindingHelper.ConvertTo(value, destinationType));
// Assert
var expectedMessage = string.Format("The parameter conversion from type '{0}' to type '{1}' " +
"failed because no type converter can convert between these types.",
value.GetType(), typeof(MyClassWithoutConverter));
Assert.Equal(expectedMessage, ex.Message);
}
[Theory]
[InlineData(new object[] { 2, FlagsEnum.Value2 })]
[InlineData(new object[] { 5, FlagsEnum.Value1 | FlagsEnum.Value4 })]
[InlineData(new object[] { 15, FlagsEnum.Value1 | FlagsEnum.Value2 | FlagsEnum.Value4 | FlagsEnum.Value8 })]
[InlineData(new object[] { 16, (FlagsEnum)16 })]
[InlineData(new object[] { 0, (FlagsEnum)0 })]
[InlineData(new object[] { null, (FlagsEnum)0 })]
[InlineData(new object[] { "Value1,Value2", (FlagsEnum)3 })]
[InlineData(new object[] { "Value1,Value2,value4, value8", (FlagsEnum)15 })]
public void ConvertTo_ConvertsEnumFlags(object value, object expected)
{
// Arrange
// Act
var outValue = ModelBindingHelper.ConvertTo<FlagsEnum>(value);
// Assert
Assert.Equal(expected, outValue);
}
private class MyClassWithoutConverter
{
}
private enum IntEnum
{
Value0 = 0,
Value1 = 1,
MaxValue = int.MaxValue
}
private enum LongEnum : long
{
Value0 = 0L,
Value1 = 1L,
MaxValue = long.MaxValue
}
private enum UnsignedIntEnum : uint
{
Value0 = 0U,
Value1 = 1U,
MaxValue = uint.MaxValue
}
private enum ByteEnum : byte
{
Value0 = 0,
Value1 = 1,
MaxValue = byte.MaxValue
}
[Flags]
public enum FlagsEnum
{
Value1 = 1,
Value2 = 2,
Value4 = 4,
Value8 = 8
}
}
}
#endif

View File

@ -72,10 +72,10 @@ namespace Microsoft.AspNet.Mvc
var modelState = new ModelStateDictionary();
modelState.Add(
"key1",
new ModelState() { Value = new ValueProviderResult("foo", "foo", CultureInfo.InvariantCulture) });
new ModelState());
modelState.Add(
"key2",
new ModelState() { Value = new ValueProviderResult("bar", "bar", CultureInfo.InvariantCulture) });
new ModelState());
// Act
var serializableError = new SerializableError(modelState);

View File

@ -2086,13 +2086,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
// Assert
var result = await ReadValue<UserWithAddress>(response);
// Though posted content did not contain any valid Addresses, it is bound as a single-element List
// containing null. Slightly odd behavior is specific to this unusual error case: CollectionModelBinder
// attempted to bind a comma-separated string as a collection and Address lacks a from-string conversion.
// MutableObjectModelBinder does not create model when value providers have no data (unless at top level).
var address = Assert.Single(result.Addresses);
Assert.Null(address);
Assert.Empty(result.Addresses);
}
[Fact]
@ -2153,12 +2147,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
// Assert
var result = await ReadValue<PeopleModel>(response);
// Though posted content did not contain any valid People, it is bound as a single-element List
// containing null. Slightly odd behavior is specific to this unusual error case: CollectionModelBinder
// attempted to bind a comma-separated string as a collection and Address lacks a from-string conversion.
// MutableObjectModelBinder does not create model when value providers have no data (unless at top level).
var person = Assert.Single(result.People);
Assert.Null(person);
Assert.Empty(result.People);
}
[Theory]

View File

@ -65,9 +65,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.Equal(1, modelState.Keys.Count);
var key = Assert.Single(modelState.Keys, k => k == "Address[0].Street");
Assert.NotNull(modelState[key].Value);
Assert.Equal("SomeStreet", modelState[key].Value.AttemptedValue);
Assert.Equal("SomeStreet", modelState[key].Value.RawValue);
Assert.Equal("SomeStreet", modelState[key].AttemptedValue);
Assert.Equal("SomeStreet", modelState[key].RawValue);
Assert.Empty(modelState[key].Errors);
Assert.Equal(ModelValidationState.Valid, modelState[key].ValidationState);
}
@ -116,7 +115,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
var state = entry.Value;
Assert.NotNull(state);
Assert.Equal(ModelValidationState.Valid, state.ValidationState);
Assert.Equal("SomeStreet", state.Value.RawValue);
Assert.Equal("SomeStreet", state.RawValue);
Assert.Equal("SomeStreet", state.AttemptedValue);
}
private class Person4
@ -161,9 +161,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.Equal(1, modelState.Keys.Count);
var key = Assert.Single(modelState.Keys, k => k == "Address[0].Street");
Assert.NotNull(modelState[key].Value);
Assert.Equal("SomeStreet", modelState[key].Value.AttemptedValue);
Assert.Equal("SomeStreet", modelState[key].Value.RawValue);
Assert.Equal("SomeStreet", modelState[key].AttemptedValue);
Assert.Equal("SomeStreet", modelState[key].RawValue);
Assert.Empty(modelState[key].Errors);
Assert.Equal(ModelValidationState.Valid, modelState[key].ValidationState);
}
@ -250,9 +249,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.Equal(1, modelState.Keys.Count);
var key = Assert.Single(modelState.Keys, k => k == "prefix.Address[0].Street");
Assert.NotNull(modelState[key].Value);
Assert.Equal("SomeStreet", modelState[key].Value.AttemptedValue);
Assert.Equal("SomeStreet", modelState[key].Value.RawValue);
Assert.Equal("SomeStreet", modelState[key].AttemptedValue);
Assert.Equal("SomeStreet", modelState[key].RawValue);
Assert.Empty(modelState[key].Errors);
Assert.Equal(ModelValidationState.Valid, modelState[key].ValidationState);
}
@ -300,7 +298,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
var state = entry.Value;
Assert.NotNull(state);
Assert.Equal(ModelValidationState.Valid, state.ValidationState);
Assert.Equal("SomeStreet", state.Value.RawValue);
Assert.Equal("SomeStreet", state.AttemptedValue);
Assert.Equal("SomeStreet", state.RawValue);
}
[Fact]
@ -343,9 +342,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.Equal(1, modelState.Keys.Count);
var key = Assert.Single(modelState.Keys, k => k == "prefix.Address[0].Street");
Assert.NotNull(modelState[key].Value);
Assert.Equal("SomeStreet", modelState[key].Value.AttemptedValue);
Assert.Equal("SomeStreet", modelState[key].Value.RawValue);
Assert.Equal("SomeStreet", modelState[key].AttemptedValue);
Assert.Equal("SomeStreet", modelState[key].RawValue);
Assert.Empty(modelState[key].Errors);
Assert.Equal(ModelValidationState.Valid, modelState[key].ValidationState);
}

View File

@ -44,12 +44,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, kvp => kvp.Key == "parameter[0]").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
entry = Assert.Single(modelState, kvp => kvp.Key == "parameter[1]").Value;
Assert.Equal("11", entry.Value.AttemptedValue);
Assert.Equal("11", entry.Value.RawValue);
Assert.Equal("11", entry.AttemptedValue);
Assert.Equal("11", entry.RawValue);
}
[Fact]
@ -89,12 +89,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, kvp => kvp.Key == "prefix[0]").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
entry = Assert.Single(modelState, kvp => kvp.Key == "prefix[1]").Value;
Assert.Equal("11", entry.Value.AttemptedValue);
Assert.Equal("11", entry.Value.RawValue);
Assert.Equal("11", entry.AttemptedValue);
Assert.Equal("11", entry.RawValue);
}
[Fact]
@ -130,12 +130,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, kvp => kvp.Key == "[0]").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
entry = Assert.Single(modelState, kvp => kvp.Key == "[1]").Value;
Assert.Equal("11", entry.Value.AttemptedValue);
Assert.Equal("11", entry.Value.RawValue);
Assert.Equal("11", entry.AttemptedValue);
Assert.Equal("11", entry.RawValue);
}
[Fact]
@ -208,12 +208,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, kvp => kvp.Key == "parameter[0].Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
entry = Assert.Single(modelState, kvp => kvp.Key == "parameter[1].Name").Value;
Assert.Equal("lang", entry.Value.AttemptedValue);
Assert.Equal("lang", entry.Value.RawValue);
Assert.Equal("lang", entry.AttemptedValue);
Assert.Equal("lang", entry.RawValue);
}
[Fact]
@ -254,12 +254,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, kvp => kvp.Key == "prefix[0].Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
entry = Assert.Single(modelState, kvp => kvp.Key == "prefix[1].Name").Value;
Assert.Equal("lang", entry.Value.AttemptedValue);
Assert.Equal("lang", entry.Value.RawValue);
Assert.Equal("lang", entry.AttemptedValue);
Assert.Equal("lang", entry.RawValue);
}
[Fact]
@ -296,12 +296,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, kvp => kvp.Key == "[0].Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
entry = Assert.Single(modelState, kvp => kvp.Key == "[1].Name").Value;
Assert.Equal("lang", entry.Value.AttemptedValue);
Assert.Equal("lang", entry.Value.RawValue);
Assert.Equal("lang", entry.AttemptedValue);
Assert.Equal("lang", entry.RawValue);
}
[Fact]

View File

@ -190,7 +190,7 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
var key = Assert.Single(modelState.Keys);
Assert.Equal("CustomParameter", key);
Assert.Equal(ModelValidationState.Valid, modelState[key].ValidationState);
Assert.NotNull(modelState[key].Value); // Value is set by test model binder, no need to validate it.
Assert.NotNull(modelState[key].RawValue); // Value is set by test model binder, no need to validate it.
}
private class Person
@ -239,7 +239,7 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.Equal(1, modelState.Keys.Count);
var key = Assert.Single(modelState.Keys, k => k == "Parameter1.Address.Street");
Assert.Equal(ModelValidationState.Valid, modelState[key].ValidationState);
Assert.NotNull(modelState[key].Value); // Value is set by test model binder, no need to validate it.
Assert.NotNull(modelState[key].RawValue); // Value is set by test model binder, no need to validate it.
}
[Fact]
@ -279,7 +279,7 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.Equal(1, modelState.Keys.Count);
var key = Assert.Single(modelState.Keys, k => k == "CustomParameter.Address.Street");
Assert.Equal(ModelValidationState.Valid, modelState[key].ValidationState);
Assert.NotNull(modelState[key].Value); // Value is set by test model binder, no need to validate it.
Assert.NotNull(modelState[key].RawValue); // Value is set by test model binder, no need to validate it.
}
private class AddressModelBinder : IModelBinder
@ -294,11 +294,9 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
var address = new Address() { Street = "SomeStreet" };
bindingContext.ModelState.SetModelValue(
ModelNames.CreatePropertyModelName(bindingContext.ModelName, "Street"),
new ValueProviderResult(
address.Street,
address.Street,
CultureInfo.CurrentCulture));
ModelNames.CreatePropertyModelName(bindingContext.ModelName, "Street"),
new string[] { address.Street },
address.Street);
var validationNode = new ModelValidationNode(
bindingContext.ModelName,
@ -319,7 +317,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
var model = "Success";
bindingContext.ModelState.SetModelValue(
bindingContext.ModelName,
new ValueProviderResult(model, model, CultureInfo.CurrentCulture));
new string[] { model },
model);
var modelValidationNode = new ModelValidationNode(
bindingContext.ModelName,

View File

@ -102,7 +102,7 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState);
Assert.Empty(entry.Key);
Assert.Null(entry.Value.Value.RawValue);
Assert.Null(entry.Value.RawValue);
}
private class Person4
@ -112,7 +112,7 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
public int Address { get; set; }
}
[Fact]
[Fact(Skip = "#2722 validation error from formatter is recorded with the wrong key.")]
public async Task FromBodyAndRequiredOnValueTypeProperty_EmptyBody_JsonFormatterAddsModelStateError()
{
// Arrange
@ -146,7 +146,9 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.False(modelState.IsValid);
var entry = Assert.Single(modelState);
Assert.Equal(string.Empty, entry.Key);
Assert.Equal("CustomParameter.Address", entry.Key);
Assert.Null(entry.Value.AttemptedValue);
Assert.Same(boundPerson, entry.Value.RawValue);
var error = Assert.Single(entry.Value.Errors);
Assert.NotNull(error.Exception);

View File

@ -65,8 +65,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.Equal(queryStringKey, entry.Key);
Assert.Empty(entry.Value.Errors);
Assert.Equal(ModelValidationState.Valid, entry.Value.ValidationState);
Assert.Equal(value, entry.Value.Value.AttemptedValue);
Assert.Equal(value, entry.Value.Value.RawValue);
Assert.Equal(value, entry.Value.AttemptedValue);
Assert.Equal(value, entry.Value.RawValue);
}
[Fact]
@ -146,8 +146,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
var entry = Assert.Single(modelState);
Assert.Equal("CustomParameter", entry.Key);
Assert.Empty(entry.Value.Errors);
Assert.Equal(value, entry.Value.Value.AttemptedValue);
Assert.Equal(value, entry.Value.Value.RawValue);
Assert.Equal(value, entry.Value.AttemptedValue);
Assert.Equal(value, entry.Value.RawValue);
}
}
}

View File

@ -51,12 +51,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, kvp => kvp.Key == "parameter[0]").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
entry = Assert.Single(modelState, kvp => kvp.Key == "parameter[1]").Value;
Assert.Equal("11", entry.Value.AttemptedValue);
Assert.Equal("11", entry.Value.RawValue);
Assert.Equal("11", entry.AttemptedValue);
Assert.Equal("11", entry.RawValue);
}
[Fact]
@ -96,12 +96,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, kvp => kvp.Key == "prefix[0]").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
entry = Assert.Single(modelState, kvp => kvp.Key == "prefix[1]").Value;
Assert.Equal("11", entry.Value.AttemptedValue);
Assert.Equal("11", entry.Value.RawValue);
Assert.Equal("11", entry.AttemptedValue);
Assert.Equal("11", entry.RawValue);
}
[Fact]
@ -137,12 +137,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, kvp => kvp.Key == "[0]").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
entry = Assert.Single(modelState, kvp => kvp.Key == "[1]").Value;
Assert.Equal("11", entry.Value.AttemptedValue);
Assert.Equal("11", entry.Value.RawValue);
Assert.Equal("11", entry.AttemptedValue);
Assert.Equal("11", entry.RawValue);
}
[Fact]
@ -215,12 +215,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, kvp => kvp.Key == "parameter[0].Id").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
entry = Assert.Single(modelState, kvp => kvp.Key == "parameter[1].Id").Value;
Assert.Equal("11", entry.Value.AttemptedValue);
Assert.Equal("11", entry.Value.RawValue);
Assert.Equal("11", entry.AttemptedValue);
Assert.Equal("11", entry.RawValue);
}
[Fact]
@ -261,12 +261,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, kvp => kvp.Key == "prefix[0].Id").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
entry = Assert.Single(modelState, kvp => kvp.Key == "prefix[1].Id").Value;
Assert.Equal("11", entry.Value.AttemptedValue);
Assert.Equal("11", entry.Value.RawValue);
Assert.Equal("11", entry.AttemptedValue);
Assert.Equal("11", entry.RawValue);
}
[Fact]
@ -303,12 +303,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, kvp => kvp.Key == "[0].Id").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
entry = Assert.Single(modelState, kvp => kvp.Key == "[1].Id").Value;
Assert.Equal("11", entry.Value.AttemptedValue);
Assert.Equal("11", entry.Value.RawValue);
Assert.Equal("11", entry.AttemptedValue);
Assert.Equal("11", entry.RawValue);
}
[Fact]
@ -386,21 +386,21 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.False(modelState.IsValid);
var entry = Assert.Single(modelState, kvp => kvp.Key == "parameter[0].Id").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
entry = Assert.Single(modelState, kvp => kvp.Key == "parameter[1].Id").Value;
Assert.Equal("11", entry.Value.AttemptedValue);
Assert.Equal("11", entry.Value.RawValue);
Assert.Equal("11", entry.AttemptedValue);
Assert.Equal("11", entry.RawValue);
entry = Assert.Single(modelState, kvp => kvp.Key == "parameter[0].Name").Value;
Assert.Null(entry.Value);
Assert.Null(entry.RawValue);
Assert.Equal(ModelValidationState.Invalid, entry.ValidationState);
var error = Assert.Single(entry.Errors);
Assert.Equal("A value for the 'Name' property was not provided.", error.ErrorMessage);
entry = Assert.Single(modelState, kvp => kvp.Key == "parameter[1].Name").Value;
Assert.Null(entry.Value);
Assert.Null(entry.RawValue);
Assert.Equal(ModelValidationState.Invalid, entry.ValidationState);
error = Assert.Single(entry.Errors);
Assert.Equal("A value for the 'Name' property was not provided.", error.ErrorMessage);
@ -446,19 +446,19 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.False(modelState.IsValid);
var entry = Assert.Single(modelState, kvp => kvp.Key == "prefix[0].Id").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
entry = Assert.Single(modelState, kvp => kvp.Key == "prefix[1].Id").Value;
Assert.Equal("11", entry.Value.AttemptedValue);
Assert.Equal("11", entry.Value.RawValue);
Assert.Equal("11", entry.AttemptedValue);
Assert.Equal("11", entry.RawValue);
entry = Assert.Single(modelState, kvp => kvp.Key == "prefix[0].Name").Value;
Assert.Null(entry.Value);
Assert.Null(entry.RawValue);
Assert.Equal(ModelValidationState.Invalid, entry.ValidationState);
entry = Assert.Single(modelState, kvp => kvp.Key == "prefix[1].Name").Value;
Assert.Null(entry.Value);
Assert.Null(entry.RawValue);
Assert.Equal(ModelValidationState.Invalid, entry.ValidationState);
}
@ -498,19 +498,19 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.False(modelState.IsValid);
var entry = Assert.Single(modelState, kvp => kvp.Key == "[0].Id").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
entry = Assert.Single(modelState, kvp => kvp.Key == "[1].Id").Value;
Assert.Equal("11", entry.Value.AttemptedValue);
Assert.Equal("11", entry.Value.RawValue);
Assert.Equal("11", entry.AttemptedValue);
Assert.Equal("11", entry.RawValue);
entry = Assert.Single(modelState, kvp => kvp.Key == "[0].Name").Value;
Assert.Null(entry.Value);
Assert.Null(entry.RawValue);
Assert.Equal(ModelValidationState.Invalid, entry.ValidationState);
entry = Assert.Single(modelState, kvp => kvp.Key == "[1].Name").Value;
Assert.Null(entry.Value);
Assert.Null(entry.RawValue);
Assert.Equal(ModelValidationState.Invalid, entry.ValidationState);
}
@ -595,12 +595,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.Equal(0, modelState.ErrorCount);
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, kvp => kvp.Key == "Addresses[Key1].Street").Value;
Assert.Equal("Street1", entry.Value.AttemptedValue);
Assert.Equal("Street1", entry.Value.RawValue);
Assert.Equal("Street1", entry.AttemptedValue);
Assert.Equal("Street1", entry.RawValue);
entry = Assert.Single(modelState, kvp => kvp.Key == "Addresses[Key2].Street").Value;
Assert.Equal("Street2", entry.Value.AttemptedValue);
Assert.Equal("Street2", entry.Value.RawValue);
Assert.Equal("Street2", entry.AttemptedValue);
Assert.Equal("Street2", entry.RawValue);
}
private class Person5

View File

@ -45,12 +45,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, kvp => kvp.Key == "parameter[0].Key").Value;
Assert.Equal("key0", entry.Value.AttemptedValue);
Assert.Equal("key0", entry.Value.RawValue);
Assert.Equal("key0", entry.AttemptedValue);
Assert.Equal("key0", entry.RawValue);
entry = Assert.Single(modelState, kvp => kvp.Key == "parameter[0].Value").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
}
[Fact]
@ -87,8 +87,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
var kvp = Assert.Single(modelState);
Assert.Equal("parameter[key0]", kvp.Key);
var entry = kvp.Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
}
[Theory]

View File

@ -71,7 +71,7 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.Equal(2, modelState.Count);
Assert.Single(modelState.Keys, k => k == "Address.Zip");
var key = Assert.Single(modelState.Keys, k => k == "Address.File");
Assert.NotNull(modelState[key].Value);
Assert.Null(modelState[key].RawValue);
Assert.Empty(modelState[key].Errors);
Assert.Equal(ModelValidationState.Skipped, modelState[key].ValidationState);
}
@ -122,8 +122,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.Equal("CustomParameter", entry.Key);
Assert.Empty(entry.Value.Errors);
Assert.Equal(ModelValidationState.Skipped, entry.Value.ValidationState);
Assert.Null(entry.Value.Value.AttemptedValue);
Assert.Equal(file, entry.Value.Value.RawValue);
Assert.Null(entry.Value.AttemptedValue);
Assert.Null(entry.Value.RawValue);
}
[Fact]

View File

@ -276,12 +276,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter[0][0].Key").Value;
Assert.Equal("key0", entry.Value.AttemptedValue);
Assert.Equal("key0", entry.Value.RawValue);
Assert.Equal("key0", entry.AttemptedValue);
Assert.Equal("key0", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "parameter[0][0].Value").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
}
// This is part of a random sampling of scenarios where a GenericModelBinder is used
@ -322,12 +322,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "[0][0].Key").Value;
Assert.Equal("key0", entry.Value.AttemptedValue);
Assert.Equal("key0", entry.Value.RawValue);
Assert.Equal("key0", entry.AttemptedValue);
Assert.Equal("key0", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "[0][0].Value").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
}
// This is part of a random sampling of scenarios where a GenericModelBinder is used
@ -403,12 +403,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter[0].Key").Value;
Assert.Equal("key0", entry.Value.AttemptedValue);
Assert.Equal("key0", entry.Value.RawValue);
Assert.Equal("key0", entry.AttemptedValue);
Assert.Equal("key0", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "parameter[0].Value").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
}
// This is part of a random sampling of scenarios where a GenericModelBinder is used
@ -448,12 +448,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "[0].Key").Value;
Assert.Equal("key0", entry.Value.AttemptedValue);
Assert.Equal("key0", entry.Value.RawValue);
Assert.Equal("key0", entry.AttemptedValue);
Assert.Equal("key0", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "[0].Value").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
}
// This is part of a random sampling of scenarios where a GenericModelBinder is used
@ -530,16 +530,16 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter[0].Key").Value;
Assert.Equal("key0", entry.Value.AttemptedValue);
Assert.Equal("key0", entry.Value.RawValue);
Assert.Equal("key0", entry.AttemptedValue);
Assert.Equal("key0", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "parameter[0].Value[0]").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "parameter[0].Value[1]").Value;
Assert.Equal("11", entry.Value.AttemptedValue);
Assert.Equal("11", entry.Value.RawValue);
Assert.Equal("11", entry.AttemptedValue);
Assert.Equal("11", entry.RawValue);
}
// This is part of a random sampling of scenarios where a GenericModelBinder is used
@ -579,16 +579,16 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "[0].Key").Value;
Assert.Equal("key0", entry.Value.AttemptedValue);
Assert.Equal("key0", entry.Value.RawValue);
Assert.Equal("key0", entry.AttemptedValue);
Assert.Equal("key0", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "[0].Value[0]").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "[0].Value[1]").Value;
Assert.Equal("11", entry.Value.AttemptedValue);
Assert.Equal("11", entry.Value.RawValue);
Assert.Equal("11", entry.AttemptedValue);
Assert.Equal("11", entry.RawValue);
}
// This is part of a random sampling of scenarios where a GenericModelBinder is used

View File

@ -109,8 +109,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.Equal("prefix.Address.Header", entry.Key);
Assert.Empty(entry.Value.Errors);
Assert.Equal(ModelValidationState.Valid, entry.Value.ValidationState);
Assert.Equal("someValue", entry.Value.Value.AttemptedValue);
Assert.Equal("someValue", entry.Value.Value.RawValue);
Assert.Equal("someValue", entry.Value.AttemptedValue);
Assert.Equal(new string[] { "someValue" }, entry.Value.RawValue);
}
// The scenario is interesting as we to bind the top level model we fallback to empty prefix,
@ -152,8 +152,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.Equal("Address.Header", entry.Key);
Assert.Empty(entry.Value.Errors);
Assert.Equal(ModelValidationState.Valid, entry.Value.ValidationState);
Assert.Equal("someValue", entry.Value.Value.AttemptedValue);
Assert.Equal("someValue", entry.Value.Value.RawValue);
Assert.Equal("someValue", entry.Value.AttemptedValue);
Assert.Equal(new string[] { "someValue" }, entry.Value.RawValue);
}
[Theory]
@ -162,9 +162,18 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
public async Task BindParameterFromHeader_WithData_WithPrefix_ModelGetsBound(Type modelType, string value)
{
// Arrange
var expectedValue = modelType == typeof(string) ?
(object)value :
(object)value.Split(',').Select(v => v.Trim()).ToArray();
object expectedValue;
object expectedRawValue;
if (modelType == typeof(string))
{
expectedValue = value;
expectedRawValue = new string[] { value };
}
else
{
expectedValue = value.Split(',').Select(v => v.Trim()).ToArray();
expectedRawValue = expectedValue;
}
var argumentBinder = ModelBindingTestHelper.GetArgumentBinder();
var parameter = new ParameterDescriptor
@ -204,8 +213,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.Equal("CustomParameter", entry.Key);
Assert.Empty(entry.Value.Errors);
Assert.Equal(ModelValidationState.Valid, entry.Value.ValidationState);
Assert.Equal(value, entry.Value.Value.AttemptedValue);
Assert.Equal(expectedValue, entry.Value.Value.RawValue);
Assert.Equal(value, entry.Value.AttemptedValue);
Assert.Equal(expectedRawValue, entry.Value.RawValue);
}
}
}

View File

@ -45,12 +45,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, kvp => kvp.Key == "parameter.Key").Value;
Assert.Equal("key0", entry.Value.AttemptedValue);
Assert.Equal("key0", entry.Value.RawValue);
Assert.Equal("key0", entry.AttemptedValue);
Assert.Equal("key0", entry.RawValue);
entry = Assert.Single(modelState, kvp => kvp.Key == "parameter.Value").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
}
[Fact]
@ -90,12 +90,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, kvp => kvp.Key == "prefix.Key").Value;
Assert.Equal("key0", entry.Value.AttemptedValue);
Assert.Equal("key0", entry.Value.RawValue);
Assert.Equal("key0", entry.AttemptedValue);
Assert.Equal("key0", entry.RawValue);
entry = Assert.Single(modelState, kvp => kvp.Key == "prefix.Value").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
}
[Fact]
@ -131,12 +131,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, kvp => kvp.Key == "Key").Value;
Assert.Equal("key0", entry.Value.AttemptedValue);
Assert.Equal("key0", entry.Value.RawValue);
Assert.Equal("key0", entry.AttemptedValue);
Assert.Equal("key0", entry.RawValue);
entry = Assert.Single(modelState, kvp => kvp.Key == "Value").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
}
[Fact]
@ -210,12 +210,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, kvp => kvp.Key == "parameter.Key").Value;
Assert.Equal("key0", entry.Value.AttemptedValue);
Assert.Equal("key0", entry.Value.RawValue);
Assert.Equal("key0", entry.AttemptedValue);
Assert.Equal("key0", entry.RawValue);
entry = Assert.Single(modelState, kvp => kvp.Key == "parameter.Value.Id").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal(model.Value.Id.ToString(), entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
}
[Fact]
@ -256,12 +256,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, kvp => kvp.Key == "prefix.Key").Value;
Assert.Equal("key0", entry.Value.AttemptedValue);
Assert.Equal("key0", entry.Value.RawValue);
Assert.Equal("key0", entry.AttemptedValue);
Assert.Equal("key0", entry.RawValue);
entry = Assert.Single(modelState, kvp => kvp.Key == "prefix.Value.Id").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
}
[Fact]
@ -298,12 +298,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, kvp => kvp.Key == "Key").Value;
Assert.Equal("key0", entry.Value.AttemptedValue);
Assert.Equal("key0", entry.Value.RawValue);
Assert.Equal("key0", entry.AttemptedValue);
Assert.Equal("key0", entry.RawValue);
entry = Assert.Single(modelState, kvp => kvp.Key == "Value.Id").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
}
[Fact]

View File

@ -82,12 +82,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.Customer.Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "parameter.Customer.Address").Value;
Assert.Null(entry.Value.AttemptedValue); // ModelState entries for body don't include original text.
Assert.Same(model.Customer.Address, entry.Value.RawValue);
Assert.Null(entry.AttemptedValue); // ModelState entries for body don't include original text.
Assert.Same(model.Customer.Address, entry.RawValue);
}
[Fact]
@ -128,12 +128,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "Customer.Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "Customer.Address").Value;
Assert.Null(entry.Value.AttemptedValue); // ModelState entries for body don't include original text.
Assert.Same(model.Customer.Address, entry.Value.RawValue);
Assert.Null(entry.AttemptedValue); // ModelState entries for body don't include original text.
Assert.Same(model.Customer.Address, entry.RawValue);
}
[Fact]
@ -173,11 +173,11 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.Customer.Address").Value;
Assert.Null(entry.Value.AttemptedValue);
Assert.Null(entry.Value.RawValue);
Assert.Null(entry.AttemptedValue);
Assert.Null(entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "parameter.Customer.Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
}
// We don't provide enough data in this test for the 'Person' model to be created. So even though there is
@ -218,8 +218,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.ProductId").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
}
// We don't provide enough data in this test for the 'Person' model to be created. So even though there is
@ -310,8 +310,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.Customer.Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
}
[Fact]
@ -350,8 +350,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "Customer.Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
}
// We don't provide enough data in this test for the 'Person' model to be created. So even though there is
@ -392,8 +392,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.ProductId").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
}
// We don't provide enough data in this test for the 'Person' model to be created. So even though there is
@ -484,12 +484,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.Customer.Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "parameter.Customer.Token").Value;
Assert.Equal(ByteArrayEncoded, entry.Value.AttemptedValue);
Assert.Equal(ByteArrayEncoded, entry.Value.RawValue);
Assert.Equal(ByteArrayEncoded, entry.AttemptedValue);
Assert.Equal(ByteArrayEncoded, entry.RawValue);
}
[Fact]
@ -528,12 +528,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "Customer.Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "Customer.Token").Value;
Assert.Equal(ByteArrayEncoded, entry.Value.AttemptedValue);
Assert.Equal(ByteArrayEncoded, entry.Value.RawValue);
Assert.Equal(ByteArrayEncoded, entry.AttemptedValue);
Assert.Equal(ByteArrayEncoded, entry.RawValue);
}
[Fact]
@ -572,8 +572,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.Customer.Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
}
private class Order4
@ -627,12 +627,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.Customer.Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "parameter.Customer.Documents").Value;
Assert.Null(entry.Value.AttemptedValue); // FormFile entries for body don't include original text.
Assert.Same(model.Customer.Documents, entry.Value.RawValue);
Assert.Null(entry.AttemptedValue); // FormFile entries for body don't include original text.
Assert.Null(entry.RawValue);
}
[Fact]
@ -672,12 +672,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "Customer.Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "Customer.Documents").Value;
Assert.Null(entry.Value.AttemptedValue); // FormFile entries for body don't include original text.
Assert.Same(model.Customer.Documents, entry.Value.RawValue);
Assert.Null(entry.AttemptedValue); // FormFile entries don't include the model.
Assert.Null(entry.RawValue);
}
[Fact]
@ -718,13 +718,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.Customer.Documents").Value;
Assert.Null(entry.Value.AttemptedValue);
var documents = Assert.IsAssignableFrom<IEnumerable<IFormFile>>(entry.Value.RawValue);
Assert.Empty(documents);
Assert.Null(entry.AttemptedValue); // FormFile entries don't include the model.
Assert.Null(entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "parameter.Customer.Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
}
// We don't provide enough data in this test for the 'Person' model to be created. So even though there are
@ -765,8 +764,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.ProductId").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
}
// We don't provide enough data in this test for the 'Person' model to be created. So even though there is
@ -849,16 +848,16 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "parameter.ProductIds[0]").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "parameter.ProductIds[1]").Value;
Assert.Equal("11", entry.Value.AttemptedValue);
Assert.Equal("11", entry.Value.RawValue);
Assert.Equal("11", entry.AttemptedValue);
Assert.Equal("11", entry.RawValue);
}
[Fact]
@ -897,16 +896,16 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "ProductIds[0]").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "ProductIds[1]").Value;
Assert.Equal("11", entry.Value.AttemptedValue);
Assert.Equal("11", entry.Value.RawValue);
Assert.Equal("11", entry.AttemptedValue);
Assert.Equal("11", entry.RawValue);
}
[Fact]
@ -944,8 +943,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
}
[Fact]
@ -1026,16 +1025,16 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "parameter.ProductIds[0]").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "parameter.ProductIds[1]").Value;
Assert.Equal("11", entry.Value.AttemptedValue);
Assert.Equal("11", entry.Value.RawValue);
Assert.Equal("11", entry.AttemptedValue);
Assert.Equal("11", entry.RawValue);
}
[Fact]
@ -1074,16 +1073,16 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "ProductIds[0]").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "ProductIds[1]").Value;
Assert.Equal("11", entry.Value.AttemptedValue);
Assert.Equal("11", entry.Value.RawValue);
Assert.Equal("11", entry.AttemptedValue);
Assert.Equal("11", entry.RawValue);
}
[Fact]
@ -1121,8 +1120,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
}
[Fact]
@ -1203,16 +1202,16 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "parameter.ProductIds[0].Key").Value;
Assert.Equal("key0", entry.Value.AttemptedValue);
Assert.Equal("key0", entry.Value.RawValue);
Assert.Equal("key0", entry.AttemptedValue);
Assert.Equal("key0", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "parameter.ProductIds[0].Value").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
}
[Fact]
@ -1251,16 +1250,16 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "ProductIds[0].Key").Value;
Assert.Equal("key0", entry.Value.AttemptedValue);
Assert.Equal("key0", entry.Value.RawValue);
Assert.Equal("key0", entry.AttemptedValue);
Assert.Equal("key0", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "ProductIds[0].Value").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
}
[Fact]
@ -1298,8 +1297,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
}
[Fact]
@ -1380,16 +1379,16 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "parameter.ProductId.Key").Value;
Assert.Equal("key0", entry.Value.AttemptedValue);
Assert.Equal("key0", entry.Value.RawValue);
Assert.Equal("key0", entry.AttemptedValue);
Assert.Equal("key0", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "parameter.ProductId.Value").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
}
[Fact]
@ -1428,16 +1427,16 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "ProductId.Key").Value;
Assert.Equal("key0", entry.Value.AttemptedValue);
Assert.Equal("key0", entry.Value.RawValue);
Assert.Equal("key0", entry.AttemptedValue);
Assert.Equal("key0", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "ProductId.Value").Value;
Assert.Equal("10", entry.Value.AttemptedValue);
Assert.Equal("10", entry.Value.RawValue);
Assert.Equal("10", entry.AttemptedValue);
Assert.Equal("10", entry.RawValue);
}
[Fact]
@ -1475,8 +1474,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
}
[Fact]
@ -1568,8 +1567,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "Customer.Address").Value;
Assert.Null(entry.Value.AttemptedValue);
Assert.Same(model.Customer.Address, entry.Value.RawValue);
Assert.Null(entry.AttemptedValue);
Assert.Same(model.Customer.Address, entry.RawValue);
}
private class Order10
@ -1616,7 +1615,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.False(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "Customer").Value;
Assert.Null(entry.Value);
Assert.Null(entry.RawValue);
Assert.Null(entry.AttemptedValue);
var error = Assert.Single(modelState["Customer"].Errors);
Assert.Equal("A value for the 'Customer' property was not provided.", error.ErrorMessage);
}
@ -1670,12 +1670,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.False(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.Customer.Id").Value;
Assert.NotNull(entry.Value);
Assert.Equal("123", entry.Value.RawValue);
Assert.Equal("123", entry.Value.AttemptedValue);
Assert.Equal("123", entry.RawValue);
Assert.Equal("123", entry.AttemptedValue);
entry = Assert.Single(modelState, e => e.Key == "parameter.Customer.Name").Value;
Assert.Null(entry.Value);
Assert.Null(entry.RawValue);
Assert.Null(entry.AttemptedValue);
var error = Assert.Single(modelState["parameter.Customer.Name"].Errors);
Assert.Equal("A value for the 'Name' property was not provided.", error.ErrorMessage);
}
@ -1716,12 +1716,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.False(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "Customer.Id").Value;
Assert.NotNull(entry.Value);
Assert.Equal("123", entry.Value.RawValue);
Assert.Equal("123", entry.Value.AttemptedValue);
Assert.Equal("123", entry.RawValue);
Assert.Equal("123", entry.AttemptedValue);
entry = Assert.Single(modelState, e => e.Key == "Customer.Name").Value;
Assert.Null(entry.Value);
Assert.Null(entry.RawValue);
Assert.Null(entry.AttemptedValue);
var error = Assert.Single(modelState["Customer.Name"].Errors);
Assert.Equal("A value for the 'Name' property was not provided.", error.ErrorMessage);
}
@ -1766,12 +1766,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.False(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "customParameter.Customer.Id").Value;
Assert.NotNull(entry.Value);
Assert.Equal("123", entry.Value.RawValue);
Assert.Equal("123", entry.Value.AttemptedValue);
Assert.Equal("123", entry.RawValue);
Assert.Equal("123", entry.AttemptedValue);
entry = Assert.Single(modelState, e => e.Key == "customParameter.Customer.Name").Value;
Assert.Null(entry.Value);
Assert.Null(entry.RawValue);
Assert.Null(entry.AttemptedValue);
var error = Assert.Single(modelState["customParameter.Customer.Name"].Errors);
Assert.Equal("A value for the 'Name' property was not provided.", error.ErrorMessage);
}
@ -1816,7 +1816,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.False(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "ProductName").Value;
Assert.Null(entry.Value);
Assert.Null(entry.RawValue);
Assert.Null(entry.AttemptedValue);
var error = Assert.Single(modelState["ProductName"].Errors);
Assert.Equal("A value for the 'ProductName' property was not provided.", error.ErrorMessage);
}
@ -1859,7 +1860,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.False(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "customParameter.ProductName").Value;
Assert.Null(entry.Value);
Assert.Null(entry.RawValue);
Assert.Null(entry.AttemptedValue);
var error = Assert.Single(modelState["customParameter.ProductName"].Errors);
Assert.Equal("A value for the 'ProductName' property was not provided.", error.ErrorMessage);
}
@ -1898,9 +1900,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "ProductName").Value;
Assert.NotNull(entry.Value);
Assert.Equal("abc", entry.Value.RawValue);
Assert.Equal("abc", entry.Value.AttemptedValue);
Assert.Equal("abc", entry.RawValue);
Assert.Equal("abc", entry.AttemptedValue);
}
private class Order13
@ -1943,7 +1944,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.False(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "OrderIds").Value;
Assert.Null(entry.Value);
Assert.Null(entry.RawValue);
Assert.Null(entry.AttemptedValue);
var error = Assert.Single(modelState["OrderIds"].Errors);
Assert.Equal("A value for the 'OrderIds' property was not provided.", error.ErrorMessage);
}
@ -1986,7 +1988,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.False(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "customParameter.OrderIds").Value;
Assert.Null(entry.Value);
Assert.Null(entry.RawValue);
Assert.Null(entry.AttemptedValue);
var error = Assert.Single(modelState["customParameter.OrderIds"].Errors);
Assert.Equal("A value for the 'OrderIds' property was not provided.", error.ErrorMessage);
}
@ -2025,9 +2028,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "OrderIds[0]").Value;
Assert.NotNull(entry.Value);
Assert.Equal("123", entry.Value.RawValue);
Assert.Equal("123", entry.Value.AttemptedValue);
Assert.Equal("123", entry.RawValue);
Assert.Equal("123", entry.AttemptedValue);
}
private class Order14
@ -2072,8 +2074,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.False(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.ProductId").Value;
Assert.Equal(string.Empty, entry.Value.AttemptedValue);
Assert.Equal(string.Empty, entry.Value.RawValue);
Assert.Equal(string.Empty, entry.AttemptedValue);
Assert.Equal(string.Empty, entry.RawValue);
var error = Assert.Single(entry.Errors);
Assert.Equal("The value '' is invalid.", error.ErrorMessage);

View File

@ -13,7 +13,7 @@ using Xunit;
namespace Microsoft.AspNet.Mvc.IntegrationTests
{
public class TypeConverterModelBinderIntegrationTest
public class SimpleTypeModelBinderIntegrationTest
{
[Fact]
public async Task BindProperty_WithData_WithPrefix_GetsBound()
@ -58,10 +58,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.Equal(1, modelState.Keys.Count);
var key = Assert.Single(modelState.Keys, k => k == "CustomParameter.Address.Zip");
Assert.NotNull(modelState[key].Value);
Assert.Equal("1", modelState[key].Value.AttemptedValue);
Assert.Equal("1", modelState[key].Value.RawValue);
Assert.NotNull(modelState[key].Value);
Assert.Equal("1", modelState[key].AttemptedValue);
Assert.Equal("1", modelState[key].RawValue);
Assert.Empty(modelState[key].Errors);
Assert.Equal(ModelValidationState.Valid, modelState[key].ValidationState);
}
@ -105,10 +103,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.Equal(1, modelState.Keys.Count);
var key = Assert.Single(modelState.Keys, k => k == "Address.Zip");
Assert.NotNull(modelState[key].Value);
Assert.Equal("1", modelState[key].Value.AttemptedValue);
Assert.Equal("1", modelState[key].Value.RawValue);
Assert.NotNull(modelState[key].Value);
Assert.Equal("1", modelState[key].AttemptedValue);
Assert.Equal("1", modelState[key].RawValue);
Assert.Empty(modelState[key].Errors);
Assert.Equal(ModelValidationState.Valid, modelState[key].ValidationState);
}
@ -152,13 +148,56 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.Equal(1, modelState.Keys.Count);
var key = Assert.Single(modelState.Keys);
Assert.Equal("Parameter1", key);
Assert.NotNull(modelState[key].Value);
Assert.Equal("someValue", modelState[key].Value.AttemptedValue);
Assert.Equal("someValue", modelState[key].Value.RawValue);
Assert.Equal("someValue", modelState[key].AttemptedValue);
Assert.Equal("someValue", modelState[key].RawValue);
Assert.Empty(modelState[key].Errors);
Assert.Equal(ModelValidationState.Valid, modelState[key].ValidationState);
}
[Fact]
public async Task BindParameter_WithMultipleValues_GetsBoundToFirstValue()
{
// Arrange
var argumentBinder = ModelBindingTestHelper.GetArgumentBinder();
var parameter = new ParameterDescriptor()
{
Name = "Parameter1",
BindingInfo = new BindingInfo(),
ParameterType = typeof(string)
};
var operationContext = ModelBindingTestHelper.GetOperationBindingContext(request =>
{
request.QueryString = new QueryString("?Parameter1=someValue&Parameter1=otherValue");
});
var modelState = new ModelStateDictionary();
// Act
var modelBindingResult = await argumentBinder.BindModelAsync(parameter, modelState, operationContext);
// Assert
// ModelBindingResult
Assert.NotNull(modelBindingResult);
Assert.True(modelBindingResult.IsModelSet);
// Model
var model = Assert.IsType<string>(modelBindingResult.Model);
Assert.Equal("someValue", model);
// ModelState
Assert.True(modelState.IsValid);
Assert.Equal(1, modelState.Keys.Count);
var key = Assert.Single(modelState.Keys);
Assert.Equal("Parameter1", key);
Assert.Equal("someValue,otherValue", modelState[key].AttemptedValue);
Assert.Equal(new string[] { "someValue", "otherValue" }, modelState[key].RawValue);
Assert.Empty(modelState[key].Errors);
Assert.Equal(ModelValidationState.Valid, modelState[key].ValidationState);
}
[Fact]
public async Task BindParameter_NonConvertableValue_GetsError()
@ -201,9 +240,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.Equal("Parameter1", key);
var entry = modelState[key];
Assert.NotNull(entry.Value);
Assert.Equal("abcd", entry.Value.AttemptedValue);
Assert.Equal("abcd", entry.Value.RawValue);
Assert.Equal("abcd", entry.RawValue);
Assert.Equal("abcd", entry.AttemptedValue);
Assert.Equal(ModelValidationState.Invalid, entry.ValidationState);
var error = Assert.Single(entry.Errors);
@ -247,8 +285,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.False(modelState.IsValid);
var key = Assert.Single(modelState.Keys);
Assert.Equal("Parameter1", key);
Assert.Equal(string.Empty, modelState[key].Value.AttemptedValue);
Assert.Equal(string.Empty, modelState[key].Value.RawValue);
Assert.Equal(string.Empty, modelState[key].AttemptedValue);
Assert.Equal(string.Empty, modelState[key].RawValue);
var error = Assert.Single(modelState[key].Errors);
Assert.Equal(error.ErrorMessage, "The value '' is invalid.", StringComparer.Ordinal);
Assert.Null(error.Exception);
@ -292,8 +330,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var key = Assert.Single(modelState.Keys);
Assert.Equal("Parameter1", key);
Assert.Equal(string.Empty, modelState[key].Value.AttemptedValue);
Assert.Equal(string.Empty, modelState[key].Value.RawValue);
Assert.Equal(string.Empty, modelState[key].AttemptedValue);
Assert.Equal(new string[] { string.Empty }, modelState[key].RawValue);
Assert.Empty(modelState[key].Errors);
}
@ -393,10 +431,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.NotNull(entry);
Assert.Empty(entry.Errors);
Assert.Equal(ModelValidationState.Valid, entry.ValidationState);
var result = entry.Value;
Assert.NotNull(result);
Assert.Equal("line 1,line 2", result.AttemptedValue);
Assert.Equal(new[] { "line 1", "line 2" }, result.RawValue);
Assert.Equal("line 1,line 2", entry.AttemptedValue);
Assert.Equal(new[] { "line 1", "line 2" }, entry.RawValue);
}
private class Person

View File

@ -53,9 +53,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
var entry = Assert.Single(modelState);
Assert.Equal("Street", entry.Key);
var state = entry.Value;
Assert.NotNull(state.Value);
Assert.Equal("SomeStreet", state.Value.AttemptedValue);
Assert.Equal("SomeStreet", state.Value.RawValue);
Assert.Equal("SomeStreet", state.AttemptedValue);
Assert.Equal("SomeStreet", state.RawValue);
Assert.Empty(state.Errors);
Assert.Equal(ModelValidationState.Valid, state.ValidationState);
}
@ -88,9 +87,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
var entry = Assert.Single(modelState);
Assert.Equal("Street", entry.Key);
var state = entry.Value;
Assert.NotNull(state.Value);
Assert.Equal("SomeStreet", state.Value.AttemptedValue);
Assert.Equal("SomeStreet", state.Value.RawValue);
Assert.Equal("SomeStreet", state.AttemptedValue);
Assert.Equal("SomeStreet", state.RawValue);
Assert.Empty(state.Errors);
Assert.Equal(ModelValidationState.Valid, state.ValidationState);
}
@ -199,9 +197,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
var entry = Assert.Single(modelState);
Assert.Equal("Address.Street", entry.Key);
var state = entry.Value;
Assert.NotNull(state.Value);
Assert.Equal("SomeStreet", state.Value.AttemptedValue);
Assert.Equal("SomeStreet", state.Value.RawValue);
Assert.Equal("SomeStreet", state.AttemptedValue);
Assert.Equal("SomeStreet", state.RawValue);
Assert.Empty(state.Errors);
Assert.Equal(ModelValidationState.Valid, state.ValidationState);
}
@ -241,9 +238,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
var entry = Assert.Single(modelState);
Assert.Equal("Address[0].Street", entry.Key);
var state = entry.Value;
Assert.NotNull(state.Value);
Assert.Equal("SomeStreet", state.Value.AttemptedValue);
Assert.Equal("SomeStreet", state.Value.RawValue);
Assert.Equal("SomeStreet", state.AttemptedValue);
Assert.Equal("SomeStreet", state.RawValue);
Assert.Empty(state.Errors);
Assert.Equal(ModelValidationState.Valid, state.ValidationState);
}
@ -283,9 +279,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
var entry = Assert.Single(modelState);
Assert.Equal("Address[0].Street", entry.Key);
var state = entry.Value;
Assert.NotNull(state.Value);
Assert.Equal("SomeStreet", state.Value.AttemptedValue);
Assert.Equal("SomeStreet", state.Value.RawValue);
Assert.Equal("SomeStreet", state.AttemptedValue);
Assert.Equal("SomeStreet", state.RawValue);
Assert.Empty(state.Errors);
Assert.Equal(ModelValidationState.Valid, state.ValidationState);
}
@ -345,9 +340,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
var entry = Assert.Single(modelState);
Assert.Equal("Address[0].Street", entry.Key);
var state = entry.Value;
Assert.NotNull(state.Value);
Assert.Equal("SomeStreet", state.Value.AttemptedValue);
Assert.Equal("SomeStreet", state.Value.RawValue);
Assert.Equal("SomeStreet", state.AttemptedValue);
Assert.Equal("SomeStreet", state.RawValue);
Assert.Empty(state.Errors);
Assert.Equal(ModelValidationState.Valid, state.ValidationState);
}
@ -387,7 +381,7 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
var state = entry.Value;
Assert.NotNull(state);
Assert.Equal(ModelValidationState.Valid, state.ValidationState);
Assert.Equal("SomeStreet", state.Value.RawValue);
Assert.Equal("SomeStreet", state.RawValue);
}
private class Person4
@ -425,9 +419,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
var entry = Assert.Single(modelState);
Assert.Equal("Address[0].Street", entry.Key);
var state = entry.Value;
Assert.NotNull(state.Value);
Assert.Equal("SomeStreet", state.Value.AttemptedValue);
Assert.Equal("SomeStreet", state.Value.RawValue);
Assert.Equal("SomeStreet", state.AttemptedValue);
Assert.Equal("SomeStreet", state.RawValue);
Assert.Empty(state.Errors);
Assert.Equal(ModelValidationState.Valid, state.ValidationState);
}
@ -474,9 +467,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
var entry = Assert.Single(modelState);
Assert.Equal("Address[0].Street", entry.Key);
var state = entry.Value;
Assert.NotNull(state.Value);
Assert.Equal("SomeStreet", state.Value.AttemptedValue);
Assert.Equal("SomeStreet", state.Value.RawValue);
Assert.Equal("SomeStreet", state.AttemptedValue);
Assert.Equal("SomeStreet", state.RawValue);
Assert.Empty(state.Errors);
Assert.Equal(ModelValidationState.Valid, state.ValidationState);
}
@ -550,9 +542,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
var entry = Assert.Single(modelState);
Assert.Equal("prefix.Street", entry.Key);
var state = entry.Value;
Assert.NotNull(state.Value);
Assert.Equal("SomeStreet", state.Value.AttemptedValue);
Assert.Equal("SomeStreet", state.Value.RawValue);
Assert.Equal("SomeStreet", state.AttemptedValue);
Assert.Equal("SomeStreet", state.RawValue);
Assert.Empty(state.Errors);
Assert.Equal(ModelValidationState.Valid, state.ValidationState);
}
@ -585,9 +576,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
var entry = Assert.Single(modelState);
Assert.Equal("prefix.Street", entry.Key);
var state = entry.Value;
Assert.NotNull(state.Value);
Assert.Equal("SomeStreet", state.Value.AttemptedValue);
Assert.Equal("SomeStreet", state.Value.RawValue);
Assert.Equal("SomeStreet", state.AttemptedValue);
Assert.Equal("SomeStreet", state.RawValue);
Assert.Empty(state.Errors);
Assert.Equal(ModelValidationState.Valid, state.ValidationState);
}
@ -689,9 +679,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
var entry = Assert.Single(modelState);
Assert.Equal("prefix.Address.Street", entry.Key);
var state = entry.Value;
Assert.NotNull(state.Value);
Assert.Equal("SomeStreet", state.Value.AttemptedValue);
Assert.Equal("SomeStreet", state.Value.RawValue);
Assert.Equal("SomeStreet", state.AttemptedValue);
Assert.Equal("SomeStreet", state.RawValue);
Assert.Empty(state.Errors);
Assert.Equal(ModelValidationState.Valid, state.ValidationState);
}
@ -726,9 +715,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
var entry = Assert.Single(modelState);
Assert.Equal("prefix.Address[0].Street", entry.Key);
var state = entry.Value;
Assert.NotNull(state.Value);
Assert.Equal("SomeStreet", state.Value.AttemptedValue);
Assert.Equal("SomeStreet", state.Value.RawValue);
Assert.Equal("SomeStreet", state.AttemptedValue);
Assert.Equal("SomeStreet", state.RawValue);
Assert.Empty(state.Errors);
Assert.Equal(ModelValidationState.Valid, state.ValidationState);
}
@ -768,9 +756,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
var entry = Assert.Single(modelState);
Assert.Equal("prefix.Address[0].Street", entry.Key);
var state = entry.Value;
Assert.NotNull(state.Value);
Assert.Equal("SomeStreet", state.Value.AttemptedValue);
Assert.Equal("SomeStreet", state.Value.RawValue);
Assert.Equal("SomeStreet", state.AttemptedValue);
Assert.Equal("SomeStreet", state.RawValue);
Assert.Empty(state.Errors);
Assert.Equal(ModelValidationState.Valid, state.ValidationState);
}
@ -820,9 +807,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
var entry = Assert.Single(modelState);
Assert.Equal("prefix.Address[0].Street", entry.Key);
var state = entry.Value;
Assert.NotNull(state.Value);
Assert.Equal("SomeStreet", state.Value.AttemptedValue);
Assert.Equal("SomeStreet", state.Value.RawValue);
Assert.Equal("SomeStreet", state.AttemptedValue);
Assert.Equal("SomeStreet", state.RawValue);
Assert.Empty(state.Errors);
Assert.Equal(ModelValidationState.Valid, state.ValidationState);
}
@ -857,7 +843,7 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
var state = entry.Value;
Assert.NotNull(state);
Assert.Equal(ModelValidationState.Valid, state.ValidationState);
Assert.Equal("SomeStreet", state.Value.RawValue);
Assert.Equal("SomeStreet", state.RawValue);
}
[Fact]
@ -890,9 +876,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
var entry = Assert.Single(modelState);
Assert.Equal("prefix.Address[0].Street", entry.Key);
var state = entry.Value;
Assert.NotNull(state.Value);
Assert.Equal("SomeStreet", state.Value.AttemptedValue);
Assert.Equal("SomeStreet", state.Value.RawValue);
Assert.Equal("SomeStreet", state.AttemptedValue);
Assert.Equal("SomeStreet", state.RawValue);
Assert.Empty(state.Errors);
Assert.Equal(ModelValidationState.Valid, state.ValidationState);
}
@ -939,9 +924,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
var entry = Assert.Single(modelState);
Assert.Equal("prefix.Address[0].Street", entry.Key);
var state = entry.Value;
Assert.NotNull(state.Value);
Assert.Equal("SomeStreet", state.Value.AttemptedValue);
Assert.Equal("SomeStreet", state.Value.RawValue);
Assert.Equal("SomeStreet", state.AttemptedValue);
Assert.Equal("SomeStreet", state.RawValue);
Assert.Empty(state.Errors);
Assert.Equal(ModelValidationState.Valid, state.ValidationState);
}

View File

@ -53,8 +53,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.CustomerName").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
Assert.Empty(entry.Errors);
}
@ -91,7 +91,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.False(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "CustomerName").Value;
Assert.Null(entry.Value);
Assert.Null(entry.RawValue);
Assert.Null(entry.AttemptedValue);
Assert.Equal(ModelValidationState.Invalid, entry.ValidationState);
var error = Assert.Single(entry.Errors);
@ -143,8 +144,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.Customer.Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
Assert.Empty(entry.Errors);
}
@ -181,7 +182,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.False(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "Customer").Value;
Assert.Null(entry.Value);
Assert.Null(entry.RawValue);
Assert.Null(entry.AttemptedValue);
Assert.Equal(ModelValidationState.Invalid, entry.ValidationState);
var error = Assert.Single(entry.Errors);
@ -235,8 +237,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.Customer.Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
Assert.Empty(entry.Errors);
}
@ -276,7 +278,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.False(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.Customer.Name").Value;
Assert.Null(entry.Value);
Assert.Null(entry.RawValue);
Assert.Null(entry.AttemptedValue);
Assert.Equal(ModelValidationState.Invalid, entry.ValidationState);
var error = Assert.Single(entry.Errors);
@ -328,8 +331,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "Items[0].ItemId").Value;
Assert.Equal("17", entry.Value.AttemptedValue);
Assert.Equal("17", entry.Value.RawValue);
Assert.Equal("17", entry.AttemptedValue);
Assert.Equal("17", entry.RawValue);
Assert.Empty(entry.Errors);
}
@ -367,7 +370,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.False(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "Items").Value;
Assert.Null(entry.Value);
Assert.Null(entry.RawValue);
Assert.Null(entry.AttemptedValue);
Assert.Equal(ModelValidationState.Invalid, entry.ValidationState);
var error = Assert.Single(entry.Errors);
@ -415,8 +419,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter[0].ProductId").Value;
Assert.Equal("17", entry.Value.AttemptedValue);
Assert.Equal("17", entry.Value.RawValue);
Assert.Equal("17", entry.AttemptedValue);
Assert.Equal("17", entry.RawValue);
Assert.Empty(entry.Errors);
}
@ -456,7 +460,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.False(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter[0].ProductId").Value;
Assert.Null(entry.Value);
Assert.Null(entry.RawValue);
Assert.Null(entry.AttemptedValue);
Assert.Equal(ModelValidationState.Invalid, entry.ValidationState);
var error = Assert.Single(entry.Errors);
@ -502,8 +507,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
Assert.Empty(entry.Errors);
}
@ -540,8 +545,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.False(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.Name").Value;
Assert.Equal("billybob", entry.Value.AttemptedValue);
Assert.Equal("billybob", entry.Value.RawValue);
Assert.Equal("billybob", entry.AttemptedValue);
Assert.Equal("billybob", entry.RawValue);
var error = Assert.Single(entry.Errors);
Assert.Equal("Too Long.", error.ErrorMessage);
@ -592,8 +597,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.Customer.Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
Assert.Empty(entry.Errors);
}
@ -630,8 +635,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.False(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.Customer.Name").Value;
Assert.Equal("billybob", entry.Value.AttemptedValue);
Assert.Equal("billybob", entry.Value.RawValue);
Assert.Equal("billybob", entry.AttemptedValue);
Assert.Equal("billybob", entry.RawValue);
var error = Assert.Single(entry.Errors);
Assert.Equal("Too Long.", error.ErrorMessage);
@ -730,8 +735,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.Customer.Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
Assert.Empty(entry.Errors);
}
@ -768,11 +773,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.False(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.Customer.Name").Value;
Assert.Equal("billybob", entry.Value.AttemptedValue);
Assert.Equal("billybob", entry.Value.RawValue);
Assert.Equal("billybob", entry.AttemptedValue);
Assert.Equal("billybob", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "parameter.Customer").Value;
Assert.Null(entry.Value);
Assert.Null(entry.RawValue);
Assert.Null(entry.AttemptedValue);
Assert.Equal(ModelValidationState.Invalid, entry.ValidationState);
var error = Assert.Single(entry.Errors);
Assert.Equal("Invalid Person.", error.ErrorMessage);
@ -838,8 +844,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.Products[0].Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
Assert.Empty(entry.Errors);
}
@ -876,11 +882,12 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.False(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter.Products[0].Name").Value;
Assert.Equal("billybob", entry.Value.AttemptedValue);
Assert.Equal("billybob", entry.Value.RawValue);
Assert.Equal("billybob", entry.AttemptedValue);
Assert.Equal("billybob", entry.RawValue);
entry = Assert.Single(modelState, e => e.Key == "parameter.Products").Value;
Assert.Null(entry.Value);
Assert.Null(entry.RawValue);
Assert.Null(entry.AttemptedValue);
Assert.Equal(ModelValidationState.Invalid, entry.ValidationState);
var error = Assert.Single(entry.Errors);
@ -927,8 +934,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter[0].Name").Value;
Assert.Equal("bill", entry.Value.AttemptedValue);
Assert.Equal("bill", entry.Value.RawValue);
Assert.Equal("bill", entry.AttemptedValue);
Assert.Equal("bill", entry.RawValue);
Assert.Empty(entry.Errors);
}
@ -965,8 +972,8 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.False(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "parameter[0].Name").Value;
Assert.Equal("billybob", entry.Value.AttemptedValue);
Assert.Equal("billybob", entry.Value.RawValue);
Assert.Equal("billybob", entry.AttemptedValue);
Assert.Equal("billybob", entry.RawValue);
var error = Assert.Single(entry.Errors);
Assert.Equal("Too Long.", error.ErrorMessage);
@ -1070,23 +1077,23 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
Assert.True(modelState.IsValid);
var entry = Assert.Single(modelState, e => e.Key == "HomeAddress.Country.Name").Value;
Assert.Equal("US", entry.Value.AttemptedValue);
Assert.Equal("US", entry.Value.RawValue);
Assert.Equal("US", entry.AttemptedValue);
Assert.Equal("US", entry.RawValue);
Assert.Equal(ModelValidationState.Skipped, entry.ValidationState);
entry = Assert.Single(modelState, e => e.Key == "ShippingAddresses[0].Zip").Value;
Assert.Equal("45", entry.Value.AttemptedValue);
Assert.Equal("45", entry.Value.RawValue);
Assert.Equal("45", entry.AttemptedValue);
Assert.Equal("45", entry.RawValue);
Assert.Equal(ModelValidationState.Skipped, entry.ValidationState);
entry = Assert.Single(modelState, e => e.Key == "HomeAddress.Zip").Value;
Assert.Equal("46", entry.Value.AttemptedValue);
Assert.Equal("46", entry.Value.RawValue);
Assert.Equal("46", entry.AttemptedValue);
Assert.Equal("46", entry.RawValue);
Assert.Equal(ModelValidationState.Skipped, entry.ValidationState);
entry = Assert.Single(modelState, e => e.Key == "OfficeAddress").Value;
Assert.Null(entry.Value.AttemptedValue);
var address = Assert.IsType<Address>(entry.Value.RawValue);
Assert.Null(entry.AttemptedValue);
var address = Assert.IsType<Address>(entry.RawValue);
Assert.Equal(47, address.Zip);
// Address itself is not excluded from validation.

View File

@ -39,13 +39,12 @@ namespace Microsoft.AspNet.Mvc
// Assert
var i = 0;
Assert.Equal(12, options.ModelBinders.Count);
Assert.Equal(11, options.ModelBinders.Count);
Assert.IsType(typeof(BinderTypeBasedModelBinder), options.ModelBinders[i++]);
Assert.IsType(typeof(ServicesModelBinder), options.ModelBinders[i++]);
Assert.IsType(typeof(BodyModelBinder), options.ModelBinders[i++]);
Assert.IsType(typeof(HeaderModelBinder), options.ModelBinders[i++]);
Assert.IsType(typeof(TypeConverterModelBinder), options.ModelBinders[i++]);
Assert.IsType(typeof(TypeMatchModelBinder), options.ModelBinders[i++]);
Assert.IsType(typeof(SimpleTypeModelBinder), options.ModelBinders[i++]);
Assert.IsType(typeof(CancellationTokenModelBinder), options.ModelBinders[i++]);
Assert.IsType(typeof(ByteArrayModelBinder), options.ModelBinders[i++]);
Assert.IsType(typeof(FormFileModelBinder), options.ModelBinders[i++]);

View File

@ -216,17 +216,13 @@ namespace Microsoft.AspNet.Mvc.Rendering
}
// rawValue, allowMultiple -> expected current values
public static TheoryData<object, bool, IReadOnlyCollection<string>> GetCurrentValues_StringAndCollectionData
public static TheoryData<string[], bool, IReadOnlyCollection<string>> GetCurrentValues_CollectionData
{
get
{
return new TheoryData<object, bool, IReadOnlyCollection<string>>
return new TheoryData<string[], bool, IReadOnlyCollection<string>>
{
// ModelStateDictionary converts single values to arrays and visa-versa.
{ string.Empty, false, new [] { string.Empty } },
{ string.Empty, true, new [] { string.Empty } },
{ "some string", false, new [] { "some string" } },
{ "some string", true, new [] { "some string" } },
// ModelStateDictionary converts arrays to single values if needed.
{ new [] { "some string" }, false, new [] { "some string" } },
{ new [] { "some string" }, true, new [] { "some string" } },
{ new [] { "some string", "some other string" }, false, new [] { "some string" } },
@ -261,9 +257,9 @@ namespace Microsoft.AspNet.Mvc.Rendering
}
[Theory]
[MemberData(nameof(GetCurrentValues_StringAndCollectionData))]
[MemberData(nameof(GetCurrentValues_CollectionData))]
public void GetCurrentValues_WithModelStateEntryAndViewData_ReturnsModelStateEntry(
object rawValue,
string[] rawValue,
bool allowMultiple,
IReadOnlyCollection<string> expected)
{
@ -274,10 +270,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
var viewContext = GetViewContext<Model>(model, metadataProvider);
viewContext.ViewData[nameof(Model.Name)] = "ignored ViewData value";
var valueProviderResult = new ValueProviderResult(rawValue);
viewContext.ModelState.SetModelValue(nameof(Model.Name), valueProviderResult);
viewContext.ModelState.SetModelValue(nameof(Model.Name), rawValue, attemptedValue: null);
// Act
var result = htmlGenerator.GetCurrentValues(
@ -292,9 +285,9 @@ namespace Microsoft.AspNet.Mvc.Rendering
}
[Theory]
[MemberData(nameof(GetCurrentValues_StringAndCollectionData))]
[MemberData(nameof(GetCurrentValues_CollectionData))]
public void GetCurrentValues_WithModelStateEntryModelExplorerAndViewData_ReturnsModelStateEntry(
object rawValue,
string[] rawValue,
bool allowMultiple,
IReadOnlyCollection<string> expected)
{
@ -305,12 +298,10 @@ namespace Microsoft.AspNet.Mvc.Rendering
var viewContext = GetViewContext<Model>(model, metadataProvider);
viewContext.ViewData[nameof(Model.Name)] = "ignored ViewData value";
viewContext.ModelState.SetModelValue(nameof(Model.Name), rawValue, attemptedValue: null);
var modelExplorer = metadataProvider.GetModelExplorerForType(typeof(string), "ignored model value");
var valueProviderResult = new ValueProviderResult(rawValue);
viewContext.ModelState.SetModelValue(nameof(Model.Name), valueProviderResult);
// Act
var result = htmlGenerator.GetCurrentValues(
viewContext,
@ -324,11 +315,11 @@ namespace Microsoft.AspNet.Mvc.Rendering
}
// rawValue -> expected current values
public static TheoryData<string, string[]> GetCurrentValues_StringData
public static TheoryData<string[], string[]> GetCurrentValues_StringData
{
get
{
return new TheoryData<string, string[]>
return new TheoryData<string[], string[]>
{
// 1. If given a ModelExplorer, GetCurrentValues does not use ViewData even if expression result is
// null.
@ -336,8 +327,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
// if entry is null.
// 3. Otherwise, GetCurrentValue does not fall back anywhere else even if ViewData.Model is null.
{ null, null },
{ string.Empty, new [] { string.Empty } },
{ "some string", new [] { "some string" } },
{ new string[] { string.Empty }, new [] { string.Empty } },
{ new string[] { "some string" }, new [] { "some string" } },
};
}
}
@ -345,7 +336,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
[Theory]
[MemberData(nameof(GetCurrentValues_StringData))]
public void GetCurrentValues_WithModelExplorerAndViewData_ReturnsExpressionResult(
string rawValue,
string[] rawValue,
IReadOnlyCollection<string> expected)
{
// Arrange
@ -355,12 +346,10 @@ namespace Microsoft.AspNet.Mvc.Rendering
var viewContext = GetViewContext<Model>(model, metadataProvider);
viewContext.ViewData[nameof(Model.Name)] = "ignored ViewData value";
viewContext.ModelState.SetModelValue(nameof(Model.Name), rawValue, attemptedValue: null);
var modelExplorer = metadataProvider.GetModelExplorerForType(typeof(string), rawValue);
var valueProviderResult = new ValueProviderResult(rawValue: null);
viewContext.ModelState.SetModelValue(nameof(Model.Name), valueProviderResult);
// Act
var result = htmlGenerator.GetCurrentValues(
viewContext,
@ -375,7 +364,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
[Theory]
[MemberData(nameof(GetCurrentValues_StringData))]
public void GetCurrentValues_WithViewData_ReturnsViewDataEntry(
object rawValue,
string[] rawValue,
IReadOnlyCollection<string> expected)
{
// Arrange
@ -385,9 +374,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
var viewContext = GetViewContext<Model>(model, metadataProvider);
viewContext.ViewData[nameof(Model.Name)] = rawValue;
var valueProviderResult = new ValueProviderResult(rawValue: null);
viewContext.ModelState.SetModelValue(nameof(Model.Name), valueProviderResult);
viewContext.ModelState.SetModelValue(nameof(Model.Name), rawValue, attemptedValue: null);
// Act
var result = htmlGenerator.GetCurrentValues(
@ -402,17 +389,15 @@ namespace Microsoft.AspNet.Mvc.Rendering
[Theory]
[MemberData(nameof(GetCurrentValues_StringData))]
public void GetCurrentValues_WithModel_ReturnsModel(string rawValue, IReadOnlyCollection<string> expected)
public void GetCurrentValues_WithModel_ReturnsModel(string[] rawValue, IReadOnlyCollection<string> expected)
{
// Arrange
var metadataProvider = new TestModelMetadataProvider();
var htmlGenerator = GetGenerator(metadataProvider);
var model = new Model { Name = rawValue };
var model = new Model { Name = rawValue?[0] };
var viewContext = GetViewContext<Model>(model, metadataProvider);
var valueProviderResult = new ValueProviderResult(rawValue: null);
viewContext.ModelState.SetModelValue(nameof(Model.Name), valueProviderResult);
viewContext.ModelState.SetModelValue(nameof(Model.Name), rawValue, attemptedValue: null);
// Act
var result = htmlGenerator.GetCurrentValues(
@ -467,13 +452,11 @@ namespace Microsoft.AspNet.Mvc.Rendering
var viewContext = GetViewContext<Model>(model, metadataProvider);
viewContext.ViewData[nameof(Model.Collection)] = new[] { "ignored ViewData value" };
viewContext.ModelState.SetModelValue(nameof(Model.Collection), rawValue, attemptedValue: null);
var modelExplorer =
metadataProvider.GetModelExplorerForType(typeof(List<string>), new List<string>(rawValue));
var valueProviderResult = new ValueProviderResult(rawValue: null);
viewContext.ModelState.SetModelValue(nameof(Model.Collection), valueProviderResult);
// Act
var result = htmlGenerator.GetCurrentValues(
viewContext,
@ -488,7 +471,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
[Theory]
[MemberData(nameof(GetCurrentValues_StringCollectionData))]
public void GetCurrentValues_CollectionWithViewData_ReturnsViewDataEntry(
object[] rawValue,
string[] rawValue,
IReadOnlyCollection<string> expected)
{
// Arrange
@ -498,9 +481,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
var viewContext = GetViewContext<Model>(model, metadataProvider);
viewContext.ViewData[nameof(Model.Collection)] = rawValue;
var valueProviderResult = new ValueProviderResult(rawValue: null);
viewContext.ModelState.SetModelValue(nameof(Model.Collection), valueProviderResult);
viewContext.ModelState.SetModelValue(nameof(Model.Collection), rawValue, attemptedValue: null);
// Act
var result = htmlGenerator.GetCurrentValues(
@ -526,9 +507,10 @@ namespace Microsoft.AspNet.Mvc.Rendering
model.Collection.AddRange(rawValue);
var viewContext = GetViewContext<Model>(model, metadataProvider);
var valueProviderResult = new ValueProviderResult(rawValue: null);
viewContext.ModelState.SetModelValue(nameof(Model.Collection), valueProviderResult);
viewContext.ModelState.SetModelValue(
nameof(Model.Collection),
rawValue,
attemptedValue: null);
// Act
var result = htmlGenerator.GetCurrentValues(
@ -637,9 +619,10 @@ namespace Microsoft.AspNet.Mvc.Rendering
var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
var htmlGenerator = GetGenerator(metadataProvider);
var viewContext = GetViewContext<Model>(model: null, metadataProvider: metadataProvider);
var valueProviderResult = new ValueProviderResult(rawValue);
viewContext.ModelState.SetModelValue(propertyName, valueProviderResult);
viewContext.ModelState.SetModelValue(
propertyName,
new string[] { rawValue.ToString() },
attemptedValue: null);
// Act
var result = htmlGenerator.GetCurrentValues(

View File

@ -134,9 +134,9 @@ namespace Microsoft.AspNet.Mvc.Rendering
@"<input data-val=""HtmlEncode[[true]]"" data-val-required=""HtmlEncode[[The Boolean field is required.]]"" " +
@"id=""HtmlEncode[[Property1]]"" name=""HtmlEncode[[Property1]]"" type=""HtmlEncode[[checkbox]]"" value=""HtmlEncode[[true]]"" />" +
@"<input name=""HtmlEncode[[Property1]]"" type=""HtmlEncode[[hidden]]"" value=""HtmlEncode[[false]]"" />");
var valueProviderResult = new ValueProviderResult("false", "false", CultureInfo.InvariantCulture);
var helper = DefaultTemplatesUtilities.GetHtmlHelper(GetTestModelViewData());
helper.ViewData.ModelState.SetModelValue("Property1", valueProviderResult);
helper.ViewData.ModelState.SetModelValue("Property1", new string[] { "false" }, "false");
// Act
var html = helper.CheckBox("Property1", isChecked: null, htmlAttributes: null);
@ -438,8 +438,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
@"<input name=""HtmlEncode[[Property1]]"" type=""HtmlEncode[[hidden]]"" value=""HtmlEncode[[false]]"" />");
var viewData = GetTestModelViewData();
var helper = DefaultTemplatesUtilities.GetHtmlHelper(viewData);
var valueProviderResult = new ValueProviderResult("false", "false", CultureInfo.InvariantCulture);
viewData.ModelState.SetModelValue("Property1", valueProviderResult);
viewData.ModelState.SetModelValue("Property1", new string[] { "false" }, "false");
// Act
var html = helper.CheckBoxFor(m => m.Property1, htmlAttributes: null);
@ -533,9 +532,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
var viewData = GetTestModelViewData();
var helper = DefaultTemplatesUtilities.GetHtmlHelper(viewData);
var valueProviderResult =
new ValueProviderResult(attemptedValue, attemptedValue, CultureInfo.InvariantCulture);
viewData.ModelState.SetModelValue("Property1", valueProviderResult);
viewData.ModelState.SetModelValue("Property1", new string[] { attemptedValue }, attemptedValue);
// Act
var html = helper.CheckBoxFor(m => m.Property1, htmlAttributes: null);

View File

@ -261,10 +261,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
viewData.TemplateInfo.HtmlFieldPrefix = "FieldPrefix";
var modelState = new ModelState();
modelState.Value = new ValueProviderResult(
rawValue: new string[] { "Attempted name value" },
attemptedValue: "Attempted name value",
culture: CultureInfo.InvariantCulture);
modelState.RawValue = new string[] { "Attempted name value" };
modelState.AttemptedValue = "Attempted name value";
viewData.ModelState["FieldPrefix.Name"] = modelState;
// Act
@ -288,10 +286,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
viewData.TemplateInfo.HtmlFieldPrefix = "FieldPrefix";
var modelState = new ModelState();
modelState.Value = new ValueProviderResult(
rawValue: new string[] { "Attempted name value" },
attemptedValue: "Attempted name value",
culture: CultureInfo.InvariantCulture);
modelState.RawValue = new string[] { "Attempted name value" };
modelState.AttemptedValue = "Attempted name value";
viewData.ModelState["FieldPrefix.Name"] = modelState;
// Act

View File

@ -874,7 +874,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
{
return new ModelState
{
Value = new ValueProviderResult(value, value, CultureInfo.InvariantCulture)
RawValue = new string[] { value },
AttemptedValue = value,
};
}

View File

@ -371,7 +371,8 @@ namespace Microsoft.AspNet.Mvc.Rendering
{
return new ModelState
{
Value = new ValueProviderResult(value, value, CultureInfo.InvariantCulture)
RawValue = new string[] { value },
AttemptedValue = value,
};
}

View File

@ -410,18 +410,18 @@ namespace Microsoft.AspNet.Mvc.Rendering
// Arrange
var expectedHtml = GetExpectedSelectElement(SelectSources.ModelStateEntry, allowMultiple: false);
var entryResult = new ValueProviderResult(
SelectSources.ModelStateEntry,
SelectSources.ModelStateEntry.ToString(),
culture: null);
var entryResultWithPrefix = new ValueProviderResult(
SelectSources.ModelStateEntryWithPrefix,
SelectSources.ModelStateEntryWithPrefix.ToString(),
culture: null);
var modelState = new ModelStateDictionary
{
["Property1"] = new ModelState { Value = entryResult },
["Prefix.Property1"] = new ModelState { Value = entryResultWithPrefix },
["Property1"] = new ModelState
{
RawValue = new string[] { SelectSources.ModelStateEntry.ToString() },
AttemptedValue = SelectSources.ModelStateEntry.ToString()
},
["Prefix.Property1"] = new ModelState
{
RawValue = new string[] { SelectSources.ModelStateEntryWithPrefix.ToString() },
AttemptedValue = SelectSources.ModelStateEntryWithPrefix.ToString()
},
};
var provider = TestModelMetadataProvider.CreateDefaultProvider();
@ -451,18 +451,18 @@ namespace Microsoft.AspNet.Mvc.Rendering
SelectSources.ModelStateEntryWithPrefix,
allowMultiple: false);
var entryResult = new ValueProviderResult(
SelectSources.ModelStateEntry,
SelectSources.ModelStateEntry.ToString(),
culture: null);
var entryResultWithPrefix = new ValueProviderResult(
SelectSources.ModelStateEntryWithPrefix,
SelectSources.ModelStateEntryWithPrefix.ToString(),
culture: null);
var modelState = new ModelStateDictionary
{
["Property1"] = new ModelState { Value = entryResult },
["Prefix.Property1"] = new ModelState { Value = entryResultWithPrefix },
["Property1"] = new ModelState
{
RawValue = new string[] { SelectSources.ModelStateEntry.ToString() },
AttemptedValue = SelectSources.ModelStateEntry.ToString()
},
["Prefix.Property1"] = new ModelState
{
RawValue = new string[] { SelectSources.ModelStateEntryWithPrefix.ToString() },
AttemptedValue = SelectSources.ModelStateEntryWithPrefix.ToString()
},
};
var provider = TestModelMetadataProvider.CreateDefaultProvider();
@ -821,18 +821,18 @@ namespace Microsoft.AspNet.Mvc.Rendering
// Arrange
var expectedHtml = GetExpectedSelectElement(SelectSources.ModelStateEntry, allowMultiple: true);
var entryResult = new ValueProviderResult(
SelectSources.ModelStateEntry,
SelectSources.ModelStateEntry.ToString(),
culture: null);
var entryResultWithPrefix = new ValueProviderResult(
SelectSources.ModelStateEntryWithPrefix,
SelectSources.ModelStateEntryWithPrefix.ToString(),
culture: null);
var modelState = new ModelStateDictionary
{
["Property1"] = new ModelState { Value = entryResult },
["Prefix.Property1"] = new ModelState { Value = entryResultWithPrefix },
["Property1"] = new ModelState
{
RawValue = new string[] { SelectSources.ModelStateEntry.ToString() },
AttemptedValue = SelectSources.ModelStateEntry.ToString()
},
["Prefix.Property1"] = new ModelState
{
RawValue = new string[] { SelectSources.ModelStateEntryWithPrefix.ToString() },
AttemptedValue = SelectSources.ModelStateEntryWithPrefix.ToString()
},
};
var provider = TestModelMetadataProvider.CreateDefaultProvider();
@ -862,18 +862,18 @@ namespace Microsoft.AspNet.Mvc.Rendering
SelectSources.ModelStateEntryWithPrefix,
allowMultiple: true);
var entryResult = new ValueProviderResult(
SelectSources.ModelStateEntry,
SelectSources.ModelStateEntry.ToString(),
culture: null);
var entryResultWithPrefix = new ValueProviderResult(
SelectSources.ModelStateEntryWithPrefix,
SelectSources.ModelStateEntryWithPrefix.ToString(),
culture: null);
var modelState = new ModelStateDictionary
{
["Property1"] = new ModelState { Value = entryResult },
["Prefix.Property1"] = new ModelState { Value = entryResultWithPrefix },
["Property1"] = new ModelState
{
RawValue = new string[] { SelectSources.ModelStateEntry.ToString() },
AttemptedValue = SelectSources.ModelStateEntry.ToString()
},
["Prefix.Property1"] = new ModelState
{
RawValue = new string[] { SelectSources.ModelStateEntryWithPrefix.ToString() },
AttemptedValue = SelectSources.ModelStateEntryWithPrefix.ToString()
},
};
var provider = TestModelMetadataProvider.CreateDefaultProvider();

View File

@ -164,17 +164,13 @@ namespace Microsoft.AspNet.Mvc.Core
viewData.TemplateInfo.HtmlFieldPrefix = "FieldPrefix";
var modelState = new ModelState();
modelState.Value = new ValueProviderResult(
rawValue: new string[] { "StringPropertyRawValue" },
attemptedValue: "StringPropertyAttemptedValue",
culture: CultureInfo.InvariantCulture);
modelState.AttemptedValue = "StringPropertyAttemptedValue";
modelState.RawValue = new string[] { "StringPropertyRawValue" };
viewData.ModelState["FieldPrefix.StringProperty"] = modelState;
modelState = new ModelState();
modelState.Value = new ValueProviderResult(
rawValue: new string[] { "ModelRawValue" },
attemptedValue: "ModelAttemptedValue",
culture: CultureInfo.InvariantCulture);
modelState.AttemptedValue = "ModelAttemptedValue";
modelState.RawValue = new string[] { "ModelRawValue" };
viewData.ModelState["FieldPrefix"] = modelState;
// Act & Assert
@ -225,10 +221,8 @@ namespace Microsoft.AspNet.Mvc.Core
viewData["StringProperty"] = "ViewDataValue <\"\">";
var modelState = new ModelState();
modelState.Value = new ValueProviderResult(
rawValue: new string[] { "ObjectPropertyRawValue <\"\">" },
attemptedValue: "ObjectPropertyAttemptedValue <\"\">",
culture: CultureInfo.InvariantCulture);
modelState.AttemptedValue = "ObjectPropertyAttemptedValue <\"\">";
modelState.RawValue = new string[] { "ObjectPropertyRawValue <\"\">" };
viewData.ModelState["ObjectProperty"] = modelState;
// Act & Assert

View File

@ -99,7 +99,7 @@ namespace ModelBindingWebSite.Controllers
bindingContext.ModelName + "." + "productId";
var value = await bindingContext.ValueProvider.GetValueAsync(key);
model.ProductId = (int)value.ConvertTo(typeof(int));
model.ProductId = value.ConvertTo<int>();
var validationNode =
new ModelValidationNode(bindingContext.ModelName, bindingContext.ModelMetadata, value);

View File

@ -218,7 +218,7 @@ namespace ModelBindingWebSite.Controllers
public Task<ValueProviderResult> GetValueAsync(string key)
{
return Task.FromResult<ValueProviderResult>(null);
return Task.FromResult<ValueProviderResult>(ValueProviderResult.None);
}
}
}

View File

@ -31,7 +31,7 @@ namespace ValueProvidersWebSite
public Task<ValueProviderResult> GetValueAsync(string key)
{
var value = "custom-value-provider-value";
var result = new ValueProviderResult(value, value, CultureInfo.CurrentCulture);
var result = new ValueProviderResult(value, CultureInfo.CurrentCulture);
return Task.FromResult(result);
}
}