Fix 1373, Improve EDDL() Exception message in the [Flags] case

- https://aspnetwebstack.codeplex.com/workitem/1373
- "Error message is not clear when enum that has flags attribute calls EnumDropDownListFor html helper"
- Add new message for case where ModelType has a [Flags] attribute
- Provide EnumHelper.HasFlags(Type) internal method to make determination easy for EDDL()
- Leads to a duplicate call to Nullable.GetUnderlyingType(Type) but only in the failure case
This commit is contained in:
dougbu 2013-11-07 15:52:51 -08:00
Родитель d778f9c0f9
Коммит 5ce679813f
5 изменённых файлов: 44 добавлений и 7 удалений

Просмотреть файл

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.Contracts;
using System.Linq.Expressions;
using System.Reflection;
using System.Web.Mvc.Properties;
@ -38,8 +39,7 @@ namespace System.Web.Mvc.Html
Type checkedType = Nullable.GetUnderlyingType(type) ?? type;
if (checkedType.IsEnum)
{
FlagsAttribute attribute = checkedType.GetCustomAttribute<FlagsAttribute>(inherit: false);
isValid = attribute == null;
isValid = !HasFlagsInternal(checkedType);
}
}
@ -257,6 +257,22 @@ namespace System.Web.Mvc.Html
return GetSelectList(metadata.ModelType, value);
}
internal static bool HasFlags(Type type)
{
Contract.Assert(type != null);
Type checkedType = Nullable.GetUnderlyingType(type) ?? type;
return HasFlagsInternal(checkedType);
}
private static bool HasFlagsInternal(Type type)
{
Contract.Assert(type != null);
FlagsAttribute attribute = type.GetCustomAttribute<FlagsAttribute>(inherit: false);
return attribute != null;
}
// Return non-empty name specified in a [Display] attribute for the given field, if any; field's name otherwise
private static string GetDisplayName(FieldInfo field)
{

Просмотреть файл

@ -169,8 +169,17 @@ namespace System.Web.Mvc.Html
if (!EnumHelper.IsValidForEnumHelper(metadata.ModelType))
{
throw Error.Argument("expression", MvcResources.SelectExtensions_InvalidExpressionParameterType,
metadata.ModelType.FullName);
string formatString;
if (EnumHelper.HasFlags(metadata.ModelType))
{
formatString = MvcResources.SelectExtensions_InvalidExpressionParameterTypeHasFlags;
}
else
{
formatString = MvcResources.SelectExtensions_InvalidExpressionParameterType;
}
throw Error.Argument("expression", formatString, metadata.ModelType.FullName, "Flags");
}
// Run through same processing as SelectInternal() to determine selected value and ensure it is included

11
src/System.Web.Mvc/Properties/MvcResources.Designer.cs сгенерированный
Просмотреть файл

@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.18051
// Runtime Version:4.0.30319.34003
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@ -1095,6 +1095,15 @@ namespace System.Web.Mvc.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Return type &apos;{0}&apos; is not supported. Type must not have a &apos;{1}&apos; attribute..
/// </summary>
internal static string SelectExtensions_InvalidExpressionParameterTypeHasFlags {
get {
return ResourceManager.GetString("SelectExtensions_InvalidExpressionParameterTypeHasFlags", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The SessionStateTempDataProvider class requires session state to be enabled..
/// </summary>

Просмотреть файл

@ -507,6 +507,9 @@
<data name="SelectExtensions_InvalidExpressionParameterType" xml:space="preserve">
<value>Return type '{0}' is not supported.</value>
</data>
<data name="SelectExtensions_InvalidExpressionParameterTypeHasFlags" xml:space="preserve">
<value>Return type '{0}' is not supported. Type must not have a '{1}' attribute.</value>
</data>
<data name="DefaultControllerFactory_DirectRouteAmbiguous" xml:space="preserve">
<value>Multiple controller types were found that match the URL. This can happen if attribute routes on multiple controllers match the requested URL.{1}{1}The request has found the following matching controller types: {0}</value>
</data>

Просмотреть файл

@ -1137,7 +1137,7 @@ namespace System.Web.Mvc.Html.Test
// Act & Assert
Assert.ThrowsArgument(() => helper.EnumDropDownListFor(model => model), paramName: "expression",
exceptionMessage: "Return type 'System.Web.Mvc.Html.Test.SelectExtensionsTest+EnumWithFlags' is not " +
"supported." + Environment.NewLine +
"supported. Type must not have a 'Flags' attribute." + Environment.NewLine +
"Parameter name: expression");
}
@ -1151,7 +1151,7 @@ namespace System.Web.Mvc.Html.Test
// Act & Assert
Assert.ThrowsArgument(() => helper.EnumDropDownListFor(m => m.WithFlags), paramName: "expression",
exceptionMessage: "Return type 'System.Web.Mvc.Html.Test.SelectExtensionsTest+EnumWithFlags' is not " +
"supported." + Environment.NewLine +
"supported. Type must not have a 'Flags' attribute." + Environment.NewLine +
"Parameter name: expression");
}