Ok les gars. J'ai cherché plusieurs façons de le faire parce que j'étais fatigué d'écrire des astuces stupides pour contourner cette déficience du cadre .Net. Sur la base de quelques fils de discussion, j'ai composé la solution suivante.
Attention, il ne s'agit pas d'une solution totalement automatisée, et elle ne fonctionnera donc pas pour tous. Compte tenu de ma mise en œuvre, cela fonctionne. Peut-être que ma méthode aidera quelqu'un d'autre à concevoir quelque chose qui fonctionnera pour lui.
D'abord, j'ai créé un référentiel d'enum. Les enums n'ont pas besoin de résider ici, mais ils doivent être visibles depuis le référentiel.
Dans le référentiel, j'ai créé une classe et une propriété statique publique pour exposer une liste de types d'enum.
namespace MyApp.Enums
{
public enum ATS_Tabs { TabOne = 0, TabTwo = 1, TabThree = 2, TabFour = 3, TabFive = 4 };
public class ModelEnums
{
public static IEnumerable<Type> Types
{
get
{
List<Type> Types = new List<Type>();
Types.Add(typeof(ATS_Tabs));
return Types;
}
}
}
}
Ensuite, j'ai créé un classeur de modèles et implémenté l'interface IModelBinder (voir le commentaire et le lien de kdawg).
namespace MyApp.CustomModelBinders
{
public class EnumModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
ModelState modelState = new ModelState { Value = valueResult };
object actualValue = null;
try
{
return Enum.ToObject(Type.GetType(bindingContext.ModelType.AssemblyQualifiedName), Convert.ToInt32(valueResult.AttemptedValue));
}
catch (FormatException e)
{
modelState.Errors.Add(e);
}
bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
return actualValue;
}
}
}
Il pourrait être utile d'ajouter du code pour s'assurer que la conversion de valueResult.AttemptedValue n'échoue pas.
Ensuite, j'ai parcouru en boucle la liste des types d'enum que j'ai créée ci-dessus et j'ai ajouté des classeurs de modèles pour eux (...dans Global.asax.cs).
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
foreach (Type type in ModelEnums.Types)
{
ModelBinders.Binders.Add(type, new EnumModelBinder());
}
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
J'admets que ce n'est pas la méthode la plus intuitive, mais elle fonctionne très bien pour moi. N'hésitez pas à me faire savoir si je peux l'optimiser.