DropDownListFor selected value returns null in the Enum property Model on form POST in ASP.Net Core MVC

107 Views Asked by At
I have a form page with DropDownlistFor or select as below:

<select asp-for="LeaveType" 
         class="form-control" style="max-width:180px" 

         asp-items="@Html.GetEnumOcp_SelectList<LeaveType>(LeaveType.List, null)">

         <option selected="selected" value="">Please select</option>
 </select> 

I have a viewModel with following property:

public LeaveType LeaveType { get; set; }

this is my enum model:

public class LeaveType(int value, string name) : Enumeration<LeaveType>(value, name)
{
    public static readonly LeaveType AnnualLeave = new(1, "AnnualLeave");
    public static readonly LeaveType SickLeave = new(2, "SickLeave");
    public static readonly LeaveType CompassionateLeave = new(3, "CompassionateLeave");
    public static readonly LeaveType UnpaidLeave = new(4, "UnpaidLeave");
}

I have htmlExtension :

public static SelectList GetEnumOcp_SelectList<TEnum>(this IHtmlHelper html,
        IReadOnlyCollection<TEnum> isValueUsedForValue, TEnum? selectedValue)
        where TEnum : LeaveType
    {
        var myList = isValueUsedForValue.Select(eachValue => new SelectListItem
        {
            Text = eachValue.Text,
            Value = eachValue.Value.ToString(),
            Selected = eachValue.Equals(selectedValue)

        }).ToList();

        return new SelectList(myList, "Value", "Text");        
    }

in Index HttpGet action, I have expected LeaveTypes values but When I do post my from (ViewModel) with DropDownList or Select to the controller I have all values except LeaveType property value which is null. Just be aware my enum (LeaveType) is not a struct type that is class.


        [HttpGet]
        public IActionResult Index()
        {
            Logger.LogInformation("Leave Index started");

            // Populate the form on the first visit
            var model = new LeaveViewModel(); // You can initialize with any default data if needed
            return View(model);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Index(LeaveViewModel model)
        {
            if (model == null) return NotFound();
            
            if (!ModelState.IsValid)
            {
                return View(model);
            }     
            return RedirectToAction(nameof(Index));
        }

Anyone know why LeaveType property get Null value when I submit the ViewModel to index post action. all fields values have passed successfully except LeaveType. Thanks

3

There are 3 best solutions below

2
KHAL On

Try returning them as a SelectList

public static SelectList GetEnumOcp_SelectList<TEnum>(this IHtmlHelper html,
    IReadOnlyCollection<TEnum> isValueUsedForValue, TEnum? selectedValue)
    where TEnum : LeaveType
{
    var myList = isValueUsedForValue.Select(eachValue => new SelectListItem
    {
        Text = eachValue.Name,
        Value = eachValue.Value.ToString(),
        Selected = eachValue.Equals(selectedValue)

    }).ToList(); 

    return New SelectList(myList, "Value", "Text");

}
4
Qing Guo On

Below is a work demo based on your code, you can refer to it.

Add a string type property in LeaveViewModel to bind selected value(if selected value is int type, you need to set the int LeaveType), as the select value based on your comment code is string ,I set string LeaveType:

public class LeaveViewModel
 {
     public string LeaveType { get; set; }
 }

the select:

<select id="LeaveType" name="LeaveType">                 
    <option selected="selected" value="">Please select</option>          
    <option value="1">AnnualLeave</option>
    <option value="2">SickLeave</option> 
    <option value="3">CompassionateLeave</option> 
    <option value="4">UnpaidLeave</option> </select>

result:

enter image description here

1
Jaydev Kanzariya On
•   Create datatype enum and add value
     public enum AnyName{
    data1,
    data2,
    data3
       }        
•   And than create class  by using enum data type
public class YourModel
{
    public AnyName   EnumProperty { get; set; }
}
•   Use enum value in  dropdown according this 
<select name="EnumProperty">
    <option value="data1">data1</option>
    <option value="data2">data2</option>
    <option value="data3">3</option>
</select>

•   And save data in database in controller by using post method 
               [HttpPost]
public IActionResult  YourAction(YourModel model)
{
    if (ModelState.IsValid)
    {
        // Process the model
        return RedirectToAction("Success");
    }
    // If ModelState is not valid, return the view with errors
    return View(model);
}