Grid - Command Button "Edit" leads to Insert Action instead of Update Action in Controller

0 Answers 135 Views
Grid
Felix
Top achievements
Rank 1
Iron
Felix asked on 05 Jun 2023, 09:18 AM | edited on 28 Dec 2023, 09:30 AM

Hi,

I fail to figure out a problem

I have a Kendo Grid, that has a ClientDetailTemplate that creates a Tab Strip for each row, in each Tab Strip Item there is a Child Grid
Now I added a new Tab Strip Item with a new Child Grid, but everytime I edit a Row, it sends an Insert Action to the Controller instead of an Edit Action

If I debug the base controller, the model that is send to the Insert Action in the controller is valid

With all other Grids (in the other Tab Strip Items) it seems to work just fine (Edit leads to Update Action)
If I remove the Action for Insert/Create in the Child Grid it does not send any Action to the Controller

Is there a bug in my code? I just can't find out why it behaves like this.
I tried to search for it in the forum, but was not able to find something.

The Code is:
(Most columns removed)
(The grid that calls Insert instead of Update action is the first in the script tag, the second grid in the script component is for reference, where it works as expected)

@(Html.Kendo().Grid<CCPartnerTabDialogDto>()
    .Name("Grid_CCPartnerTabDialog")

    .Columns(columns =>
    {
        columns.Bound(c => c.FILIALID).Title("Fields").Width(200);
    })
    .DataSource(datasource => datasource
        .Ajax()
        .Read(read => read.Action("Read", "CCPartnerTabDialog"))

        .Filter(f => f.Add(val => val.RCDSTS).IsEqualTo(" "))

        .PageSize(30))
    .Filterable(filter => filter.Mode(GridFilterMode.Row))
    .Scrollable()
    .Height("750")
    .Sortable()
    .Reorderable(r => r.Columns(true))
    .Pageable()
    .Resizable(rs => rs.Columns(true))
    .ClientDetailTemplateId("Grid_CCPartnerTabDialog_HierarchyRowTemplate")
    .Events(events =>
    {
        events.DataBound("dataBound");
        events.DetailInit("CCPartnerTabDialogInit");
    }))

<script id="Grid_CCPartnerTabDialog_HierarchyRowTemplate" type="text/kendo-tmpl">

    @(Html.Kendo().TabStrip()
        .Name("TabStrip_CCPartnerTabDialog_Hierarchy_#=PID#")
        .Collapsible(true)
        .Items(tabs =>
        {
            tabs.Add().Text("Partner").Content(@<text>
                @(Html.Kendo().Grid<CCPartnerDto>()
                    .Name("Grid_CCPartner_Hierarchy_#=PID#")
                    .Columns(columns =>
                    {
                        columns.Bound(c => c.PID).Title("PID");
                        columns.Bound(c => c.ERPNME).Title("ERP");

                        columns.Command(command => { command.Edit(); });
                    })
                    .Width("600")
                    .DataSource(datasource => datasource
                        .Ajax()
                        .Model(model =>
                        {
                            model.Id(p => p.PID);
                            model.Field(p => p.ERPNME);
                            model.Field(p => p.SUBSFLAG);
                            model.Field(p => p.PROVFLAG);
                        })
                        .Read(read => read.Action("Read", "CCPartner", new { values = new string[] { "#=PID#" } }))

                        .Create(create => create.Action("Insert", "CCPartner"))
                        .Update(upd => upd.Action("Update", "CCPartner"))
                        .Destroy(del => del.Action("Delete", "CCPartner"))
                    )
                    .ToClientTemplate())
                </text>);

            tabs.Add().Text("Alias").Content(@<text>
                @(Html.Kendo().Grid<CCPartnerAliasDto>()
                .Name("Grid_CCPartnerAlias_Hierarchy_#=PID#")
                .Columns(columns =>
                {
                            columns.Bound(c => c.PID).Title("PartnerId").Width(200).Locked(true).Editable("notEditable");

                            columns.Command(command => { command.Edit(); command.Destroy(); });
                        })
                .ToolBar(toolbar => { toolbar.Create(); })
                .DataSource(datasource => datasource
                    .Ajax()

                    .Model(model =>
                    {
                        model.Id(p => p.PID);
                    })

                    .Read(read => read.Action("Read", "CCPartnerAlias", new { values = new string[] { "#=PID#" } }))

                    .Create(create => create.Action("Insert", "CCPartnerAlias"))
                    .Update(upd => upd.Action("Update", "CCPartnerAlias"))
                    .Destroy(del => del.Action("Delete", "CCPartnerAlias"))

                    .Filter(f => f.Add(val => val.RCDSTS).IsEqualTo(" "))

                    .PageSize(30))
                .Pageable()
                .Selectable()
                .Sortable()
                .Resizable(rs => rs.Columns(true))
                .ToClientTemplate())
                </text>);
        })
        .ToClientTemplate())


The Controller Base Class:
(where all three shown grid-controllers are derived from)

using Kendo.Mvc.Extensions;
using Kendo.Mvc.UI;
using Microsoft.AspNetCore.Mvc;
using WEB.BIM.DataLayer.Interface;
using WEB.BIM.DataLayer.Model.Application;
using WEB.BIM.DataLayer.Service;

namespace WEB.BIM.Controllers.Base
{
    public class ItemBaseController<TService, TModel> : BaseController<TService>
        where TService : IItemBaseService<TModel>
    {
        public ItemBaseController(ILogger logger, TService dataservice) : base(logger, dataservice)
        { }

        public async Task<ActionResult> Read([DataSourceRequest] DataSourceRequest request, params string[] values)
        {
            var result = await service.GetAsync(values);

            return Json(result.ToDataSourceResult(request));
        }
        public async Task<ActionResult> Insert([DataSourceRequest] DataSourceRequest request, TModel model)
        {
            if (model != null && ModelState.IsValid)
            {
                await service.InsertAsync(model, UserName());
            }

            return Json(new[] { model }.ToDataSourceResult(request));
        }
        public async Task<ActionResult> Update([DataSourceRequest] DataSourceRequest request, TModel model)
        {
            if(model != null && ModelState.IsValid)
            {
                await service.UpdateAsync(model, UserName());
            }

            return Json(new[] { model }.ToDataSourceResult(request));
        }
        public async Task<ActionResult> Delete([DataSourceRequest] DataSourceRequest request, TModel model)
        {
            if (model != null && ModelState.IsValid)
            {
                await service.DeleteAsync(model, UserName());
            }

            return Json(new[] { model }.ToDataSourceResult(request));
        }

    }
}

Any help appreciated

 

EDIT:

Huh, I just revisited my code and found the problem

1. The problem happens in hierarchical sub grids, because if i initialize the grids I set the DefaultValue of the id field to my parent id via js event like

    

// get detailGrids_subSelect

$.each(detailGrids_subSelect, function (index, value) { var tmp = value.getKendoGrid(); tmp.setOptions({ dataSource: { schema: { model: { fields: { PID: { defaultValue: e.data.PID } } } } } }) })

2. In another Grid where the id field is string i can just set it like this in datasource.model:

.Model(model =>
{
  model.Id(p => p.ALIASQLF);
  model.Id(p => p.ALIASVAL);
  model.Field(f => f.ALIASQLF).DefaultValue("#=ALIASQLF#");
})

Sadly the id field is a decimal and so i can not use the second approach, because it only allows string

Funny, that it works in the second part just fine, but in the first it recognizes, that the default value is equal to the id and then fires an insert instead of an update, if I exclude the grid in the first approach the update works as expected

But I will just remove the defaultValue in the first approach and do a custom create function where i set the parent id in the function or something like this

 

 

 

Felix
Top achievements
Rank 1
Iron
commented on 06 Jun 2023, 01:19 PM

Set 

.Create(create => create.Action("Insert", "CCPartnerAlias"))

to

.Create(create => create.Action("Update", "CCPartnerAlias"))

 

Hacky, but works

Aleksandar
Telerik team
commented on 08 Jun 2023, 04:47 AM

Hi Felix,

The reported behavior would occur if ID of the data item being edited is the same as the default value for the field, as defined via the Model configuration. For example, if the PID is an integer and you have a dataItem with PID of 0 (the default value) the changes made to the dataItem will be submitted to the Create endpoint instead of to the Update endpoint. I can suggest inspecting what data is submitted upon edit and checking if that is indeed the reason for the behavior.

Other than that, the Grid configurations and the endpoint configuration seem correct. If further assistance is required consider isolating the behavior in a sample application and sending it to us, either here or in a support ticket, so we can investigate further.

Felix
Top achievements
Rank 1
Iron
commented on 09 Jun 2023, 07:41 AM

Interesting..

I tried adding the PID as Field with DefaultValue 0, but it still leads to an "Create" Action.
The Object that is supplied to the controller has a PID Value

.Model(model =>
{
  model.Id(p => p.PID);
  model.Field(p => p.PID).DefaultValue(0);
})
I have this constellation more than once in the project but this behaviour happens only in one View - so I have no faith in reproducing it in a sample project.. Most probably a wrong code from me anywhere inbetween - but thanks for helping :)

No answers yet. Maybe you can help?

Tags
Grid
Asked by
Felix
Top achievements
Rank 1
Iron
Share this question
or