Search code examples
c#kendo-uikendo-gridkendo-asp.net-mvc

MVC Kendo Editable Grid not saving Enum value


I am currently creating my first Kendo grid. Almost everything is working, except that my Status enum and Code(basically an id) is not being passed to my controller on the Create action.

Here is my Kendo Grid (the parts that matter) -

             @(Html.Kendo().Grid<MyViewModel>()
                .Name("grid")
                .AutoBind(false)
                .HtmlAttributes(new { @class = "grid-clickable-edit" })
                .Columns(columns =>
                {
                    columns.Command(command =>
                    {
                        command.Edit().IconClass("fas fa-pencil").UpdateIconClass("fas fa-check").CancelIconClass("fas fa-ban");
                        command.Destroy().IconClass("fas fa-trash");
                    })
                        .ClientHeaderTemplate(Html.GridAddButton())
                        .Width(180);
                    //some fields
                    columns.Bound(model => model.Code)
                        .EditorTemplateName("GridDropdownEditor")
                        .EditorViewData(new {data = ViewBag.CodeList})
                        .ClientTemplate("#:Code#");
                    //some other fields
                    columns.Bound(model => model.StatusId)
                        .EditorTemplateName("StatusEditor");
                        .ClientTemplate("#:StatusName#");
                    //more fields
                })
                .Pageable(pg => pg.Numeric(false).PreviousNext(false))
                .Sortable()
                .Scrollable(scroll => scroll.Virtual(true))
                .Filterable(x => x.Enabled(false))
                .Editable(editable => editable.Mode(GridEditMode.InLine))
                .DataSource(dataSource => dataSource
                    .Ajax()
                    .Batch(true)
                    .ServerOperation(true)
                    .Model(model => { model.Id(m => m.Id); })
                    .Read(...)
                    .Create(update => update.Action(...))
                    .Update(update => update.Action(...))
                    .Destroy(update => update.Action(...))
                ))


The ViewBag.CodeList is a list of the Id of each Code, as well as the description. The dropdown basically shows the id and the description concatenated together.

GridDropdownEditor -

@model object

@(Html.Kendo().DropDownListFor(m => m)
            .DataTextField("Text")
            .DataValueField("Value")
            .BindTo((IEnumerable<SelectListItem>)ViewData["data"])
)

StatusEditor -

@using MyProject.Data.Models
@using MyProject.Helpers

@(Html.Kendo().DropDownListFor(m => m)
    .DataTextField("Text")
    .DataValueField("Value")
    .BindTo(EnumHelper<BidStatus>.ToSelectList())
    )
    )

The EnumHelper.ToSelectList() method basically gets the String and Id value from my Status Enum, and then puts it in a SelectList

Status Enum -

public enum Status
{
    Status1 = 1,
    Status2 = 2,
    Status3 = 3
}


MyViewModel(again, the parts that matter) -

public int? Code { get; set; }

public Status? StatusId { get; set; }

public string StatusName
{
    get { return StatusId.ToString(); }
}



The dropdowns for Status and Code get populated just fine, but they never actually get picked up by the grid and passed to the controller. FYI - The Code and Status fields have to be nullable. Let me know if any more info is required, and I would be happy to include it.

What I have tried
I attempted using the solutions from here - Kendo MVC grid with editable enum column, which did not work for me.


Solution

  • I believe the issue occurs because the drop down is bound to a collection of objects, thus, on the server, the binder fails to map the submitted object to an enum value.

    You could try to set the ValuePrimitive setting of the drop down to true, this way only the value field (Value) will be submitted to the server, not the whole object.

    e.g.

    @using MyProject.Data.Models
    @using MyProject.Helpers
    
    @(Html.Kendo().DropDownListFor(m => m)
        .DataTextField("Text")
        .DataValueField("Value")
        .ValuePrimitive(true)
        .BindTo(EnumHelper<BidStatus>.ToSelectList())
        )
        )
    

    Do the same for both drop downs.