【问题标题】:Kendo Grid - Datasource Update not hitting controllerKendo Grid - 数据源更新未命中控制器
【发布时间】:2023-03-07 18:43:01
【问题描述】:

首先:我为此找到了几个问题,到目前为止,没有一个答案对我有用。事实上,我还没有找到接受的答案!

我有一个 MVC 4 应用程序、一个 cshtml 页面和它下面的几层局部视图。

主视图(剑道标签,无表单元素,在标签 #1 上向下钻取):

<div class="container-fluid" style="margin-left: 10px; margin-right: 10px; padding-right: 30px;">
    @(Html.Kendo().TabStrip()
            .Name("tabStrip")
            .Events(e => e.Select("tabstrip_select"))
            .Items(items =>
            {
                items.Add()
                     .Text("Clone Assembly")
                     .Selected(true)
                     .Content(@<text>@Html.Partial("_Assembly", Model)</text>);
                items.Add()
                     .Text("Submit")
                     .Visible(@Model.Status == (int)SessionStatuses.Started)
                     .HtmlAttributes(new { userWorkSessionId = Model.UserWorkSessionId })
                     .LoadContentFrom("_AssemblyStarted", "ProductReuse", new { userWorkSessionId = Model.UserWorkSessionId });
                items.Add()
                     .Text("Session Results")
                     .Visible(@Model.Status >= (int)SessionStatuses.Submitted)
                     .HtmlAttributes(new { userWorkSessionId = Model.UserWorkSessionId })
                     .LoadContentFrom("_AssemblySubmitted", "ProductReuse", new { userWorkSessionId = Model.UserWorkSessionId });
            })
    )
</div>

_assembly 局部视图(剑道网格):

@using (Html.BeginForm("Assembly", "ProductReuse", FormMethod.Post, new {id = "frmStartScreen"}))
{
    @Html.HiddenFor(m => m.Status)
    @Html.HiddenFor(m => m.UserWorkSessionId)

    <div class="row">
        <div class="panel panel-info">
            <div class="panel-heading">
                <div class="panel-heading text-center">
                    <h2 class="pr">@string.Format("{0} | {1} | {2}", Model.GlobalPartNum, Model.CloneScopeDisplay, Model.StatusDisplay)</h2>
                </div>
            </div>
            <div class="panel-body" style="margin-bottom: 10px; margin-top: 10px;">
                <div class="row">
                    @(Html.Kendo().Grid<BomViewModel>()
                          .Name("bom-prGrid-kendoGrid")
                          .HtmlAttributes(new {@class = "prGrid"})
                          .ClientRowTemplate("")
                          .Columns(columns =>
                          {
                              if (Model.StatusDisplay.Equals("Started"))
                              {
                                  columns.Command(cmd => cmd.Edit()).Width(80);
                              }
                              columns.Bound(g => g.BomId).Hidden();
                              columns.Bound(g => g.IsEditable).Hidden();
                              columns.Bound(g => g.Row).Width(75).Title("Row");
                              columns.Bound(g => g.PartNum).Width(125).Title("DWG/<br/>Part No");
                              columns.Bound(g => g.Qty).Width(80).HtmlAttributes(new {style = "text-align:center"}).Title("Qty");
                              columns.Bound(g => g.ItemDesc).Width(350).Title("Description");
                          })
                          .DataSource(dataSource => dataSource
                              .Ajax()
                              .Model(model =>
                              {
                                  model.Id(g => g.Row);
                                  model.Field(m => m.Row).Editable(false);
                              })
                              .PageSize(100)
                              .Read(r => r.Action("GetCloneAssembly", "AjaxProductReuse").Data("ProductReuseGridReadData"))
                              .Update(u => u.Action("UpdateBomItem", "AjaxProductReuse").Type(HttpVerbs.Post))
                              .Events(e => e.Error("ajax_error").Sync("dataSource_sync").Change("dataSource_change"))
                          )
                          .Events(e => e.DataBound("onDataBound").Edit("onEdit"))
                          .Pageable(pager => pager
                              .Input(true)
                              .Numeric(true)
                              .Info(true)
                              .PreviousNext(true)
                              .Refresh(true)
                              .PageSizes(new int[] {100, 250, 500, 1000})
                          )
                          .ToolBar(toolbar =>
                          {
                          toolbar.Template(
                                  @<text>
                                      <div class="container-fluid otherElements" style="padding-top: 5px; padding-bottom: 5px;">
                                          @Html.Partial("_CloneAssembly", Model)
                                      </div>
                                   </text>);
                          })
                          .Excel(excel => excel.FileName("ClonableBom.xlsx").Filterable(true).AllPages(true).ProxyURL(Url.Action("ExcelProxy", "AjaxProductReuse")))
                          .Sortable()
                          .Scrollable()
                          .Filterable()
                          //.Editable(editable => editable.Mode(GridEditMode.PopUp).TemplateName("BOMForm").Window(w => w.Title("Manage BOM Item").Name("BOMForm")))
                          .Editable(editable => editable.Mode(GridEditMode.PopUp).TemplateName("BOMForm"))
                          .Resizable(resizing => resizing.Columns(true)).Reorderable(reorder => reorder.Columns(true))
                          )
                </div>
            </div>
        </div>
    </div>
}

控制器(获取/发布主页):

[HttpGet]
public ActionResult Assembly(int userWorkSessionId = int.MinValue)
{
    var response = GetCachedCurrentWorkSession(userWorkSessionId);
    return View(response);
}

[HttpPost]
public ActionResult Assembly(AssemblyViewModel command)
{
    var saveServiceCommand = _mapper.Map<WorkSessionModel>(command);
    var serviceResponse = _productReuseService.ApplyGlobalSettingsCommand(saveServiceCommand);
    var response = SaveCachedCurrentWorkSession(serviceResponse);

    return View(response);
}

Ajax 控制器(处理数据源读取和更新):

[HttpPost]
public JsonResult UpdateBomItem([DataSourceRequest] DataSourceRequest request, [Bind(Prefix = "models")]BomViewModel bomViewModel)
{
    var command = _mapper.Map<BomModel>(bomViewModel);
    var commandResponse = _productReuseService.UpdateBomItem(command);
    var response = _mapper.Map<List<BomViewModel>>(commandResponse);
    return Json(ToDataSourceResult(response, request, modelState: ModelState));
}

与 Telerik 网站上的几个演示相比,一切看起来都不错。但是,当我提交更新的弹出表单时,我出现了奇怪的行为:

在这两种情况下,Ajax 调用从未在我的代码中中断(即:没有证据表明它实际上进入了该方法!)当我在 Assembly POST 方法中中断时,模型是空的,已初始化但为空。

看起来它在第二个实例中所做的是将网格中的 每一 行发送到主操作方法而不是 ajax 处理程序。而且,最重要的是,跟踪中的 401 错误行看起来像是在命中 GET 而不是 POST 并被拒绝,因为 GET 只需要一个 INT。

我们中的几个人现在都在研究这个问题,但我们都不知道是什么导致了这种行为。

有什么想法吗?

【问题讨论】:

  • HTTP 状态码 401 与 IIS 服务器上的网站配置有关。 Web 服务器返回 401,而不是您的代码。
  • 另外,如果不指定ajax类型,相信Kendo Datasource会默认为GET
  • 对于数据源更新,ajax类型设置为POST。
  • 是否调用了正确的 URL - ProductReuse/ProductReuse/Assembly?userWorkSession=45?那是您的控制器方法。如果您尝试使用 Postman 或 Fiddler 等工具调用控制器会发生什么?
  • 那是主页的控制器和动作。当我提交表单(通过提交按钮)时,它按预期工作。当我提交弹出表单时,失败的调用是 ProductReuse/AjaxProductReuse/UpdateBomItem 调用。

标签: c# asp.net-mvc asp.net-mvc-4 kendo-grid kendo-asp.net-mvc


【解决方案1】:

我最终更改了数据源上的 id 绑定:

.Model(model =>
{
    model.Id(g => g.Row);
    model.Field(m => m.Row).Editable(false);
})

改为:

.Model(model => 
{ 
    model.Id(g => g.BomId); 
})

这解决了它。虽然 Row 是集合上的唯一 int,但 BomId 是数据库中定义的 PK。为什么这应该有所作为我不知道。但是,即使 Kendo(和支持模型)对 PK 一无所知,它也确实如此,因为它是一个没有实体信息的 POCO。

如果你们中的任何人知道为什么这会影响它,我会对解释非常感兴趣!

【讨论】:

  • 很高兴您找到了答案。您应该考虑接受这个作为答案,因为它解决了您的问题。
  • 我打算。 24 小时内不允许选择它作为答案。
  • 我不知道这个限制。很高兴知道。
猜你喜欢
  • 2021-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-14
  • 1970-01-01
相关资源
最近更新 更多