Use `ModelMetadata.GetDisplayName()` in error message replacing `FormatException` and `OverflowException`
- #3227 - much of change is to tests, creating and passing `ModelMetadata` - updated `InputFormatterContext` to make `ModelMetadata` available to `JsonInputFormatter` - walk `ModelMetadata` tree to get information about property with an issue - add missing `null` checks in `ModelStateDictionaryExtensions`
This commit is contained in:
parent
9b9d72f3f7
commit
40b7636b72
|
|
@ -29,7 +29,7 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
HttpContext httpContext,
|
||||
string modelName,
|
||||
ModelStateDictionary modelState,
|
||||
Type modelType)
|
||||
ModelMetadata metadata)
|
||||
{
|
||||
if (httpContext == null)
|
||||
{
|
||||
|
|
@ -46,15 +46,16 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
throw new ArgumentNullException(nameof(modelState));
|
||||
}
|
||||
|
||||
if (modelType == null)
|
||||
if (metadata == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(modelType));
|
||||
throw new ArgumentNullException(nameof(metadata));
|
||||
}
|
||||
|
||||
HttpContext = httpContext;
|
||||
ModelName = modelName;
|
||||
ModelState = modelState;
|
||||
ModelType = modelType;
|
||||
Metadata = metadata;
|
||||
ModelType = metadata.ModelType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -73,7 +74,12 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
public ModelStateDictionary ModelState { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the expected <see cref="Type"/> of the model represented by the request body.
|
||||
/// Gets the requested <see cref="ModelMetadata"/> of the request body deserialization.
|
||||
/// </summary>
|
||||
public ModelMetadata Metadata { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the requested <see cref="Type"/> of the request body deserialization.
|
||||
/// </summary>
|
||||
public Type ModelType { get; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
/// <remarks>
|
||||
/// <para>
|
||||
/// <see cref="ModelStateDictionary"/> tracks the number of model errors added by calls to
|
||||
/// <see cref="AddModelError(string, Exception)"/> or <see cref="TryAddModelError(string, Exception)"/>.
|
||||
/// <see cref="AddModelError(string, Exception, ModelMetadata)"/> or
|
||||
/// <see cref="TryAddModelError(string, Exception, ModelMetadata)"/>.
|
||||
/// Once the value of <code>MaxAllowedErrors - 1</code> is reached, if another attempt is made to add an error,
|
||||
/// the error message will be ignored and a <see cref="TooManyModelErrorsException"/> will be added.
|
||||
/// </para>
|
||||
|
|
@ -202,7 +203,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
/// </summary>
|
||||
/// <param name="key">The key of the <see cref="ModelStateEntry"/> to add errors to.</param>
|
||||
/// <param name="exception">The <see cref="Exception"/> to add.</param>
|
||||
public void AddModelError(string key, Exception exception)
|
||||
public void AddModelError(string key, Exception exception, ModelMetadata metadata)
|
||||
{
|
||||
if (key == null)
|
||||
{
|
||||
|
|
@ -214,7 +215,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
throw new ArgumentNullException(nameof(exception));
|
||||
}
|
||||
|
||||
TryAddModelError(key, exception);
|
||||
if (metadata == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(metadata));
|
||||
}
|
||||
|
||||
TryAddModelError(key, exception, metadata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -228,7 +234,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
/// <c>True</c> if the given error was added, <c>false</c> if the error was ignored.
|
||||
/// See <see cref="MaxAllowedErrors"/>.
|
||||
/// </returns>
|
||||
public bool TryAddModelError(string key, Exception exception)
|
||||
public bool TryAddModelError(string key, Exception exception, ModelMetadata metadata)
|
||||
{
|
||||
if (key == null)
|
||||
{
|
||||
|
|
@ -240,6 +246,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
throw new ArgumentNullException(nameof(exception));
|
||||
}
|
||||
|
||||
if (metadata == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(metadata));
|
||||
}
|
||||
|
||||
if (ErrorCount >= MaxAllowedErrors - 1)
|
||||
{
|
||||
EnsureMaxErrorsReachedRecorded();
|
||||
|
|
@ -252,16 +263,17 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
ModelStateEntry entry;
|
||||
TryGetValue(key, out entry);
|
||||
|
||||
var name = metadata.GetDisplayName();
|
||||
string errorMessage;
|
||||
if (entry == null)
|
||||
{
|
||||
errorMessage = Resources.FormatModelError_InvalidValue_GenericMessage(key);
|
||||
errorMessage = Resources.FormatModelError_InvalidValue_GenericMessage(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
errorMessage = Resources.FormatModelError_InvalidValue_MessageWithModelValue(
|
||||
entry.AttemptedValue,
|
||||
key);
|
||||
name);
|
||||
}
|
||||
|
||||
return TryAddModelError(key, errorMessage);
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
httpContext,
|
||||
modelBindingKey,
|
||||
bindingContext.ModelState,
|
||||
bindingContext.ModelType);
|
||||
bindingContext.ModelMetadata);
|
||||
var formatters = bindingContext.OperationBindingContext.InputFormatters;
|
||||
var formatter = formatters.FirstOrDefault(f => f.CanRead(formatterContext));
|
||||
|
||||
|
|
@ -95,7 +95,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
bindingContext.ModelState.AddModelError(modelBindingKey, ex);
|
||||
bindingContext.ModelState.AddModelError(modelBindingKey, ex, bindingContext.ModelMetadata);
|
||||
|
||||
// This model binder is the only handler for the Body binding source and it cannot run twice. Always
|
||||
// tell the model binding system to skip other model binders and never to fall back i.e. indicate a
|
||||
|
|
|
|||
|
|
@ -50,9 +50,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
var model = Convert.FromBase64String(value);
|
||||
return ModelBindingResult.SuccessAsync(bindingContext.ModelName, model);
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch (Exception exception)
|
||||
{
|
||||
bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, ex);
|
||||
bindingContext.ModelState.TryAddModelError(
|
||||
bindingContext.ModelName,
|
||||
exception,
|
||||
bindingContext.ModelMetadata);
|
||||
}
|
||||
|
||||
// Matched the type (byte[]) only this binder supports. As in missing data cases, always tell the model
|
||||
|
|
|
|||
|
|
@ -592,7 +592,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
var validationState = modelState.GetFieldValidationState(modelStateKey);
|
||||
if (validationState == ModelValidationState.Unvalidated)
|
||||
{
|
||||
modelState.AddModelError(modelStateKey, exception);
|
||||
modelState.AddModelError(modelStateKey, exception, bindingContext.ModelMetadata);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,9 +60,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
return ModelBindingResult.SuccessAsync(bindingContext.ModelName, model);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch (Exception exception)
|
||||
{
|
||||
bindingContext.ModelState.TryAddModelError(bindingContext.ModelName, ex);
|
||||
bindingContext.ModelState.TryAddModelError(
|
||||
bindingContext.ModelName,
|
||||
exception,
|
||||
bindingContext.ModelMetadata);
|
||||
|
||||
// Were able to find a converter for the type but conversion failed.
|
||||
// Tell the model binding system to skip other model binders.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ using System.IO;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc.Internal;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Formatters
|
||||
|
|
@ -101,7 +101,8 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
}
|
||||
}
|
||||
|
||||
context.ModelState.TryAddModelError(key, eventArgs.ErrorContext.Error);
|
||||
var metadata = GetPathMetadata(context.Metadata, eventArgs.ErrorContext.Path);
|
||||
context.ModelState.TryAddModelError(key, eventArgs.ErrorContext.Error, metadata);
|
||||
|
||||
// Error must always be marked as handled
|
||||
// Failure to do so can cause the exception to be rethrown at every recursive level and
|
||||
|
|
@ -171,5 +172,51 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
{
|
||||
return JsonSerializer.Create(SerializerSettings);
|
||||
}
|
||||
|
||||
private ModelMetadata GetPathMetadata(ModelMetadata metadata, string path)
|
||||
{
|
||||
var index = 0;
|
||||
while (index >= 0 && index < path.Length)
|
||||
{
|
||||
if (path[index] == '[')
|
||||
{
|
||||
// At start of "[0]".
|
||||
if (metadata.ElementMetadata == null)
|
||||
{
|
||||
// Odd case but don't throw just because ErrorContext had an odd-looking path.
|
||||
break;
|
||||
}
|
||||
|
||||
metadata = metadata.ElementMetadata;
|
||||
index = path.IndexOf(']', index);
|
||||
}
|
||||
else if (path[index] == '.' || path[index] == ']')
|
||||
{
|
||||
// Skip '.' in "prefix.property" or "[0].property" or ']' in "[0]".
|
||||
index++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// At start of "property", "property." or "property[0]".
|
||||
var endIndex = path.IndexOfAny(new[] { '.', '[' }, index);
|
||||
if (endIndex == -1)
|
||||
{
|
||||
endIndex = path.Length;
|
||||
}
|
||||
|
||||
var propertyName = path.Substring(index, endIndex - index);
|
||||
if (metadata.Properties[propertyName] == null)
|
||||
{
|
||||
// Odd case but don't throw just because ErrorContext had an odd-looking path.
|
||||
break;
|
||||
}
|
||||
|
||||
metadata = metadata.Properties[propertyName];
|
||||
index = endIndex;
|
||||
}
|
||||
}
|
||||
|
||||
return metadata;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,21 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
Expression<Func<TModel, object>> expression,
|
||||
string errorMessage)
|
||||
{
|
||||
if (modelState == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(modelState));
|
||||
}
|
||||
|
||||
if (expression == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(expression));
|
||||
}
|
||||
|
||||
if (errorMessage == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(errorMessage));
|
||||
}
|
||||
|
||||
modelState.AddModelError(GetExpressionText(expression), errorMessage);
|
||||
}
|
||||
|
||||
|
|
@ -40,9 +55,25 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
public static void AddModelError<TModel>(
|
||||
this ModelStateDictionary modelState,
|
||||
Expression<Func<TModel, object>> expression,
|
||||
Exception exception)
|
||||
Exception exception,
|
||||
ModelMetadata metadata)
|
||||
{
|
||||
modelState.AddModelError(GetExpressionText(expression), exception);
|
||||
if (modelState == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(modelState));
|
||||
}
|
||||
|
||||
if (expression == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(expression));
|
||||
}
|
||||
|
||||
if (metadata == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(metadata));
|
||||
}
|
||||
|
||||
modelState.AddModelError(GetExpressionText(expression), exception, metadata);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -59,6 +90,16 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
this ModelStateDictionary modelState,
|
||||
Expression<Func<TModel, object>> expression)
|
||||
{
|
||||
if (modelState == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(modelState));
|
||||
}
|
||||
|
||||
if (expression == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(expression));
|
||||
}
|
||||
|
||||
return modelState.Remove(GetExpressionText(expression));
|
||||
}
|
||||
|
||||
|
|
@ -73,6 +114,16 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
this ModelStateDictionary modelState,
|
||||
Expression<Func<TModel, object>> expression)
|
||||
{
|
||||
if (modelState == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(modelState));
|
||||
}
|
||||
|
||||
if (expression == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(expression));
|
||||
}
|
||||
|
||||
string modelKey = GetExpressionText(expression);
|
||||
if (string.IsNullOrEmpty(modelKey))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -179,10 +179,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
// Arrange
|
||||
var dictionary = new ModelStateDictionary();
|
||||
dictionary.AddModelError("some key", "some error");
|
||||
var ex = new Exception();
|
||||
var exception = new Exception();
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForProperty(typeof(string), nameof(string.Length));
|
||||
|
||||
// Act
|
||||
dictionary.AddModelError("some key", ex);
|
||||
dictionary.AddModelError("some key", exception, metadata);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(2, dictionary.ErrorCount);
|
||||
|
|
@ -191,7 +193,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
|
||||
Assert.Equal(2, kvp.Value.Errors.Count);
|
||||
Assert.Equal("some error", kvp.Value.Errors[0].ErrorMessage);
|
||||
Assert.Same(ex, kvp.Value.Errors[1].Exception);
|
||||
Assert.Same(exception, kvp.Value.Errors[1].Exception);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -546,9 +548,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
{
|
||||
MaxAllowedErrors = 5
|
||||
};
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForProperty(typeof(string), nameof(string.Length));
|
||||
dictionary.AddModelError("key1", "error1");
|
||||
dictionary.AddModelError("key2", new Exception());
|
||||
dictionary.AddModelError("key3", new Exception());
|
||||
dictionary.AddModelError("key2", new Exception(), metadata);
|
||||
dictionary.AddModelError("key3", new Exception(), metadata);
|
||||
dictionary.AddModelError("key4", "error4");
|
||||
dictionary.AddModelError("key5", "error5");
|
||||
|
||||
|
|
@ -572,6 +576,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
{
|
||||
MaxAllowedErrors = 3
|
||||
};
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForProperty(typeof(string), nameof(string.Length));
|
||||
|
||||
// Act and Assert
|
||||
Assert.False(dictionary.HasReachedMaxErrors);
|
||||
|
|
@ -579,7 +585,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
Assert.True(result);
|
||||
|
||||
Assert.False(dictionary.HasReachedMaxErrors);
|
||||
result = dictionary.TryAddModelError("key2", new Exception());
|
||||
result = dictionary.TryAddModelError("key2", new Exception(), metadata);
|
||||
Assert.True(result);
|
||||
|
||||
Assert.False(dictionary.HasReachedMaxErrors); // Still room for TooManyModelErrorsException.
|
||||
|
|
@ -614,10 +620,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
{
|
||||
MaxAllowedErrors = 4
|
||||
};
|
||||
dictionary.AddModelError("key1", new Exception());
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForProperty(typeof(string), nameof(string.Length));
|
||||
dictionary.AddModelError("key1", new Exception(), metadata);
|
||||
dictionary.AddModelError("key2", "error2");
|
||||
dictionary.AddModelError("key3", "error3");
|
||||
dictionary.AddModelError("key3", new Exception());
|
||||
dictionary.AddModelError("key3", new Exception(), metadata);
|
||||
|
||||
// Act and Assert
|
||||
Assert.True(dictionary.HasReachedMaxErrors);
|
||||
|
|
@ -642,15 +650,17 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
{
|
||||
MaxAllowedErrors = 3
|
||||
};
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForProperty(typeof(string), nameof(string.Length));
|
||||
|
||||
// Act and Assert
|
||||
var result = dictionary.TryAddModelError("key1", "error1");
|
||||
Assert.True(result);
|
||||
|
||||
result = dictionary.TryAddModelError("key2", new Exception());
|
||||
result = dictionary.TryAddModelError("key2", new Exception(), metadata);
|
||||
Assert.True(result);
|
||||
|
||||
result = dictionary.TryAddModelError("key3", new Exception());
|
||||
result = dictionary.TryAddModelError("key3", new Exception(), metadata);
|
||||
Assert.False(result);
|
||||
|
||||
Assert.Equal(3, dictionary.Count);
|
||||
|
|
@ -668,10 +678,12 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
{
|
||||
MaxAllowedErrors = 3
|
||||
};
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForProperty(typeof(string), nameof(string.Length));
|
||||
|
||||
// Act
|
||||
dictionary.AddModelError("key1", "error1");
|
||||
dictionary.TryAddModelError("key3", new Exception());
|
||||
dictionary.TryAddModelError("key3", new Exception(), metadata);
|
||||
|
||||
var copy = new ModelStateDictionary(dictionary);
|
||||
copy.AddModelError("key2", "error2");
|
||||
|
|
@ -711,11 +723,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
public void ModelStateDictionary_ReturnGenericErrorMessage_WhenModelStateNotSet()
|
||||
{
|
||||
// Arrange
|
||||
var expected = "The supplied value is invalid for key.";
|
||||
var expected = "The supplied value is invalid for Length.";
|
||||
var dictionary = new ModelStateDictionary();
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForProperty(typeof(string), nameof(string.Length));
|
||||
|
||||
// Act
|
||||
dictionary.TryAddModelError("key", new FormatException());
|
||||
dictionary.TryAddModelError("key", new FormatException(), metadata);
|
||||
|
||||
// Assert
|
||||
var error = Assert.Single(dictionary["key"].Errors);
|
||||
|
|
@ -726,12 +740,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
public void ModelStateDictionary_ReturnSpecificErrorMessage_WhenModelStateSet()
|
||||
{
|
||||
// Arrange
|
||||
var expected = "The value 'some value' is not valid for key.";
|
||||
var expected = "The value 'some value' is not valid for Length.";
|
||||
var dictionary = new ModelStateDictionary();
|
||||
dictionary.SetModelValue("key", new string[] { "some value" }, "some value");
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForProperty(typeof(string), nameof(string.Length));
|
||||
|
||||
// Act
|
||||
dictionary.TryAddModelError("key", new FormatException());
|
||||
dictionary.TryAddModelError("key", new FormatException(), metadata);
|
||||
|
||||
// Assert
|
||||
var error = Assert.Single(dictionary["key"].Errors);
|
||||
|
|
@ -744,9 +760,11 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
// Arrange
|
||||
var dictionary = new ModelStateDictionary();
|
||||
dictionary.SetModelValue("key", new string[] { "some value" }, "some value");
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForProperty(typeof(string), nameof(string.Length));
|
||||
|
||||
// Act
|
||||
dictionary.TryAddModelError("key", new InvalidOperationException());
|
||||
dictionary.TryAddModelError("key", new InvalidOperationException(), metadata);
|
||||
|
||||
// Assert
|
||||
var error = Assert.Single(dictionary["key"].Errors);
|
||||
|
|
|
|||
|
|
@ -36,11 +36,14 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
var formatter = new CatchAllFormatter();
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.Request.ContentType = requestContentType;
|
||||
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(typeof(void));
|
||||
var context = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: new ModelStateDictionary(),
|
||||
modelType: typeof(void));
|
||||
metadata: metadata);
|
||||
|
||||
// Act
|
||||
var result = formatter.CanRead(context);
|
||||
|
|
@ -66,11 +69,14 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
var formatter = new MultipartFormatter();
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.Request.ContentType = requestContentType;
|
||||
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(typeof(void));
|
||||
var context = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: new ModelStateDictionary(),
|
||||
modelType: typeof(void));
|
||||
metadata: metadata);
|
||||
|
||||
// Act
|
||||
var result = formatter.CanRead(context);
|
||||
|
|
@ -93,11 +99,14 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
var formatter = new MultipartFormatter();
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.Request.ContentType = requestContentType;
|
||||
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(typeof(void));
|
||||
var context = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: new ModelStateDictionary(),
|
||||
modelType: typeof(void));
|
||||
metadata: metadata);
|
||||
|
||||
// Act
|
||||
var result = formatter.CanRead(context);
|
||||
|
|
@ -123,11 +132,14 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
var formatter = new MultipartMixedFormatter();
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.Request.ContentType = requestContentType;
|
||||
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(typeof(void));
|
||||
var context = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: new ModelStateDictionary(),
|
||||
modelType: typeof(void));
|
||||
metadata: metadata);
|
||||
|
||||
// Act
|
||||
var result = formatter.CanRead(context);
|
||||
|
|
@ -150,11 +162,14 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
var formatter = new MultipartMixedFormatter();
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.Request.ContentType = requestContentType;
|
||||
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(typeof(void));
|
||||
var context = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: new ModelStateDictionary(),
|
||||
modelType: typeof(void));
|
||||
metadata: metadata);
|
||||
|
||||
// Act
|
||||
var result = formatter.CanRead(context);
|
||||
|
|
@ -183,11 +198,14 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
var formatter = new MathMLFormatter();
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.Request.ContentType = requestContentType;
|
||||
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(typeof(void));
|
||||
var context = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: new ModelStateDictionary(),
|
||||
modelType: typeof(void));
|
||||
metadata: metadata);
|
||||
|
||||
// Act
|
||||
var result = formatter.CanRead(context);
|
||||
|
|
@ -209,11 +227,14 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
var formatter = new MathMLFormatter();
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.Request.ContentType = requestContentType;
|
||||
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(typeof(void));
|
||||
var context = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: new ModelStateDictionary(),
|
||||
modelType: typeof(void));
|
||||
metadata: metadata);
|
||||
|
||||
// Act
|
||||
var result = formatter.CanRead(context);
|
||||
|
|
@ -240,11 +261,14 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
var formatter = new XmlFormatter();
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.Request.ContentType = requestContentType;
|
||||
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(typeof(void));
|
||||
var context = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: new ModelStateDictionary(),
|
||||
modelType: typeof(void));
|
||||
metadata: metadata);
|
||||
|
||||
// Act
|
||||
var result = formatter.CanRead(context);
|
||||
|
|
@ -268,11 +292,14 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
var formatter = new XmlFormatter();
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.Request.ContentType = requestContentType;
|
||||
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(typeof(void));
|
||||
var context = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: new ModelStateDictionary(),
|
||||
modelType: typeof(void));
|
||||
metadata: metadata);
|
||||
|
||||
// Act
|
||||
var result = formatter.CanRead(context);
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
|||
public async Task BindModelAddsModelErrorsOnInvalidCharacters()
|
||||
{
|
||||
// Arrange
|
||||
var expected = "The value '\"Fys1\"' is not valid for foo.";
|
||||
var expected = "The value '\"Fys1\"' is not valid for Byte[].";
|
||||
|
||||
var valueProvider = new SimpleValueProvider()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Test
|
|||
public async Task BindModel_Error_FormatExceptionsTurnedIntoStringsInModelState()
|
||||
{
|
||||
// Arrange
|
||||
var message = "The value 'not an integer' is not valid for theModelName.";
|
||||
var message = "The value 'not an integer' is not valid for Int32.";
|
||||
var bindingContext = GetBindingContext(typeof(int));
|
||||
bindingContext.ValueProvider = new SimpleValueProvider
|
||||
{
|
||||
|
|
|
|||
|
|
@ -38,11 +38,13 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
var contentBytes = Encoding.UTF8.GetBytes("content");
|
||||
|
||||
var httpContext = GetHttpContext(contentBytes, contentType: requestContentType);
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(typeof(string));
|
||||
var formatterContext = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: new ModelStateDictionary(),
|
||||
modelType: typeof(string));
|
||||
metadata: metadata);
|
||||
|
||||
// Act
|
||||
var result = formatter.CanRead(formatterContext);
|
||||
|
|
@ -84,11 +86,13 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
var contentBytes = Encoding.UTF8.GetBytes(content);
|
||||
|
||||
var httpContext = GetHttpContext(contentBytes);
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(type);
|
||||
var context = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: new ModelStateDictionary(),
|
||||
modelType: type);
|
||||
metadata: metadata);
|
||||
|
||||
// Act
|
||||
var result = await formatter.ReadAsync(context);
|
||||
|
|
@ -107,11 +111,13 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
var contentBytes = Encoding.UTF8.GetBytes(content);
|
||||
|
||||
var httpContext = GetHttpContext(contentBytes);
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(typeof(User));
|
||||
var context = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: new ModelStateDictionary(),
|
||||
modelType: typeof(User));
|
||||
metadata: metadata);
|
||||
|
||||
// Act
|
||||
var result = await formatter.ReadAsync(context);
|
||||
|
|
@ -133,11 +139,13 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
|
||||
var modelState = new ModelStateDictionary();
|
||||
var httpContext = GetHttpContext(contentBytes);
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(typeof(User));
|
||||
var context = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: modelState,
|
||||
modelType: typeof(User));
|
||||
metadata: metadata);
|
||||
|
||||
// Act
|
||||
var result = await formatter.ReadAsync(context);
|
||||
|
|
@ -149,6 +157,61 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
modelState["Age"].Errors[0].Exception.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReadAsync_InvalidArray_AddsOverflowErrorsToModelState()
|
||||
{
|
||||
// Arrange
|
||||
var content = "[0, 23, 300]";
|
||||
var formatter = new JsonInputFormatter();
|
||||
var contentBytes = Encoding.UTF8.GetBytes(content);
|
||||
|
||||
var modelState = new ModelStateDictionary();
|
||||
var httpContext = GetHttpContext(contentBytes);
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(typeof(byte[]));
|
||||
var context = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: modelState,
|
||||
metadata: metadata);
|
||||
|
||||
// Act
|
||||
var result = await formatter.ReadAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.True(result.HasError);
|
||||
Assert.Equal("The supplied value is invalid for Byte.", modelState["[2]"].Errors[0].ErrorMessage);
|
||||
Assert.Null(modelState["[2]"].Errors[0].Exception);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReadAsync_InvalidComplexArray_AddsOverflowErrorsToModelState()
|
||||
{
|
||||
// Arrange
|
||||
var content = "[{name: 'Name One', Age: 30}, {name: 'Name Two', Small: 300}]";
|
||||
var formatter = new JsonInputFormatter();
|
||||
var contentBytes = Encoding.UTF8.GetBytes(content);
|
||||
|
||||
var modelState = new ModelStateDictionary();
|
||||
var httpContext = GetHttpContext(contentBytes);
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(typeof(User[]));
|
||||
var context = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: "names",
|
||||
modelState: modelState,
|
||||
metadata: metadata);
|
||||
|
||||
// Act
|
||||
var result = await formatter.ReadAsync(context);
|
||||
|
||||
// Assert
|
||||
Assert.True(result.HasError);
|
||||
Assert.Equal(
|
||||
"Error converting value 300 to type 'System.Byte'. Path '[1].Small', line 1, position 59.",
|
||||
modelState["names[1].Small"].Errors[0].Exception.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReadAsync_UsesTryAddModelValidationErrorsToModelState()
|
||||
{
|
||||
|
|
@ -159,11 +222,13 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
|
||||
var modelState = new ModelStateDictionary();
|
||||
var httpContext = GetHttpContext(contentBytes);
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(typeof(User));
|
||||
var context = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: modelState,
|
||||
modelType: typeof(User));
|
||||
metadata: metadata);
|
||||
|
||||
modelState.MaxAllowedErrors = 3;
|
||||
modelState.AddModelError("key1", "error1");
|
||||
|
|
@ -215,11 +280,13 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
|
||||
var modelState = new ModelStateDictionary();
|
||||
var httpContext = GetHttpContext(contentBytes, "application/json;charset=utf-8");
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(typeof(UserLogin));
|
||||
var inputFormatterContext = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: modelState,
|
||||
modelType: typeof(UserLogin));
|
||||
metadata: metadata);
|
||||
|
||||
// Act
|
||||
var result = await jsonFormatter.ReadAsync(inputFormatterContext);
|
||||
|
|
@ -248,11 +315,13 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
|
||||
var modelState = new ModelStateDictionary();
|
||||
var httpContext = GetHttpContext(contentBytes, "application/json;charset=utf-8");
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(typeof(UserLogin));
|
||||
var inputFormatterContext = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: modelState,
|
||||
modelType: typeof(UserLogin));
|
||||
metadata: metadata);
|
||||
|
||||
// Act
|
||||
var result = await jsonFormatter.ReadAsync(inputFormatterContext);
|
||||
|
|
@ -315,6 +384,8 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
public string Name { get; set; }
|
||||
|
||||
public decimal Age { get; set; }
|
||||
|
||||
public byte Small { get; set; }
|
||||
}
|
||||
|
||||
private sealed class UserLogin
|
||||
|
|
|
|||
|
|
@ -25,11 +25,13 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
|
||||
var modelState = new ModelStateDictionary();
|
||||
var httpContext = GetHttpContext(contentBytes);
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(typeof(JsonPatchDocument<Customer>));
|
||||
var context = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: modelState,
|
||||
modelType: typeof(JsonPatchDocument<Customer>));
|
||||
metadata: metadata);
|
||||
|
||||
// Act
|
||||
var result = await formatter.ReadAsync(context);
|
||||
|
|
@ -53,11 +55,13 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
|
||||
var modelState = new ModelStateDictionary();
|
||||
var httpContext = GetHttpContext(contentBytes);
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(typeof(JsonPatchDocument<Customer>));
|
||||
var context = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: modelState,
|
||||
modelType: typeof(JsonPatchDocument<Customer>));
|
||||
metadata: metadata);
|
||||
|
||||
// Act
|
||||
var result = await formatter.ReadAsync(context);
|
||||
|
|
@ -86,11 +90,13 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
|
||||
var modelState = new ModelStateDictionary();
|
||||
var httpContext = GetHttpContext(contentBytes, contentType: requestContentType);
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(typeof(JsonPatchDocument<Customer>));
|
||||
var formatterContext = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: modelState,
|
||||
modelType: typeof(JsonPatchDocument<Customer>));
|
||||
metadata: metadata);
|
||||
|
||||
// Act
|
||||
var result = formatter.CanRead(formatterContext);
|
||||
|
|
@ -111,11 +117,13 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
|
||||
var modelState = new ModelStateDictionary();
|
||||
var httpContext = GetHttpContext(contentBytes, contentType: "application/json-patch+json");
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(modelType);
|
||||
var formatterContext = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: modelState,
|
||||
modelType: modelType);
|
||||
metadata: metadata);
|
||||
|
||||
// Act
|
||||
var result = formatter.CanRead(formatterContext);
|
||||
|
|
@ -137,11 +145,13 @@ namespace Microsoft.AspNet.Mvc.Formatters
|
|||
|
||||
var modelState = new ModelStateDictionary();
|
||||
var httpContext = GetHttpContext(contentBytes, contentType: "application/json-patch+json");
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(typeof(Customer));
|
||||
var context = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: modelState,
|
||||
modelType: typeof(Customer));
|
||||
metadata: metadata);
|
||||
|
||||
// Act
|
||||
var result = await formatter.ReadAsync(context);
|
||||
|
|
|
|||
|
|
@ -73,11 +73,13 @@ namespace Microsoft.AspNet.Mvc.Formatters.Xml
|
|||
|
||||
var modelState = new ModelStateDictionary();
|
||||
var httpContext = GetHttpContext(contentBytes, contentType: requestContentType);
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(typeof(string));
|
||||
var formatterContext = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: modelState,
|
||||
modelType: typeof(string));
|
||||
metadata: metadata);
|
||||
|
||||
// Act
|
||||
var result = formatter.CanRead(formatterContext);
|
||||
|
|
@ -337,11 +339,13 @@ namespace Microsoft.AspNet.Mvc.Formatters.Xml
|
|||
var modelState = new ModelStateDictionary();
|
||||
var httpContext = GetHttpContext(inputBytes, contentType: "application/xml; charset=utf-16");
|
||||
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(typeof(TestLevelOne));
|
||||
var context = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: modelState,
|
||||
modelType: typeof(TestLevelOne));
|
||||
metadata: metadata);
|
||||
|
||||
// Act
|
||||
var ex = await Assert.ThrowsAsync(expectedException, () => formatter.ReadAsync(context));
|
||||
|
|
@ -401,11 +405,13 @@ namespace Microsoft.AspNet.Mvc.Formatters.Xml
|
|||
var modelState = new ModelStateDictionary();
|
||||
var httpContext = GetHttpContext(contentBytes, contentType: "application/xml; charset=utf-16");
|
||||
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(typeof(TestLevelOne));
|
||||
var context = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: modelState,
|
||||
modelType: typeof(TestLevelOne));
|
||||
metadata: metadata);
|
||||
|
||||
// Act
|
||||
var result = await formatter.ReadAsync(context);
|
||||
|
|
@ -544,11 +550,13 @@ namespace Microsoft.AspNet.Mvc.Formatters.Xml
|
|||
private InputFormatterContext GetInputFormatterContext(byte[] contentBytes, Type modelType)
|
||||
{
|
||||
var httpContext = GetHttpContext(contentBytes);
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(modelType);
|
||||
return new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: new ModelStateDictionary(),
|
||||
modelType: modelType);
|
||||
metadata: metadata);
|
||||
}
|
||||
|
||||
private static HttpContext GetHttpContext(
|
||||
|
|
|
|||
|
|
@ -59,11 +59,13 @@ namespace Microsoft.AspNet.Mvc.Formatters.Xml
|
|||
var modelState = new ModelStateDictionary();
|
||||
var httpContext = GetHttpContext(contentBytes, contentType: requestContentType);
|
||||
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(typeof(string));
|
||||
var formatterContext = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: modelState,
|
||||
modelType: typeof(string));
|
||||
metadata: metadata);
|
||||
|
||||
// Act
|
||||
var result = formatter.CanRead(formatterContext);
|
||||
|
|
@ -342,11 +344,13 @@ namespace Microsoft.AspNet.Mvc.Formatters.Xml
|
|||
var modelState = new ModelStateDictionary();
|
||||
var httpContext = GetHttpContext(inputBytes, contentType: "application/xml; charset=utf-16");
|
||||
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(typeof(TestLevelOne));
|
||||
var context = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: modelState,
|
||||
modelType: typeof(TestLevelOne));
|
||||
metadata: metadata);
|
||||
|
||||
// Act and Assert
|
||||
var ex = await Assert.ThrowsAsync(expectedException, () => formatter.ReadAsync(context));
|
||||
|
|
@ -403,11 +407,13 @@ namespace Microsoft.AspNet.Mvc.Formatters.Xml
|
|||
|
||||
var modelState = new ModelStateDictionary();
|
||||
var httpContext = GetHttpContext(contentBytes, contentType: "application/xml; charset=utf-16");
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(typeof(TestLevelOne));
|
||||
var context = new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: modelState,
|
||||
modelType: typeof(TestLevelOne));
|
||||
metadata: metadata);
|
||||
|
||||
// Act
|
||||
var result = await formatter.ReadAsync(context);
|
||||
|
|
@ -425,11 +431,13 @@ namespace Microsoft.AspNet.Mvc.Formatters.Xml
|
|||
private InputFormatterContext GetInputFormatterContext(byte[] contentBytes, Type modelType)
|
||||
{
|
||||
var httpContext = GetHttpContext(contentBytes);
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForType(modelType);
|
||||
return new InputFormatterContext(
|
||||
httpContext,
|
||||
modelName: string.Empty,
|
||||
modelState: new ModelStateDictionary(),
|
||||
modelType: modelType);
|
||||
metadata: metadata);
|
||||
}
|
||||
|
||||
private static HttpContext GetHttpContext(
|
||||
|
|
|
|||
|
|
@ -1443,7 +1443,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
var result = await response.Content.ReadAsStringAsync();
|
||||
Assert.Equal("The value 'random string' is not valid for birthdate.", result);
|
||||
Assert.Equal("The value 'random string' is not valid for DateTime.", result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
|
|
@ -244,7 +244,7 @@ namespace Microsoft.AspNet.Mvc.IntegrationTests
|
|||
|
||||
var error = Assert.Single(entry.Errors);
|
||||
Assert.Null(error.Exception);
|
||||
Assert.Equal("The value 'abcd' is not valid for Parameter1.", error.ErrorMessage);
|
||||
Assert.Equal("The value 'abcd' is not valid for Int32.", error.ErrorMessage);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
|
|||
|
|
@ -81,11 +81,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
public void AddModelError_ForSingleExpression_AddsExpectedException()
|
||||
{
|
||||
// Arrange
|
||||
var exception = new Exception();
|
||||
var dictionary = new ModelStateDictionary();
|
||||
var exception = new Exception();
|
||||
var provider = new TestModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForProperty(typeof(TestModel), nameof(TestModel.Text));
|
||||
|
||||
// Act
|
||||
dictionary.AddModelError<TestModel>(model => model.Text, exception);
|
||||
dictionary.AddModelError<TestModel>(model => model.Text, exception, metadata);
|
||||
|
||||
// Assert
|
||||
var modelState = Assert.Single(dictionary);
|
||||
|
|
@ -99,11 +101,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
public void AddModelError_ForRelationExpression_AddsExpectedException()
|
||||
{
|
||||
// Arrange
|
||||
var exception = new Exception();
|
||||
var dictionary = new ModelStateDictionary();
|
||||
var exception = new Exception();
|
||||
var provider = new TestModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForProperty(typeof(ChildModel), nameof(ChildModel.Text));
|
||||
|
||||
// Act
|
||||
dictionary.AddModelError<TestModel>(model => model.Child.Text, exception);
|
||||
dictionary.AddModelError<TestModel>(model => model.Child.Text, exception, metadata);
|
||||
|
||||
// Assert
|
||||
var modelState = Assert.Single(dictionary);
|
||||
|
|
@ -117,11 +121,13 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
public void AddModelError_ForImplicitlyCastedToObjectExpression_AddsExpectedException()
|
||||
{
|
||||
// Arrange
|
||||
var exception = new Exception();
|
||||
var dictionary = new ModelStateDictionary();
|
||||
var exception = new Exception();
|
||||
var provider = new TestModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForProperty(typeof(ChildModel), nameof(ChildModel.Value));
|
||||
|
||||
// Act
|
||||
dictionary.AddModelError<TestModel>(model => model.Child.Value, exception);
|
||||
dictionary.AddModelError<TestModel>(model => model.Child.Value, exception, metadata);
|
||||
|
||||
// Assert
|
||||
var modelState = Assert.Single(dictionary);
|
||||
|
|
@ -135,12 +141,14 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
|
|||
public void AddModelError_ForNotModelsExpression_AddsExpectedException()
|
||||
{
|
||||
// Arrange
|
||||
var dictionary = new ModelStateDictionary();
|
||||
var variable = "Test";
|
||||
var exception = new Exception();
|
||||
var dictionary = new ModelStateDictionary();
|
||||
var provider = new TestModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForProperty(typeof(string), nameof(string.Length));
|
||||
|
||||
// Act
|
||||
dictionary.AddModelError<TestModel>(model => variable, exception);
|
||||
dictionary.AddModelError<TestModel>(model => variable, exception, metadata);
|
||||
|
||||
// Assert
|
||||
var modelState = Assert.Single(dictionary);
|
||||
|
|
|
|||
|
|
@ -343,23 +343,29 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
modelState.AddModelError("Property3.OrderedProperty3", "This is an error for Property3.OrderedProperty3.");
|
||||
modelState.AddModelError("Property3.OrderedProperty2", "This is an error for Property3.OrderedProperty2.");
|
||||
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForProperty(typeof(ValidationModel), nameof(ValidationModel.Property3));
|
||||
modelState.AddModelError("Property3", "This is an error for Property3.");
|
||||
modelState.AddModelError("Property3", new InvalidCastException("Exception will be ignored."));
|
||||
modelState.AddModelError("Property3", new InvalidCastException("Exception will be ignored."), metadata);
|
||||
|
||||
metadata = provider.GetMetadataForProperty(typeof(ValidationModel), nameof(ValidationModel.Property2));
|
||||
modelState.AddModelError("Property2", "This is an error for Property2.");
|
||||
modelState.AddModelError("Property2", "This is another error for Property2.");
|
||||
modelState.AddModelError("Property2", new OverflowException("Produces invalid value message"));
|
||||
modelState.AddModelError("Property2", new OverflowException("Produces invalid value message"), metadata);
|
||||
|
||||
metadata = provider.GetMetadataForType(typeof(ValidationModel));
|
||||
modelState.AddModelError(string.Empty, "This is an error for the model root.");
|
||||
modelState.AddModelError(string.Empty, "This is another error for the model root.");
|
||||
modelState.AddModelError(string.Empty, new InvalidOperationException("Another ignored Exception."));
|
||||
modelState.AddModelError(string.Empty, new InvalidOperationException("Another ignored Exception."), metadata);
|
||||
}
|
||||
|
||||
// Adds one or more errors for all properties in OrderedModel. But adds errors out of order.
|
||||
private void AddOrderedErrors(ModelStateDictionary modelState)
|
||||
{
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForProperty(typeof(OrderedModel), nameof(OrderedModel.Property3));
|
||||
modelState.AddModelError("Property3", "This is an error for Property3.");
|
||||
modelState.AddModelError("Property3", new InvalidCastException("An ignored Exception."));
|
||||
modelState.AddModelError("Property3", new InvalidCastException("An ignored Exception."), metadata);
|
||||
|
||||
modelState.AddModelError("Property2", "This is an error for Property2.");
|
||||
modelState.AddModelError("Property2", "This is another error for Property2.");
|
||||
|
|
|
|||
|
|
@ -66,13 +66,19 @@ namespace System.Web.Http.Dispatcher
|
|||
[Fact]
|
||||
public void ModelStateConstructorWithDetail_AddsCorrectDictionaryItems()
|
||||
{
|
||||
// Arrange
|
||||
ModelStateDictionary modelState = new ModelStateDictionary();
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForProperty(typeof(string), nameof(string.Length));
|
||||
modelState.AddModelError("[0].Name", "error1");
|
||||
modelState.AddModelError("[0].Name", "error2");
|
||||
modelState.AddModelError("[0].Address", "error");
|
||||
modelState.AddModelError("[2].Name", new Exception("OH NO"));
|
||||
modelState.AddModelError("[2].Name", new Exception("OH NO"), metadata);
|
||||
|
||||
// Act
|
||||
HttpError error = new HttpError(modelState, true);
|
||||
|
||||
// Assert
|
||||
HttpError modelStateError = error["ModelState"] as HttpError;
|
||||
|
||||
Assert.Contains(new KeyValuePair<string, object>("Message", "The request is invalid."), error);
|
||||
|
|
@ -98,13 +104,19 @@ namespace System.Web.Http.Dispatcher
|
|||
[Fact]
|
||||
public void ModelStateConstructorWithoutDetail_AddsCorrectDictionaryItems()
|
||||
{
|
||||
// Arrange
|
||||
ModelStateDictionary modelState = new ModelStateDictionary();
|
||||
var provider = new EmptyModelMetadataProvider();
|
||||
var metadata = provider.GetMetadataForProperty(typeof(string), nameof(string.Length));
|
||||
modelState.AddModelError("[0].Name", "error1");
|
||||
modelState.AddModelError("[0].Name", "error2");
|
||||
modelState.AddModelError("[0].Address", "error");
|
||||
modelState.AddModelError("[2].Name", new Exception("OH NO"));
|
||||
modelState.AddModelError("[2].Name", new Exception("OH NO"), metadata);
|
||||
|
||||
// Act
|
||||
HttpError error = new HttpError(modelState, false);
|
||||
|
||||
// Assert
|
||||
HttpError modelStateError = error["ModelState"] as HttpError;
|
||||
|
||||
Assert.Contains(new KeyValuePair<string, object>("Message", "The request is invalid."), error);
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace XmlFormattersWebSite.Controllers
|
|||
}
|
||||
|
||||
ModelState.AddModelError("key1", "key1-error");
|
||||
ModelState.AddModelError("key2", exception);
|
||||
ModelState.AddModelError("key2", exception, ViewData.ModelMetadata);
|
||||
|
||||
return new ObjectResult(new SerializableError(ModelState));
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue