Exploring Enums support in ASP.NET MVC 5.1 – Part 2

This is second part of the series of exploring enums support in ASP.NET MVC 5.1 that was recently got released with Visual Studio 2013 Update 2. The first part of the series can be read from the below link

Enums support in ASP.NET MVC 5.1- Part 1

In last post we discussed that how the new scaffolding works fantastic for enum types as well. But there are other different scenarios where we need to customize it before displaying on UI. We discuss the issue in one of the sceanio in last post. To handle these scenarios, few other new helper methods got introduced. A new class EnumHelper got added which has two methods :

GetSelectList – which has four overridden method and it returns a list of SelectListItem which can be used to further populate the dropdown in UI.

IsValidForEnumHelper– This method also has two overridden method that tells whether the passed type is enum. This should be used to check the type of passed value and GetSelectList should be used if IsValidForEnumHelper returns true.

So let’s jump to the example and use the above methods.

In part-1 of the series, we used the following enum in the example

public enum ExpertiseArea
{
    ASPNET,
    Csharp,
    WindowsAzure,
    WCF
}

but as we know that enum properties can not include space or some special characters. Say, if we want to display WindowsAzure as Windows Azure or ASPNET as ASP.NET etc. In this scenario, we need to create custom views for edit and display purposes.

First let’s change the enum itself and add the display attributes as

    public enum ExpertiseArea
    {
        [Display(Name = "ASP.NET")]
        ASPNET,
        [Display(Name = "C#")]
        Csharp,
        [Display(Name = "Windows Azure")]
        WindowsAzure,
        WCF
    }

Now let’s create the partial view for display scenario.  Here we need to cater multiple scenarios like

– If there are some items which has some selected value for enum property then find the selected text/vale. SelectedText represent the display attribute

– If nothing is selected then show the empty value. (Empty value cannot be converted in enum type)

– If the type itself is not an enum then use the normal value.

We can write it as

@model Enum

@if (EnumHelper.IsValidForEnumHelper(ViewData.ModelMetadata))
{
    string displayAttrName = null;
    foreach (SelectListItem item in EnumHelper.GetSelectList(ViewData.ModelMetadata, (Enum)Model))
    {
        if (item.Selected)
        {
            displayAttrName = item.Text ?? item.Value;
        }
    }

    // displayAttrName is not assigned to any value
    if (String.IsNullOrEmpty(displayAttrName))
    {
        if (Model == null)
        {
            displayAttrName = String.Empty;
        }
        else
        {
            displayAttrName = Model.ToString();
        }
    }

    @Html.DisplayTextFor(model => displayAttrName)
}
else
{
    @Html.DisplayTextFor(model => model)
}

Make sure that above Partial View enum.cshtml is created in EditorTemplates folder under the Shared directory.

So if we see the above code, then we find that EnumHelper.IsValidForEnumHelper is used to check that whether the passed value is of enum type and the other one EnumHelper.GetSelectList which returns the list of items in SelectListItem type as discussed.

Now let’s us create the partial view for Edit purposes as

@model Enum

@if (EnumHelper.IsValidForEnumHelper(ViewData.ModelMetadata))
{
    @Html.EnumDropDownListFor(model => model, htmlAttributes: new { @class = "form-control" })
}
else
{
    @Html.TextBoxFor(model => model, htmlAttributes: new { @class = "form-control" })
}

This partial view also should be in EditorTemplates folder under the Shared directory. Here again the new helper method EnumHelper.IsValidForEnumHelper which tells whether the provided model data is of type enum or not. When it is of type enum then it uses @Html.EnumDropDownListFor else uses normal @Html.TextBoxFor

Now let’s see the Create/Edit views and here we have not used
@Html.EnumDropDownListFor instead used normal @Html.EditorFor which uses the display and edit templates that we created

   @Html.EditorFor(model => model.Area)

Now let’s run the application, in create page looks like

Part2-1

and after adding Index look as

part2-2Here the earlier issue is resolved and we are able to see the consistent values on diffrent CRUD screen. We can write the similar custom code in other scenarios as well.

Happy learning,
Brij

Advertisements

Enums support in ASP.NET MVC 5.1- Part 1

Hello All,

Recently Microsoft releases a second update for Visual Studio 2013 named Visual Studio Update 2 RC. Here RC means that it is in Release candidate version  and you may expect few changes in the final version. But there are a list of changes they provided in ASP.NET MVC and Webforms that will be going to help a lot in your day to day coding. The new version of ASP.NET MVC is named as ASP.NET MVC5.1. In few of my coming posts, I’ll be discussing the major changes in ASP.NET MVC with examples.

So in this post, We’ll discuss few features of ASP.NET MVC5.1. ASP.NET MVC provides scaffolding that enables us to create the controller and views for our model. The controls on views are rendered based on the type of properties in the model but it is not true for all types. Say if you have property in your which is of type Enum then the UI generate the normal textbox for it which allows to enter free text which may become brutal to your application if it is not handled properly. To handle this scenario, I discuss that in one my old post, how you can extend EditorFor for custom type. You can refer the link

Html.EditorFor – Extend for custom type

But it requires lots of steps and require to handle various scenarios like displaying, editing etc which is error prone as well. Let’s take the same earlier example, I took a class as

    public class Speaker
    {
        public int Id { get; set; }

        public string Name { get; set; }

        public bool IsAvailable { get; set; }

        public ExpertiseArea Area { get; set; }
    }

The enum type ExpertiseArea is defined as

    public enum ExpertiseArea
    {
        ASPNET,
        Csharp,
        WindowsAzure,
        WCF
    }

Now when I created the Controller and Views via scaffolding as

Controller

and

addcontroller

and It created the controller and related views. Now lets run the application so it looks like as

page

Great!! Now you can see that expertise area is rendered as dropdown without any specific code. That’s fantastic.

Now let’s have a look on the cshtml page itself

 @Html.EnumDropDownListFor(model => model.Area, htmlAttributes: new { @class = "form-control" })

So here, we find that there is a new helper method EnumDropDownListFor got introduced that is used for enum types. And this is used for on Create and Edit views because these views only allows user to edit or enter new data. Rest of the views are same as earlier.

This is very good feature that will help a lot to developers.For simple scenario it is fine, so let us discuss another scenario, where we dont want to show the actual enum value but we want to show some different value on the UI. So let’s add display attribute in enum as

    public enum ExpertiseArea
    {
        [Display(Name = "ASP.NET")]
        ASPNET,
        [Display(Name = "C#")]
        Csharp,
        [Display(Name = "Windows Azure")]
        WindowsAzure,
        WCF
    }

Now again, let’s run the application and see the create page

part1-1It seems great, the value that populated in dropdown is what we put in display attribute. That’s what we want. Let’s add it and see the index page

part1-2Ohh.. this we did not expect. We expected that it should be C#. It means that it cannot be handled without just by simple scaffolding but it is required some custom code.

We’ll discuss this scenario in next part. Stay tuned!

Cheers,
Brij