In this post I share the code I wrote to get the values from dropdowns and it can be used for checkbox lists and radio button lists too.

Some background

Recently I was asked to build a membership registration and login flow for a client. The client was Tarik from Creativaholic Studio. Tarik has kindly agreed for me to share some of the code I wrote for this, as it solves some interesting problems I encountered along the way.

In this project, I needed to have properties on the member profile which used the dropdown list, checkbox list and radio button list datatypes.

And I needed to be able to edit them in the edit profile screen.

So what I had to do was get the values from the dropdown datatype in the backoffice and use them to load an Html.DropdownList in the form on the front end.

Dropdown data type

In order to get the values from the datatype I decided to put the code in a service to make it reusable and allow it to be used with dependency injection.

I created a service called DataTypeValueService.

IDataTypeValueService Interface

First I created an interface for it:

using System.Collections.Generic;
using System.Web.Mvc;

namespace CodeShare.Core.Services
{
    public interface IDataTypeValueService
    {
        IEnumerable<SelectListItem> GetItemsFromValueListDataType(string dataTypeName, string[] selectedValues);
    }
}

DataTypeValueService Class

Next I created the implementation for the interface:

using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Services;

namespace CodeShare.Core.Services
{
    public class DataTypeValueService : IDataTypeValueService
    {
        private readonly IDataTypeService _dataTypeService;

        public DataTypeValueService(IDataTypeService dataTypeService)
        {
            _dataTypeService = dataTypeService;
        }

        public IEnumerable<SelectListItem> GetItemsFromValueListDataType(string dataTypeName, string[] selectedValues)
        {
            IEnumerable<SelectListItem> items = null;

            var dataTypeConfig =
                (ValueListConfiguration)_dataTypeService.GetDataType(dataTypeName).Configuration;


            if (dataTypeConfig?.Items != null && dataTypeConfig.Items.Any())
            {
                items =
                    dataTypeConfig.Items.Select(x => new SelectListItem()
                    {
                        Text = x.Value,
                        Value = x.Value,
                        Selected = selectedValues != null && selectedValues.Contains(x.Value)
                    });
            }

            return items;
        }
    }
}

Now we have a method where we can get the options from the data type as an IEnumerable of SelectListItem. The good thing about using this as a result set is that each item can have Text, Value and Selected properties.

View Model

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;

namespace CodeShare.Core.Models.ViewModels
{
    public class EditProfileViewModel
    {
        [Display(Name = "Job Title")]
        public string JobTitle { get; set; }

        public IEnumerable<SelectListItem> JobTitleOptions { get; set; }
    }
}

We can now call this code from our controller to load the values into our JobTitleOptions property on our view model.

Register the service for Dependency Injection usage

using CodeShare.Core.Services;
using Umbraco.Core;
using Umbraco.Core.Composing;

namespace CodeShare.Core.Composing
{
    [RuntimeLevel(MinLevel = RuntimeLevel.Run)]
    public class RegisterServicesComposer : IUserComposer
    {
        public void Compose(Composition composition)
        {
            composition.Register(typeof(IDataTypeValueService),
                typeof(DataTypeValueService), Lifetime.Request);
        }
    }
}

Controller with Dependency Injection

using CodeShare.Core.Models.ViewModels;
using CodeShare.Core.Services;
using System.Web.Mvc;
using Umbraco.Web.Mvc;

namespace CodeShare.Core.Controllers.Surface
{
    public class AccountSurfaceController : SurfaceController
    {
        private readonly IDataTypeValueService _dataTypeValueService;

        public AccountSurfaceController(IDataTypeValueService dataTypeValueService)
        {
            _dataTypeValueService = dataTypeValueService;
        }

        [HttpGet]
        public ActionResult RenderEditProfile()
        {
            var model = new EditProfileViewModel();

            model.JobTitleOptions =
                _dataTypeValueService.GetItemsFromValueListDataType("[Dropdown] Job Titles", selectedValues: null);

            return PartialView("~/Views/Partials/Membership/_EditProfile.cshtml", model);
        }
    }
}

Using this in the Html.DropDownList

@Html.DropDownListFor(x => x.JobTitle, Model.JobTitleOptions, "Please select..")

This will now load the dropdown for you on the front end.

If you need help with the implementation of this, you can get in touch with me on LinkedIn

Paul Seal

Umbraco MVP and .NET Web Developer from Derby (UK) who specialises in building Content Management System (CMS) websites using MVC with Umbraco as a framework. Paul is passionate about web development and programming as a whole. Apart from when he's with his wife and son, if he's not writing code, he's thinking about it or listening to a podcast about it.

Proudly sponsored by

Moriyama

  • Moriyama build, support and deploy Umbraco, Azure and ASP.NET websites and applications.
AppVeyor

  • CI/CD service for Windows, Linux and macOS
  • Build, test, deploy your apps faster, on any platform.
stkrs

  • Custom stickers for startups, artists and brands.
  • Bespoke easy-apply, removable, custom brand stickers printed in the UK.
elmah.io

  • elmah.io is the easy error logging and uptime monitoring service for .NET.
  • Take back control of your errors with support for all .NET web and logging frameworks.
uSync Complete

  • uSync.Complete gives you all the uSync packages, allowing you to completely control how your Umbraco settings, content and media is stored, transferred and managed across all your Umbraco Installations.