【问题标题】:Kendo UI Grid: update/save not working (_AntiForgeryToken not present)Kendo UI Grid:更新/保存不起作用(_AntiForgeryToken 不存在)
【发布时间】:2017-08-18 11:42:08
【问题描述】:

我有一个显示合同附件的 KENDO 网格,其中有一列“状态”。在该列中显示附件/合同的当前状态。调用“编辑”事件时,单元格中会出现一个组合框,其中包含所有可用的状态选项。 选择状态并单击“更新”按钮后,出现以下异常:

The required anti-forgery form field "__RequestVerificationToken" is not present.

我在带有网格的视图中添加了@Html.AntiForgeryToken(),并将[ValidateAntiForgeryToken] 注释添加到我的方法中。

我在这里做错了什么?

这是网格:

@Html.AntiForgeryToken()
@(Html.Kendo().Grid<AttachmentGridViewModel>()

                                .Name("attachmentEditGrid")                                  
                                .HtmlAttributes(new
                                {
                                    style = "height:auto;",
                                    @class = "kendoHover"
                                })
                                .Columns(columns =>
                                {
                                    columns.Bound(c => c.number).Title(Resources.Number);
                                    columns.Bound(c => c.Consultant.FirstName).Title(Resources.Consultant);
                                    columns.Bound(c => c.StartDate).Title(Resources.StartDate).Format("{0:" + System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern + "}");
                                    columns.Bound(c => c.EndDate).Title(Resources.EndDate).Format("{0:" + System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern + "}");
                                    columns.Bound(c => c.Status).Title(Resources.Status).EditorTemplateName("ContractStatusEditor");
                                    columns.Command(command =>
                                    {
                                        command.Custom(Resources.Delete).Text("<span class=\"glyphicon glyphicon-remove padding-deletebutton \"></span>" + Resources.Delete).Click("onClickAttachmentDelete").HtmlAttributes(new { @class = "btn btn-danger" });
                                        command.Edit().Text(Resources.Edit).CancelText(Resources.Cancel);
                                    }).Title(Resources.Action).Width(200);
                                })
                                .ToolBar(toolBar => toolBar.Template("<a class='k-button k-button-icontext' href='/FA/ContractAttachment/CreateContractAttachment?contractId=1'><span class='glyphicon glyphicon-plus'></span>" + Resources.CreateAttachment + "</a>"))
                                //.Scrollable()
                                .Pageable(pageable => pageable
                                .Refresh(true)
                                .PageSizes(new List<object> { 3, 6, 12, Resources.All })
                                .ButtonCount(5))
                                // .Sortable()
                                .Filterable(filterable => filterable
                                .Extra(true)
                                .Operators(operators => operators
                                   .ForString(str => str.Clear()
                                       .Contains(Resources.Contains)
                                       .StartsWith(Resources.StartsWith)
                                       .EndsWith(Resources.EndsWith)
                                       .IsEqualTo(Resources.IsEqualTo)
                                       .IsNotEqualTo(Resources.IsNotEqualTo)
                                   )))
                                   .Events(events => events
                                         .Save("onSaveAttachStatus")
                                         .Edit("onAttachEdit")
                                         .DataBound("onAttachDataBound")
                                         .Cancel("onCancelEditing")
                                      )
                           .Editable(editable => editable.Mode(GridEditMode.InLine))
                           .Selectable(s => s.Enabled(ViewBag.Permissions.ReturnValue.FaEditStatusContractAttachments))
                           .DataSource(dataSource => dataSource
                                 .Ajax()
                                 .ServerOperation(true)
                                 .Update(update => update.Action("ChangeStatus", "ContractAttachment").Data("getValues"))
                                 .Read(read => read.Action("ReadAttachmentsGrid", "Contract", new { id = Id }))
                                 .PageSize(10)
                             .Model(model =>
                             {
                                 model.Id(c => c.ContractId);
                                 model.Field(c => c.number).Editable(false);
                                 model.Field(c => c.Consultant).Editable(false);
                                 model.Field(c => c.StartDate).Editable(false);
                                 model.Field(c => c.EndDate).Editable(false);
                                 model.Field(c => c.Status).Editable(true);
                             }))/*End datasource*/

)

这是为保存更改而调用的操作方法:

  [HttpPost]
    [ValidateAntiForgeryToken]
    [Auth(Permission.FaEditStatusContractAttachments)]
    public JsonResult ChangeStatus(int idAttachment, string statusContractAttach)
    {

        var contractAttach = _getContractAttachmentByIdQueryHandler.Execute(idAttachment).ReturnValue;
        var contractAttachStatus = (ContractStatus)Enum.Parse(typeof(ContractStatus), statusContractAttach);

        if (contractAttach == null)
        {
            var json = new { result = "Failed" };
            return Json(json, JsonRequestBehavior.AllowGet);
        }

        contractAttach.StatusContractAttachment = contractAttachStatus;
        var result = _updateContractAttachmentCommandHandler.Execute(new UpdateContractAttachmentCommand(contractAttach));

        if (result.HasError)
        {
            var json = new { result = "Failed" };
            return Json(json, JsonRequestBehavior.AllowGet);
        }
        else
        {
            UpdateHistory(idAttachment, contractAttachStatus);
            var json = new { result = "Success" };
            return Json(json, JsonRequestBehavior.AllowGet);
        }
    }

这是与网格相关的JQuery:

 //--------------------------Attachments EDIT Grid --------------------//

//save event
  function onSaveAttachStatus(e) {
   //post status data to action method
      $.post('@Url.Action("ChangeStatus", "ContractAttachment")', { contractId: e.model.Id, status: e.model.StatusContract }).success(function(data) {
                showErrorNotification('@Resources.ContractStatusChangedSuccessMessage', true);
            });
};

//kendo notification with succesmessage
function showErrorNotification(message, success) {
    var notification = $("#staticNotification").data('kendoNotification');
    notification.show(message, success ? "success" : "error");
    var container = $(notification.options.appendTo);
    container.scrollTop(container[0].scrollHeight);
}

function onClickAttachmentDelete() {
    //custom delete function
     var idToDelete = $(this).closest('tr').data('attachid');
        var attachNumber = $(this).closest('tr').data('number');
        //initiates modal with data
        $('#dialog-delete-attachnr').text(attachNumber);
        $("#dialog-delete-attach").modal();
        $('#dialog-delete-attach').data('attachid', idToDelete);
        $('#dialog-delete-contract').data('attachnumber', attachtNumber);
}


//edit event
function onAttachEdit(e) {

        var ddl = $("#Status").data('kendoDropDownList');
        var oldData = ddl.dataSource._data;
        var signedAccountStatus = @((int) ContractStatus.SignedByAccount);
        for (var i = 0; i < oldData.length; i++) {
            if (ddl.selectedIndex >= signedAccountStatus && parseInt(oldData[i].Value) < signedAccountStatus) {
                ddl.dataSource.remove(oldData[i--]);
            }
        }
        console.log("edit ok");
    }

  //resets grid data
    function resetGrid() {
        $("#attachmentEditGrid").data("kendoGrid").dataSource.read();

         };

  //returns data for the .Update action
         function getValues(e) {
             var id = e.Data.attachId;
             var value = e.Data("kendoDropdownList").value();
             console.log(id, value);
             return { id, value };
         }


            //Hide edit button when status is finished and hide delete when anyone signed
            //when data is loaded to the grid
    function onAttachDataBound(e) {
        var attachEditGrid = $("#attachmentEditGrid").data("kendoGrid");
        var attachEditGridData = attachEditGrid.dataSource.view();
            //loop through rows
        for (var i = 0; i < attachEditGridData.length; i++){
            var row = attachEditGrid.table.find("tr[data-uid='" + attachEditGridData[i].uid + "']");
            var statusContractAttach = attachEditGridData[i].Status;
            //hide delete when signed
            if (statusContractAttach >= @((int) ContractStatus.SignedByAccount)){
                row.find('.k-grid-Delete').hide();
            }
            //hide edit when contract is finished
            if (statusContractAttach == @((int)ContractStatus.Finished)){
                row.find(".k-grid-edit").hide();
            }

        }
    };


    //cancel edit
    function onCancelEditing(e) {
        resetGrid();
        onAttachDataBound();
    }

【问题讨论】:

  • 为什么在 ajax 请求中需要防伪令牌?通常它只适用于表单提交。应该使用 CORS 标头来保护 Ajax 请求。
  • 我是一名大三学生,上周才开始实习。我正在处理内部 ERP 应用程序的合同部分,这是我在尝试更新时遇到的异常。它似乎适用于应用程序的其他领域。我会这样保持一致。

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


【解决方案1】:

JQuery post 方法不会自动添加 __RequestVerificationToken 参数。我建议手动添加。

var data = $.extend(true, { contractId: e.model.Id, status: e.model.StatusContract }, 
    { __RequestVerificationToken: $('input[name="__RequestVerificationToken"]').val() });
// maybe you need convert to json befor send data:
// data = data.toJSON();
$.post('@Url.Action("ChangeStatus", "ContractAttachment")', data )
.success(function(data) {
    showErrorNotification('@Resources.ContractStatusChangedSuccessMessage', true);
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-22
    • 2013-01-27
    • 2012-12-10
    • 1970-01-01
    • 1970-01-01
    • 2014-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多