What is this post about?

If you use Umbraco and you create forms using MVC and razor, perhaps a contact form, you might want to populate a dropdownlist with data controlled by the Umbraco backoffice. This post shows you how to do that.

You can now watch the video of me implementing this

Watch on YouTube

1. Create an Umbraco Data type

In the Developer tab of Umbraco, click on the dots next to Data Types and create a new data type. Enter a name and choose dropdown list as the property editor.

Add the values you want to appear in the dropdown list. Then click on Save.

After you have pressed save, make a note of the id at the end of the url.

2. Add this helper class to your project

using System;
using System.Collections.Generic;
using System.Xml.XPath;
using System.Web.Mvc;
using System.Web.Configuration;
namespace CodeShare.Library.Helpers {     public class PreValueHelper     {         public List<SelectListItem> GetPreValuesFromDataTypeId(int dataTypeId)         {             List<SelectListItem> preValueSelectorList = new List<SelectListItem>();
            XPathNodeIterator iterator = umbraco.library.GetPreValues(dataTypeId);             iterator.MoveNext();             XPathNodeIterator preValues = iterator.Current.SelectChildren("preValue", "");
            while (preValues.MoveNext())             {                 string preValueIdAsString = preValues.Current.GetAttribute("id", "");                 int preValueId = 0;                 int.TryParse(preValueIdAsString, out preValueId);                 string preValue = preValues.Current.Value;                 preValueSelectorList.Add(new SelectListItem { Value = preValue, Text = preValue }); //you could use the preValueId for the value here if you want the value to be a number             }
            return preValueSelectorList;         }     } }

3. Include some extra methods for retrieving your data type id from app settings.

You could save the id of the data type in your web.config app settings. These methods will help you with that

using System;
using System.Collections.Generic;
using System.Xml.XPath;
using System.Web.Mvc;
using System.Web.Configuration;
namespace CodeShare.Library.Helpers {     public class PreValueHelper     {         private const string APP_SETTING_ERROR_MESSAGE = "Invalid or missing appSetting, ";
        public List<SelectListItem> GetPreValuesFromDataTypeId(int dataTypeId)         {             List<SelectListItem> preValueSelectorList = new List<SelectListItem>();
            XPathNodeIterator iterator = umbraco.library.GetPreValues(dataTypeId);             iterator.MoveNext();             XPathNodeIterator preValues = iterator.Current.SelectChildren("preValue", "");
            while (preValues.MoveNext())             {                 string preValueIdAsString = preValues.Current.GetAttribute("id", "");                 int preValueId = 0;                 int.TryParse(preValueIdAsString, out preValueId);                 string preValue = preValues.Current.Value;                 preValueSelectorList.Add(new SelectListItem { Value = preValue, Text = preValue });             }
            return preValueSelectorList;         }         public List<SelectListItem> GetPreValuesFromAppSettingName(string appSettingName)         {             int dataTypeId = GetIntFromAppSetting(appSettingName);             List<SelectListItem> preValues = GetPreValuesFromDataTypeId(dataTypeId);             return preValues;         }
        private int GetIntFromAppSetting(string appSettingName)         {             int intValue = 0;             string setting = GetStringFromAppSetting(appSettingName);             if (!int.TryParse(setting, out intValue))             {                 throw new Exception(APP_SETTING_ERROR_MESSAGE + appSettingName);             }             return intValue;         }
        private string GetStringFromAppSetting(string appSettingName)         {             string setting = WebConfigurationManager.AppSettings[appSettingName] as string;             if (String.IsNullOrEmpty(setting))             {                 throw new Exception(APP_SETTING_ERROR_MESSAGE + appSettingName);             }             return setting;         }
    } }

4. Add a property in your model, using the type List<SelectListItem>

In this example, my model has a list of titles.

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

namespace CodeShare.Library.Models
{
    public class ContactModel
    {

        [Display(Name = "Title:")]
        public string Title { get; set; }

        public List<SelectListItem> Titles { get; set; }
    }
}

5. Use the helper in the controller to load the values from the data type.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Umbraco.Web.Mvc;
using CodeShare.Library.Models;

namespace CodeShare.Web.Controllers {     public class ContactController : SurfaceController     {
        private PreValueHelper preValueHelper => new PreValueHelper();
        private string GetViewPath(string name)         {             return $"~/Views/Partials/Apply/{name}.cshtml";         }
        [HttpGet]         public ActionResult RenderContactForm()         {             ContactModel model = new ContactModel();             SetModelData(model);             return PartialView(GetViewPath("_ApplicantDetails"), model);         }
        [HttpPost]         public ActionResult RenderContactForm(ContactModel model)         {             SetModelData(model);             return PartialView(GetViewPath("_ContactForm"), model);         }
        [HttpPost]         public ActionResult SubmitContactForm(ContactModel model)         {             if(ModelState.IsValid)             {                 //Do something                 return RedirectToCurrentUmbracoPage();             }             return CurrentUmbracoPage();         }
        private void SetModelData(ContactModel model)         {             model.Titles = preValueHelper.GetPreValuesFromAppSettingName("TitlesDataTypeId");         }     } }

6. Render the dropdown list in your razor partial view in the form

@using CodeShare.Library.Models
@model ContactForm
@using (Html.BeginUmbracoForm("SubmitContactForm", "Apply")) {     @Html.AntiForgeryToken()
    @Html.LabelFor(m => m.Title)     @Html.DropDownListFor(m => m.Title, Model.Titles, "Please Select...")     @Html.ValidationMessageFor(m => m.Title)
    <button>Submit</button> }

That's it, all done

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.
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.
uSkinned

  • More than a theme for Umbraco CMS, take full control of your content and design with a feature-rich, award-nominated & content editor focused website platform.
UmbHost

  • Affordable, Geo-Redundant, Umbraco hosting which gives back to the community by sponsoring an Umbraco Open Source Developer with each hosting package sold.