Using flags enumeration with ASP.NET MVC and CodeFluent Entities

Brouillon

À venir

0 comment

Enumeration support

CodeFluent Entities provides full support of “enumeration” types and multi value enumerations (flag enumeration).

 image

To declare a multi value enumeration, go to the enumeration type properties and set the, go to the enumeration type properties and set the Multi Value property to True.

 image

And since the build version (646) you can set an enumeration value as the combination of other values (by their name).

 image

Using enumeration values with ASP.NET MVC

Let’s use these concepts on an ASP.NET MVC application, I will use the model above as an example. I also have a MediaController with an Index action to list all Medias and an Edit action (Get and Post). The default template for an enumeration value is a textbox, so if I write something like this:

@Html.EditorFor(m => m.MediaType)

I will get a textbox for my enumeration value.

 image

This will work but the user will have to write a correct enumeration value, and unless each user knows all the possible enumeration values, this is not an acceptable solution. It would be better to display a dropdown list instead. Let’s create a template namedChoice.cshtml on the Views\Shared\EditorTemplates folder.

@model Enum

@{
  var items = from object value in Enum.GetValues(Model.GetType())
  select new { Value = value, Text = value.ToString() };
  SelectList list = new SelectList(items, "Value", "Text", Model);
}

@Html.DropDownList("", list)

And now if we choose this as the template for our enumeration:

@Html.EditorFor(m => m.MediaType, "Choice")

 image

This works fine and we can use the Choice.cshtml template for any enumeration type.

Using multi enumeration values with ASP.NET MVC

Let’s now do the same work for a multi value enumeration (flag enumeration). First we create a template named MultiChoice.cshtml on the Views\Shared\EditorTemplates folder.

@model Enum

@{
  var items = from object value in Enum.GetValues(Model.GetType())
  select new { Value = value, Text = value.ToString() };
  IEnumerable selected = CodeFluent.Runtime.Utilities.ConvertUtilities.SplitEnumValues(Model);
  MultiSelectList list = new MultiSelectList(items, "Value", "Text", selected);
}

@Html.DropDownList("", list, new { multiple = "multiple" })

We use here a method on the CodeFluent.Runtime.Utilities namespace to split a flag value into a list of enumeration values. Let’s try it for our multi value enumeration.

@Html.EditorFor(m => m.ReleaseFormat, "MultiChoice")

 image

This seems to work but it doesn’t, when I try to save my form, not all values are saved (from the flag multi value enumeration). This is because MVC does not bind correctly the multi value enumeration to my model. We need to add a custom model binder (System.Web.Mvc.IModelBinder) and a value provider (System.Web.Mvc.IValueProvider). I will use some utilities classes that are used for the ASP.NET Web Site V2 producer, they can be found under the Templates folder in the CodeFluent Entities installation location (Program Files (x86)\SoftFluent\CodeFluent\Modeler\Templates\UI\AspNetMvc\Code\Utilities.cs.tpl). I will copy the content of the file in my ASP.NET MVC project filling the correct namespace. Don’t forget to add a reference to the CodeFluent.Runtime.Web assembly.

 image

Finally, we register the EntityBinder and the EntityValueProviderFactory classes that we have just added. On the Application Start:

ValueProviderFactories.Factories.Add(new EntityValueProviderFactory());
ModelBinderProviders.BinderProviders.Add(new EntityBinder());

This time everything works great. This post was inspired by the CodeFluent Entities templates when wondering what the ASP.NET Web Site V2 producer generates.

hca