diff --git a/src/Microsoft.AspNet.Mvc.Core/Properties/Resources.Designer.cs b/src/Microsoft.AspNet.Mvc.Core/Properties/Resources.Designer.cs
index 9dfdac729a..62dc4be9f4 100644
--- a/src/Microsoft.AspNet.Mvc.Core/Properties/Resources.Designer.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/Properties/Resources.Designer.cs
@@ -730,6 +730,22 @@ namespace Microsoft.AspNet.Mvc.Core
return string.Format(CultureInfo.CurrentCulture, GetString("HtmlHelper_SelectExpressionNotEnumerable"), p0);
}
+ ///
+ /// The type '{0}' is not supported. Type must be an {1} that does not have an associated {2}.
+ ///
+ internal static string HtmlHelper_TypeNotSupported_ForGetEnumSelectList
+ {
+ get { return GetString("HtmlHelper_TypeNotSupported_ForGetEnumSelectList"); }
+ }
+
+ ///
+ /// The type '{0}' is not supported. Type must be an {1} that does not have an associated {2}.
+ ///
+ internal static string FormatHtmlHelper_TypeNotSupported_ForGetEnumSelectList(object p0, object p1, object p2)
+ {
+ return string.Format(CultureInfo.CurrentCulture, GetString("HtmlHelper_TypeNotSupported_ForGetEnumSelectList"), p0, p1, p2);
+ }
+
///
/// The ViewData item that has the key '{0}' is of type '{1}' but must be of type '{2}'.
///
diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs
index 8de7be9913..2191b575b3 100644
--- a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs
@@ -350,6 +350,39 @@ namespace Microsoft.AspNet.Mvc.Rendering
additionalViewData);
}
+ ///
+ public IEnumerable GetEnumSelectList() where TEnum : struct
+ {
+ var type = typeof(TEnum);
+ var metadata = MetadataProvider.GetMetadataForType(type);
+ if (!metadata.IsEnum || metadata.IsFlagsEnum)
+ {
+ var message = Resources.FormatHtmlHelper_TypeNotSupported_ForGetEnumSelectList(
+ type.FullName,
+ nameof(Enum).ToLowerInvariant(),
+ nameof(FlagsAttribute));
+ throw new ArgumentException(message, nameof(TEnum));
+ }
+
+ return GetEnumSelectList(metadata);
+ }
+
+ ///
+ public IEnumerable GetEnumSelectList([NotNull] Type enumType)
+ {
+ var metadata = MetadataProvider.GetMetadataForType(enumType);
+ if (!metadata.IsEnum || metadata.IsFlagsEnum)
+ {
+ var message = Resources.FormatHtmlHelper_TypeNotSupported_ForGetEnumSelectList(
+ enumType.FullName,
+ nameof(Enum).ToLowerInvariant(),
+ nameof(FlagsAttribute));
+ throw new ArgumentException(message, nameof(enumType));
+ }
+
+ return GetEnumSelectList(metadata);
+ }
+
///
public HtmlString Hidden(string expression, object value, object htmlAttributes)
{
@@ -1016,5 +1049,43 @@ namespace Microsoft.AspNet.Mvc.Rendering
{
return _htmlGenerator.GetClientValidationRules(ViewContext, modelExplorer, expression);
}
+
+ ///
+ /// Returns a select list for the given .
+ ///
+ /// to generate a select list for.
+ ///
+ /// An containing the select list for the given
+ /// .
+ ///
+ ///
+ /// Thrown if 's is not an
+ /// or if it has a .
+ ///
+ protected virtual IEnumerable GetEnumSelectList([NotNull] ModelMetadata metadata)
+ {
+ if (!metadata.IsEnum || metadata.IsFlagsEnum)
+ {
+ var message = Resources.FormatHtmlHelper_TypeNotSupported_ForGetEnumSelectList(
+ metadata.ModelType.FullName,
+ nameof(Enum).ToLowerInvariant(),
+ nameof(FlagsAttribute));
+ throw new ArgumentException(message, nameof(metadata));
+ }
+
+ var selectList = new List();
+ foreach (var keyValuePair in metadata.EnumDisplayNamesAndValues)
+ {
+ var selectListItem = new SelectListItem
+ {
+ Text = keyValuePair.Key,
+ Value = keyValuePair.Value,
+ };
+
+ selectList.Add(selectListItem);
+ }
+
+ return selectList;
+ }
}
}
diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelper.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelper.cs
index c88702865a..9b5931aa20 100644
--- a/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelper.cs
+++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelper.cs
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Open Technologies, Inc. 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.Threading.Tasks;
using Microsoft.AspNet.Mvc.ModelBinding;
@@ -374,7 +375,37 @@ namespace Microsoft.AspNet.Mvc.Rendering
/// is null; ignored otherwise.
///
/// An containing the relevant rules.
- IEnumerable GetClientValidationRules(ModelExplorer modelExplorer, string expression);
+ IEnumerable GetClientValidationRules(
+ ModelExplorer modelExplorer,
+ string expression);
+
+ ///
+ /// Returns a select list for the given .
+ ///
+ /// Type to generate a select list for.
+ ///
+ /// An containing the select list for the given
+ /// .
+ ///
+ ///
+ /// Thrown if is not an or if it has a
+ /// .
+ ///
+ IEnumerable GetEnumSelectList() where TEnum : struct;
+
+ ///
+ /// Returns a select list for the given .
+ ///
+ /// to generate a select list for.
+ ///
+ /// An containing the select list for the given
+ /// .
+ ///
+ ///
+ /// Thrown if is not an or if it has a
+ /// .
+ ///
+ IEnumerable GetEnumSelectList([NotNull] Type enumType);
///
/// Returns an <input> element of type "hidden" for the specified .
diff --git a/src/Microsoft.AspNet.Mvc.Core/Resources.resx b/src/Microsoft.AspNet.Mvc.Core/Resources.resx
index 20099dea90..2ad230d2c9 100644
--- a/src/Microsoft.AspNet.Mvc.Core/Resources.resx
+++ b/src/Microsoft.AspNet.Mvc.Core/Resources.resx
@@ -253,6 +253,9 @@
The parameter '{0}' must evaluate to an IEnumerable when multiple selection is allowed.
+
+ The type '{0}' is not supported. Type must be an {1} that does not have an associated {2}.
+
The ViewData item that has the key '{0}' is of type '{1}' but must be of type '{2}'.
diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Properties/Resources.Designer.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Properties/Resources.Designer.cs
new file mode 100644
index 0000000000..300525e63d
--- /dev/null
+++ b/test/Microsoft.AspNet.Mvc.Core.Test/Properties/Resources.Designer.cs
@@ -0,0 +1,46 @@
+//
+namespace Microsoft.AspNet.Mvc.Core.Test
+{
+ using System.Globalization;
+ using System.Reflection;
+ using System.Resources;
+
+ internal static class Resources
+ {
+ private static readonly ResourceManager _resourceManager
+ = new ResourceManager("Microsoft.AspNet.Mvc.Core.Test.Resources", typeof(Resources).GetTypeInfo().Assembly);
+
+ ///
+ /// name from resources
+ ///
+ internal static string DisplayAttribute_Name
+ {
+ get { return GetString("DisplayAttribute_Name"); }
+ }
+
+ ///
+ /// name from resources
+ ///
+ internal static string FormatDisplayAttribute_Name()
+ {
+ return GetString("DisplayAttribute_Name");
+ }
+
+ private static string GetString(string name, params string[] formatterNames)
+ {
+ var value = _resourceManager.GetString(name);
+
+ System.Diagnostics.Debug.Assert(value != null);
+
+ if (formatterNames != null)
+ {
+ for (var i = 0; i < formatterNames.Length; i++)
+ {
+ value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}");
+ }
+ }
+
+ return value;
+ }
+ }
+}
diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultEditorTemplatesTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultEditorTemplatesTest.cs
index 467d9ab9c5..7c27d4cfea 100644
--- a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultEditorTemplatesTest.cs
+++ b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/DefaultEditorTemplatesTest.cs
@@ -1012,12 +1012,22 @@ Environment.NewLine;
}
public IEnumerable GetClientValidationRules(
- ModelExplorer modelExplorer,
+ ModelExplorer modelExplorer,
string name)
{
return Enumerable.Empty();
}
+ public IEnumerable GetEnumSelectList() where TEnum : struct
+ {
+ throw new NotImplementedException();
+ }
+
+ public IEnumerable GetEnumSelectList([NotNull] Type enumType)
+ {
+ throw new NotImplementedException();
+ }
+
public HtmlString Hidden(string name, object value, object htmlAttributes)
{
return new HtmlString("__Hidden__");
diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/HtmlHelperSelectTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/HtmlHelperSelectTest.cs
index 525a290db0..cf972b1adf 100644
--- a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/HtmlHelperSelectTest.cs
+++ b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/HtmlHelperSelectTest.cs
@@ -3,7 +3,13 @@
using System;
using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
using System.Linq;
+using Microsoft.AspNet.Mvc.ModelBinding;
+using Microsoft.AspNet.Testing;
+using Microsoft.Framework.Internal;
+using Microsoft.Framework.WebEncoders;
+using Moq;
using Xunit;
namespace Microsoft.AspNet.Mvc.Rendering
@@ -858,6 +864,354 @@ namespace Microsoft.AspNet.Mvc.Rendering
Assert.Equal(savedSelected, selectList.Select(item => item.Selected));
}
+ [Fact]
+ public void GetEnumSelectListTEnum_ThrowsWithFlagsEnum()
+ {
+ // Arrange
+ var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
+ var htmlHelper = new TestHtmlHelper(metadataProvider);
+
+ // Act & Assert
+ ExceptionAssert.ThrowsArgument(
+ () => htmlHelper.GetEnumSelectList(),
+ "TEnum",
+ $"The type '{ typeof(EnumWithFlags).FullName }' is not supported.");
+ }
+
+ [Fact]
+ public void GetEnumSelectListTEnum_ThrowsWithNonEnum()
+ {
+ // Arrange
+ var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
+ var htmlHelper = new TestHtmlHelper(metadataProvider);
+
+ // Act & Assert
+ ExceptionAssert.ThrowsArgument(
+ () => htmlHelper.GetEnumSelectList(),
+ "TEnum",
+ $"The type '{ typeof(StructWithFields).FullName }' is not supported.");
+ }
+
+ [Fact]
+ public void GetEnumSelectListTEnum_WrapsGetEnumSelectListModelMetadata()
+ {
+ // Arrange
+ var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
+ var metadata = metadataProvider.GetMetadataForType(typeof(EnumWithFields));
+ var htmlHelper = new TestHtmlHelper(metadataProvider);
+
+ // Act
+ var result = htmlHelper.GetEnumSelectList();
+
+ // Assert
+ Assert.Equal(metadata.ModelType, htmlHelper.Metadata.ModelType);
+
+ Assert.Same(htmlHelper.SelectListItems, result); // No replacement of the underlying List
+ VerifySelectList(htmlHelper.CopiedSelectListItems, result); // No change to the (mutable) items
+ }
+
+ [Fact]
+ public void GetEnumSelectListType_ThrowsWithFlagsEnum()
+ {
+ // Arrange
+ var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
+ var htmlHelper = new TestHtmlHelper(metadataProvider);
+
+ // Act & Assert
+ ExceptionAssert.ThrowsArgument(
+ () => htmlHelper.GetEnumSelectList(typeof(EnumWithFlags)),
+ "enumType",
+ $"The type '{ typeof(EnumWithFlags).FullName }' is not supported.");
+ }
+
+ [Fact]
+ public void GetEnumSelectListType_ThrowsWithNonEnum()
+ {
+ // Arrange
+ var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
+ var htmlHelper = new TestHtmlHelper(metadataProvider);
+
+ // Act & Assert
+ ExceptionAssert.ThrowsArgument(
+ () => htmlHelper.GetEnumSelectList(typeof(StructWithFields)),
+ "enumType",
+ $"The type '{ typeof(StructWithFields).FullName }' is not supported.");
+ }
+
+ [Fact]
+ public void GetEnumSelectListType_ThrowsWithNonStruct()
+ {
+ // Arrange
+ var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
+ var htmlHelper = new TestHtmlHelper(metadataProvider);
+
+ // Act & Assert
+ ExceptionAssert.ThrowsArgument(
+ () => htmlHelper.GetEnumSelectList(typeof(ClassWithFields)),
+ "enumType",
+ $"The type '{ typeof(ClassWithFields).FullName }' is not supported.");
+ }
+
+ [Fact]
+ public void GetEnumSelectListType_WrapsGetEnumSelectListModelMetadata()
+ {
+ // Arrange
+ var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
+ var metadata = metadataProvider.GetMetadataForType(typeof(EnumWithFields));
+ var htmlHelper = new TestHtmlHelper(metadataProvider);
+
+ // Act
+ var result = htmlHelper.GetEnumSelectList(typeof(EnumWithFields));
+
+ // Assert
+ Assert.Equal(metadata.ModelType, htmlHelper.Metadata.ModelType);
+
+ Assert.Same(htmlHelper.SelectListItems, result); // No replacement of the underlying List
+ VerifySelectList(htmlHelper.CopiedSelectListItems, result); // No change to the (mutable) items
+ }
+
+ public static TheoryData> GetEnumSelectListData
+ {
+ get
+ {
+ return new TheoryData>
+ {
+ { typeof(EmptyEnum), Enumerable.Empty() },
+ { typeof(EmptyEnum?), Enumerable.Empty() },
+ {
+ typeof(EnumWithDisplayNames),
+ new List
+ {
+ new SelectListItem { Text = "cero", Value = "0" },
+ new SelectListItem { Text = nameof(EnumWithDisplayNames.One), Value = "1" },
+ new SelectListItem { Text = "dos", Value = "2" },
+ new SelectListItem { Text = "tres", Value = "3" },
+ new SelectListItem { Text = "name from resources", Value = "-2" },
+ new SelectListItem { Text = "menos uno", Value = "-1" },
+ }
+ },
+ {
+ typeof(EnumWithDisplayNames?),
+ new List
+ {
+ new SelectListItem { Text = "cero", Value = "0" },
+ new SelectListItem { Text = nameof(EnumWithDisplayNames.One), Value = "1" },
+ new SelectListItem { Text = "dos", Value = "2" },
+ new SelectListItem { Text = "tres", Value = "3" },
+ new SelectListItem { Text = "name from resources", Value = "-2" },
+ new SelectListItem { Text = "menos uno", Value = "-1" },
+ }
+ },
+ {
+ typeof(EnumWithDuplicates),
+ new List
+ {
+ new SelectListItem { Text = nameof(EnumWithDuplicates.Zero), Value = "0" },
+ new SelectListItem { Text = nameof(EnumWithDuplicates.None), Value = "0" },
+ new SelectListItem { Text = nameof(EnumWithDuplicates.One), Value = "1" },
+ new SelectListItem { Text = nameof(EnumWithDuplicates.Duece), Value = "2" },
+ new SelectListItem { Text = nameof(EnumWithDuplicates.Two), Value = "2" },
+ new SelectListItem { Text = nameof(EnumWithDuplicates.MoreThanTwo), Value = "3" },
+ new SelectListItem { Text = nameof(EnumWithDuplicates.Three), Value = "3" },
+ }
+ },
+ {
+ typeof(EnumWithDuplicates?),
+ new List
+ {
+ new SelectListItem { Text = nameof(EnumWithDuplicates.Zero), Value = "0" },
+ new SelectListItem { Text = nameof(EnumWithDuplicates.None), Value = "0" },
+ new SelectListItem { Text = nameof(EnumWithDuplicates.One), Value = "1" },
+ new SelectListItem { Text = nameof(EnumWithDuplicates.Duece), Value = "2" },
+ new SelectListItem { Text = nameof(EnumWithDuplicates.Two), Value = "2" },
+ new SelectListItem { Text = nameof(EnumWithDuplicates.MoreThanTwo), Value = "3" },
+ new SelectListItem { Text = nameof(EnumWithDuplicates.Three), Value = "3" },
+ }
+ },
+ {
+ typeof(EnumWithFields),
+ new List
+ {
+ new SelectListItem { Text = nameof(EnumWithFields.Zero), Value = "0" },
+ new SelectListItem { Text = nameof(EnumWithFields.One), Value = "1" },
+ new SelectListItem { Text = nameof(EnumWithFields.Two), Value = "2" },
+ new SelectListItem { Text = nameof(EnumWithFields.Three), Value = "3" },
+ new SelectListItem { Text = nameof(EnumWithFields.MinusTwo), Value = "-2" },
+ new SelectListItem { Text = nameof(EnumWithFields.MinusOne), Value = "-1" },
+ }
+ },
+ {
+ typeof(EnumWithFields?),
+ new List
+ {
+ new SelectListItem { Text = nameof(EnumWithFields.Zero), Value = "0" },
+ new SelectListItem { Text = nameof(EnumWithFields.One), Value = "1" },
+ new SelectListItem { Text = nameof(EnumWithFields.Two), Value = "2" },
+ new SelectListItem { Text = nameof(EnumWithFields.Three), Value = "3" },
+ new SelectListItem { Text = nameof(EnumWithFields.MinusTwo), Value = "-2" },
+ new SelectListItem { Text = nameof(EnumWithFields.MinusOne), Value = "-1" },
+ }
+ },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(GetEnumSelectListData))]
+ public void GetEnumSelectList_ReturnsExpectedItems(Type type, IEnumerable expected)
+ {
+ // Arrange
+ var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
+ var metadata = metadataProvider.GetMetadataForType(type);
+ var htmlHelper = new TestHtmlHelper(metadataProvider);
+
+ // Act
+ var result = htmlHelper.GetEnumSelectList(type);
+
+ // Assert
+ VerifySelectList(expected, result);
+ }
+
+ // Confirm methods that wrap GetEnumSelectList(ModelMetadata) are not changing anything in returned collection.
+ private void VerifySelectList(IEnumerable expected, IEnumerable actual)
+ {
+ Assert.NotNull(actual);
+ Assert.Equal(expected.Count(), actual.Count());
+ for (var i = 0; i < actual.Count(); i++)
+ {
+ var expectedItem = expected.ElementAt(i);
+ var actualItem = actual.ElementAt(i);
+
+ Assert.False(actualItem.Disabled);
+ Assert.Null(actualItem.Group);
+ Assert.False(actualItem.Selected);
+ Assert.Equal(expectedItem.Text, actualItem.Text);
+ Assert.Equal(expectedItem.Value, actualItem.Value);
+ }
+ }
+
+ private class TestHtmlHelper : HtmlHelper
+ {
+ public TestHtmlHelper([NotNull] IModelMetadataProvider metadataProvider)
+ : base(
+ new Mock(MockBehavior.Strict).Object,
+ new Mock(MockBehavior.Strict).Object,
+ metadataProvider,
+ new Mock(MockBehavior.Strict).Object,
+ new Mock(MockBehavior.Strict).Object,
+ new Mock(MockBehavior.Strict).Object)
+ {
+ }
+
+ public ModelMetadata Metadata { get; private set; }
+
+ public IEnumerable SelectListItems { get; private set; }
+
+ public IEnumerable CopiedSelectListItems { get; private set; }
+
+ protected override IEnumerable GetEnumSelectList([NotNull] ModelMetadata metadata)
+ {
+ Metadata = metadata;
+ SelectListItems = base.GetEnumSelectList(metadata);
+ if (SelectListItems != null)
+ {
+ // Perform a deep copy to help confirm the mutable items are not changed.
+ var copiedSelectListItems = new List();
+ CopiedSelectListItems = copiedSelectListItems;
+ foreach (var item in SelectListItems)
+ {
+ var copy = new SelectListItem
+ {
+ Disabled = item.Disabled,
+ Group = item.Group,
+ Selected = item.Selected,
+ Text = item.Text,
+ Value = item.Value,
+ };
+
+ copiedSelectListItems.Add(copy);
+ }
+ }
+
+ return SelectListItems;
+ }
+ }
+
+ private class ClassWithFields
+ {
+ public const int Zero = 0;
+
+ public const int One = 1;
+ }
+
+ private enum EmptyEnum
+ {
+ }
+
+ private enum EnumWithDisplayNames
+ {
+ [Display(Name = "tres")]
+ Three = 3,
+
+ [Display(Name = "dos")]
+ Two = 2,
+
+ // Display attribute exists but does not set Name.
+ [Display(ShortName = "uno")]
+ One = 1,
+
+ [Display(Name = "cero")]
+ Zero = 0,
+
+ [Display(Name = "menos uno")]
+ MinusOne = -1,
+
+#if USE_REAL_RESOURCES
+ [Display(Name = nameof(Test.Resources.DisplayAttribute_Name), ResourceType = typeof(Test.Resources))]
+#else
+ [Display(Name = nameof(TestResources.DisplayAttribute_Name), ResourceType = typeof(TestResources))]
+#endif
+ MinusTwo = -2,
+ }
+
+ private enum EnumWithDuplicates
+ {
+ Zero = 0,
+ One = 1,
+ Three = 3,
+ MoreThanTwo = 3,
+ Two = 2,
+ None = 0,
+ Duece = 2,
+ }
+
+ [Flags]
+ private enum EnumWithFlags
+ {
+ Four = 4,
+ Two = 2,
+ One = 1,
+ Zero = 0,
+ All = -1,
+ }
+
+ private enum EnumWithFields
+ {
+ MinusTwo = -2,
+ MinusOne = -1,
+ Three = 3,
+ Two = 2,
+ One = 1,
+ Zero = 0,
+ }
+
+ private struct StructWithFields
+ {
+ public const int Zero = 0;
+
+ public const int One = 1;
+ }
+
private class ModelContainingList
{
public List Property1 { get; } = new List();
diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/TestResources.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/TestResources.cs
new file mode 100644
index 0000000000..1d66d7f313
--- /dev/null
+++ b/test/Microsoft.AspNet.Mvc.Core.Test/Rendering/TestResources.cs
@@ -0,0 +1,14 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNet.Mvc.Core.Test;
+
+namespace Microsoft.AspNet.Mvc
+{
+ // Wrap resources to make them available as public properties for [Display]. That attribute does not support
+ // internal properties.
+ public class TestResources
+ {
+ public static string DisplayAttribute_Name { get; } = Resources.DisplayAttribute_Name;
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Resources.resx b/test/Microsoft.AspNet.Mvc.Core.Test/Resources.resx
new file mode 100644
index 0000000000..08344b52fb
--- /dev/null
+++ b/test/Microsoft.AspNet.Mvc.Core.Test/Resources.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ name from resources
+
+
\ No newline at end of file
diff --git a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/DataAnnotationsMetadataProviderTest.cs b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/DataAnnotationsMetadataProviderTest.cs
index b2353ee428..0b50d8ed40 100644
--- a/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/DataAnnotationsMetadataProviderTest.cs
+++ b/test/Microsoft.AspNet.Mvc.ModelBinding.Test/Metadata/DataAnnotationsMetadataProviderTest.cs
@@ -422,7 +422,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata
new List>
{
new KeyValuePair("cero", "0"),
- new KeyValuePair("uno", "1"),
+ new KeyValuePair(nameof(EnumWithDisplayNames.One), "1"),
new KeyValuePair("dos", "2"),
new KeyValuePair("tres", "3"),
new KeyValuePair("name from resources", "-2"),
@@ -434,7 +434,7 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata
new List>
{
new KeyValuePair("cero", "0"),
- new KeyValuePair("uno", "1"),
+ new KeyValuePair(nameof(EnumWithDisplayNames.One), "1"),
new KeyValuePair("dos", "2"),
new KeyValuePair("tres", "3"),
new KeyValuePair("name from resources", "-2"),
@@ -569,7 +569,8 @@ namespace Microsoft.AspNet.Mvc.ModelBinding.Metadata
[Display(Name = "dos")]
Two = 2,
- [Display(Name = "uno")]
+ // Display attribute exists but does not set Name.
+ [Display(ShortName = "uno")]
One = 1,
[Display(Name = "cero")]