how to configure dropdownlist to return the Title and not id back to the database

Ken Peck 1 Reputation point
2022-08-08T18:19:02.487+00:00

I have an asp.net mvc using entity framework web app. A specific table in the app has a text column we want to force users to select entries from a dropdown to avoid spelling issues. There are only two selections, Buy Item and Raw Components. We don't want to go through the trouble of creating an actual table and then relate that table with the original. When creating a new record or editing an existing record I would like to have the selected Text and not the selected ID saved in the record. The reason for this is there are many records in the table already AND a report deck associated with the table that would all have to be updated if the ID was saved back to the record. In the examples I've included below, you see I've used the ViewBag method although the Model method (for me) has the same issues.

To start I created a class

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Web;  
  
namespace ProdMan4.Models  
{  
public class ItemTypes  
{  
public int Id { get; set; }  
public string Title { get; set; }  
}  
  
}  

Added the following to the controller for the table...

private List<ItemTypes> GetITs()  
{  
var itemtypes = new List<ItemTypes>();  
itemtypes.Add(new ItemTypes() {Id = 1, Title = "Buy Item" });  
itemtypes.Add(new ItemTypes() {Id = 2, Title = "Raw Components" });  
  
return itemtypes;  
  
}  
  
public ActionResult Create()  
{  
ViewBag.ItemTypesSelectList = new SelectList(GetITs(),"Id", "Title");  
return View();  
}  

Then Added the dropdown on the Create View as follows...

<div class="form-group">  
@Html.LabelFor(model => model.ItemType, htmlAttributes: new { @class = "control-label col-md-2" })  
<div class="col-md-10">  
@Html.DropDownList("Title", ViewBag.ItemTypesSelectList as SelectList, "Select Type", new { @class = "form-control" })  
@Html.ValidationMessageFor(model => model.ItemType, "", new { @class = "text-danger" })  
</div>  
</div>  

I have (at least) two issues.

  1. I can create a new item but it saves the ID to the SQL table
  2. The edit view, while setup just like the create view for this column, throws the following error.

System.InvalidOperationException: 'The ViewData item that has the key 'Id' is of type 'System.Int32' but must be of type 'IEnumerable<SelectListItem>'.'

At this point I'm a bit lost. Any direction would be appreciated.

ASP.NET
ASP.NET
A set of technologies in the .NET Framework for building web applications and XML web services.
3,248 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,221 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. AgaveJoe 26,191 Reputation points
    2022-08-08T18:42:54.62+00:00

    An HTML select's selected value is submitted not the text. If you want the text submitted then set the Id to the text value too. I assume you'll need to update the associated model (action input parameter) from an int to a string.

    private List<ItemTypes> GetITs()  
     {  
        var itemtypes = new List<ItemTypes>();  
        itemtypes.Add(new ItemTypes() {Id = "Buy Item", Title = "Buy Item" });  
        itemtypes.Add(new ItemTypes() {Id = "Raw Components", Title = "Raw Components" });  
          
        return itemtypes;  
          
     }  
    
     public class ItemTypes  
     {  
     public string Id { get; set; }  
     public string Title { get; set; }  
     }  
    

    HTML <select> Tag

    Also, you could populate a List<SelectListItem> rather than building a custom ItemTypes type.

    https://learn.microsoft.com/en-us/dotnet/api/system.web.mvc.selectlistitem?view=aspnet-mvc-5.2

    Example

        public class ViewModel  
        {  
            public string SelectedOption { get; set; }  
        }  
        public class BasicFormsController : Controller  
        {  
            // GET: BasicForms  
            [HttpGet]  
            public ActionResult Index()  
            {  
                ViewBag.Options = PopulateOptions();  
                return View();  
            }  
      
            [HttpPost]  
            public ActionResult Index(ViewModel model)  
            {  
                ViewBag.Options = PopulateOptions();  
                return View(model);  
            }  
      
            private List<SelectListItem> PopulateOptions()  
            {  
                List<SelectListItem> options = new List<SelectListItem>()  
                {  
                    new SelectListItem()  
                    {  
                        Text = "Buy Item",  
                        Value = "Buy Item"  
                    },  
                    new SelectListItem()  
                    {  
                        Text = "Raw Components",  
                        Value = "Raw Components"  
                    }  
                };  
                return options;  
            }  
        }  
    

    View

    @model MvcBasic.Controllers.ViewModel  
      
    @{  
        ViewBag.Title = "Index";  
        Layout = "~/Views/Shared/_Layout.cshtml";  
    }  
      
    <h2>Index</h2>  
      
    @using (Html.BeginForm())   
    {  
        @Html.AntiForgeryToken()  
          
        <div class="form-horizontal">  
            <h4>ViewModel</h4>  
            <hr />  
            <div class="form-group">  
                <div class="col-md-10">  
                    <div class="checkbox">  
                        @Html.DropDownListFor(model => model.SelectedOption, (List<SelectListItem>)ViewBag.Options)  
                    </div>  
                </div>  
            </div>  
      
            <div class="form-group">  
                <div class="col-md-offset-2 col-md-10">  
                    <input type="submit" value="Submit" class="btn btn-default" />  
                </div>  
            </div>  
        </div>  
    }  
    
    0 comments No comments

  2. Lan Huang-MSFT 25,471 Reputation points Microsoft Vendor
    2022-08-09T09:38:02.823+00:00

    Hi @Ken Peck ,

    1. I can create a new item but it saves the ID to the SQL table

    I tested it based on the code you provided and I think you can set both dataValueField and dataTextField to "Title".

      ViewBag.ItemTypesSelectList = new SelectList(GetITs(), "Title", "Title");  
    

    229505-1.jpg

    The edit view, while setup just like the create view for this column, throws the following error.

    The error indicates the select options are empty.
    Demo

     private List<ItemTypes> GetITs()  
            {  
                var itemtypes = new List<ItemTypes>( );  
                itemtypes.Add ( new ItemTypes ( )  { Id = 1, Title = "Buy Item" });  
                itemtypes.Add ( new ItemTypes ( ) { Id = 2, Title = "Raw Components" });  
                return itemtypes;  
            }  
            [HttpGet]  
            public ActionResult Create()  
            {  
                ViewBag.ItemTypesSelectList = new SelectList ( GetITs ( ), "Title", "Title");  
                return View();  
            }  
            [HttpPost]  
            public ActionResult Create(ItemTypes itemTypes)  
            {  
                ViewBag.ItemTypesSelectList = new SelectList ( GetITs ( ), "Title", "Title");  
                return View(itemTypes);  
            }  
    

    public class ItemTypes  
        {  
            public int Id { get; set; }  
            public string Title { get; set; }  
        }  
    

    @model WebApplication5.Models.ItemTypes  
      
    @using (Html.BeginForm("Create", "Home", FormMethod.Post))  
    {  
        <div class="form-group">  
            @Html.LabelFor(model => model.Title, htmlAttributes: new { @class = "control-label col-md-2" })  
            <div class="col-md-10">  
                @Html.DropDownList("Title", ViewBag.ItemTypesSelectList as SelectList, "Select Type", new { @class = "form-control" })  
                @Html.ValidationMessageFor(model => model.Title, "", new { @class = "text-danger" })  
            </div>  
            <input type="submit" value="Submit" class="btn btn-default" />  
        </div>  
    }  
    

    229418-2.jpg
    Best regards,
    Lan Huang


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments