CR feedback from [ModelBinderAttribute]

This commit is contained in:
Ryan Nowak 2014-12-05 14:30:41 -08:00
parent f94bd53464
commit ca714c5149
6 changed files with 105 additions and 6 deletions

View File

@ -37,8 +37,9 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
} }
/// <summary> /// <summary>
/// Gets (or sets in subclasses) <see cref="IEnumerable{IBinderTypeProviderMetadata}"/> found in collection passed /// Gets (or sets in subclasses) <see cref="IEnumerable{IBinderTypeProviderMetadata}"/> found in collection
/// to the <see cref="CachedDataAnnotationsMetadataAttributes(IEnumerable{object})"/> constructor, if any. /// passed to the <see cref="CachedDataAnnotationsMetadataAttributes(IEnumerable{object})"/> constructor,
/// if any.
/// </summary> /// </summary>
public IEnumerable<IBinderTypeProviderMetadata> BinderTypeProviders { get; set; } public IEnumerable<IBinderTypeProviderMetadata> BinderTypeProviders { get; set; }

View File

@ -39,9 +39,6 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
{ {
if (PrototypeCache.BinderTypeProviders != null) if (PrototypeCache.BinderTypeProviders != null)
{ {
// The need for fallback here is to handle cases where a model binder is specified
// on a type and on a parameter to an action.
//
// We want to respect the value set by the parameter (if any), and use the value specifed // We want to respect the value set by the parameter (if any), and use the value specifed
// on the type as a fallback. // on the type as a fallback.
// //

View File

@ -64,7 +64,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
// Act // Act
var response = await client.PostAsync("http://localhost/Home/GetCustomer?Id=1234", content); var response = await client.PostAsync("http://localhost/Home/GetCustomer?Id=1234", content);
// Assert // Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var customer = JsonConvert.DeserializeObject<Customer>( var customer = JsonConvert.DeserializeObject<Customer>(

View File

@ -86,12 +86,31 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
var result = cache.PropertyBindingInfo.ToArray(); var result = cache.PropertyBindingInfo.ToArray();
// Assert // Assert
Assert.Equal(propertyBindingInfos.Length, result.Length);
for (var index = 0; index < propertyBindingInfos.Length; index++) for (var index = 0; index < propertyBindingInfos.Length; index++)
{ {
Assert.Same(propertyBindingInfos[index], result[index]); Assert.Same(propertyBindingInfos[index], result[index]);
} }
} }
[Fact]
public void Constructor_FindsBinderTypeProviders()
{
// Arrange
var providers = new[] { new TestBinderTypeProvider(), new TestBinderTypeProvider() };
// Act
var cache = new CachedDataAnnotationsMetadataAttributes(providers);
var result = cache.BinderTypeProviders.ToArray();
// Assert
Assert.Equal(providers.Length, result.Length);
for (var index = 0; index < providers.Length; index++)
{
Assert.Same(providers[index], result[index]);
}
}
[Fact] [Fact]
public void Constructor_FindsDisplayFormat_FromDataType() public void Constructor_FindsDisplayFormat_FromDataType()
{ {
@ -123,5 +142,10 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
// Assert // Assert
Assert.Same(displayFormat, result); Assert.Same(displayFormat, result);
} }
private class TestBinderTypeProvider : IBinderTypeProviderMetadata
{
public Type BinderType { get; set; }
}
} }
} }

View File

@ -52,6 +52,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
Assert.Null(metadata.BinderModelName); Assert.Null(metadata.BinderModelName);
Assert.Null(metadata.BinderMetadata); Assert.Null(metadata.BinderMetadata);
Assert.Null(metadata.BinderType);
Assert.Empty(metadata.BinderIncludeProperties); Assert.Empty(metadata.BinderIncludeProperties);
Assert.Null(metadata.BinderExcludeProperties); Assert.Null(metadata.BinderExcludeProperties);
} }
@ -399,6 +400,79 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
Assert.Null(metadata.EditFormatString); Assert.Null(metadata.EditFormatString);
} }
[Fact]
public void Constructor_FindsBinderTypeProviders_Null()
{
// Arrange
var provider = new DataAnnotationsModelMetadataProvider();
var binderProviders = new[] { new TestBinderTypeProvider(), new TestBinderTypeProvider() };
// Act
var metadata = new CachedDataAnnotationsModelMetadata(
provider,
containerType: null,
modelType: typeof(object),
propertyName: null,
attributes: binderProviders);
// Assert
Assert.Null(metadata.BinderType);
}
[Fact]
public void Constructor_FindsBinderTypeProviders_Fallback()
{
// Arrange
var provider = new DataAnnotationsModelMetadataProvider();
var binderProviders = new[]
{
new TestBinderTypeProvider(),
new TestBinderTypeProvider() { BinderType = typeof(string) }
};
// Act
var metadata = new CachedDataAnnotationsModelMetadata(
provider,
containerType: null,
modelType: typeof(object),
propertyName: null,
attributes: binderProviders);
// Assert
Assert.Same(typeof(string), metadata.BinderType);
}
[Fact]
public void Constructor_FindsBinderTypeProviders_FirstAttributeHasPrecedence()
{
// Arrange
var provider = new DataAnnotationsModelMetadataProvider();
var binderProviders = new[]
{
new TestBinderTypeProvider() { BinderType = typeof(int) },
new TestBinderTypeProvider() { BinderType = typeof(string) }
};
// Act
var metadata = new CachedDataAnnotationsModelMetadata(
provider,
containerType: null,
modelType: typeof(object),
propertyName: null,
attributes: binderProviders);
// Assert
Assert.Same(typeof(int), metadata.BinderType);
}
private class TestBinderTypeProvider : IBinderTypeProviderMetadata
{
public Type BinderType { get; set; }
}
private class DataTypeWithCustomDisplayFormat : DataTypeAttribute private class DataTypeWithCustomDisplayFormat : DataTypeAttribute
{ {
public DataTypeWithCustomDisplayFormat() : base("Custom datatype") public DataTypeWithCustomDisplayFormat() : base("Custom datatype")

View File

@ -54,6 +54,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
{ m => m.BinderModelName = null, m => m.BinderModelName, null }, { m => m.BinderModelName = null, m => m.BinderModelName, null },
{ m => m.BinderModelName = "newModelName", m => m.BinderModelName, "newModelName" }, { m => m.BinderModelName = "newModelName", m => m.BinderModelName, "newModelName" },
{ m => m.BinderModelName = string.Empty, m => m.BinderModelName, string.Empty }, { m => m.BinderModelName = string.Empty, m => m.BinderModelName, string.Empty },
{ m => m.BinderType = null, m => m.BinderType, null },
{ m => m.BinderType = typeof(string), m => m.BinderType, typeof(string) },
{ m => m.BinderIncludeProperties = null, m => m.BinderIncludeProperties, null }, { m => m.BinderIncludeProperties = null, m => m.BinderIncludeProperties, null },
{ {
m => m.BinderIncludeProperties = emptyPropertyList, m => m.BinderIncludeProperties = emptyPropertyList,
@ -124,6 +126,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding
Assert.Equal(ModelMetadata.DefaultOrder, metadata.Order); Assert.Equal(ModelMetadata.DefaultOrder, metadata.Order);
Assert.Null(metadata.BinderModelName); Assert.Null(metadata.BinderModelName);
Assert.Null(metadata.BinderType);
Assert.Null(metadata.BinderMetadata); Assert.Null(metadata.BinderMetadata);
Assert.Null(metadata.BinderIncludeProperties); Assert.Null(metadata.BinderIncludeProperties);
Assert.Null(metadata.BinderExcludeProperties); Assert.Null(metadata.BinderExcludeProperties);