We are using AntiForgeryToken in our application. For normal Ajax post currently we are using extension method for Ajax.BeginForm as follows:
public static MvcForm BeginForm(this AjaxHelper ajaxHelper, HtmlHelper htmlHelper, AjaxOptions ajaxOptions, bool addAntiForgeryToken = true, string actionName = null, string controllerName = null,
object routeValues = null, object htmlAttributes = null)
{
return htmlHelper.BeginFormWithAntiForgery(
() => ajaxHelper.BeginForm(actionName, controllerName, routeValues, ajaxOptions, htmlAttributes),
addAntiForgeryToken);
}
private static MvcForm BeginFormWithAntiForgery(this HtmlHelper htmlHelper, Func<MvcForm> formFunc, bool addAntiForgeryToken)
{
var form = formFunc();
if (addAntiForgeryToken)
htmlHelper.ViewContext.Writer.Write(htmlHelper.AntiForgeryToken().ToHtmlString());
return form;
}
11 Answers, 1 is accepted
You cannot integrate your solution to be used by the dataSource when performing CRUD operations. However you can easily send the value of the anti forgery token to the server via the data function which is available for each of the transport methods (CRUD).
To demonstrate this in action I prepared a small sample project which you can find in the attached files.
Kind Regards,
Petur Subev
the Telerik team


I have the same issue trying to send the anti forgery token, however I am using "Html.Telerik().Grid".
Do you have an example using this version?
Thanks
Mike
The mentioned MVC extension Html.Telerik().Grid is no longer supported, as it is for a Grid which is officially not supported from several years.
The example provided by Petur is using the supported Kendo UI Grid for MVC:
http://docs.telerik.com/aspnet-mvc/helpers/grid/overview
Regards,
Stefan
Telerik by Progress

I tried following your example but am getting a compile error on the following line:
.Read(read => read.Action("ContractList3_GetData", "Contract")).Data("sendAntiForgery")) <== ".Data" shows an error "AjaxDataSourceBuilder<ContractListItemVM>' does not contain a definition for 'Data' and no extension method 'Data' accepting a first argument of type 'AjaxDataSourceBuilder<ContractListItemVM>' could be found (are you missing a using directive or an assembly reference?)"
==================================
@Html.AntiForgeryToken()
@(Html.Kendo().Grid<Shared_ViewModels.Contract.ContractListItemVM>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(c => c.ContractOid).Hidden();
columns.Bound(c => c.LesseeName).Width(230).Filterable(ftb => ftb.Multi(true).Search(true));
})
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("ContractList3_GetData", "Contract")).Data("sendAntiForgery"))
)
.DataSource(dataSource => dataSource.Ajax()
.ServerOperation(false)
)
)
<script type="text/javascript">
function sendAntiForgery() {
return { "__RequestVerificationToken": $('input[name=__RequestVerificationToken]').val() }
}
</script>
====================CONTROLLER==============
[ValidateAntiForgeryToken]
public ActionResult ContractList3_GetData([DataSourceRequest] DataSourceRequest request)
....
return Json(Shared_ServiceLayer.ContractFunctions.ContractList_SSD(vm).ToDataSourceResult(request));
The error is thrown because the Data() is misplaced. It is part of the "Read" action, not at the data source level, i.e:
.Read(read => read.Action(
"ContractList3_GetData"
,
"Contract"
).Data(
"sendAntiForgery"
))
)
https://docs.telerik.com/aspnet-mvc/api/Kendo.Mvc.UI.Fluent/CrudOperationBuilderBase#datasystemstring
Kind Regards,
Alex Hajigeorgieva
Progress Telerik


Hey Alex,
I am having this same issue with a child grid within a popup editor. It is bound to a property of the parent model via the .Edit event of the parent grid
function
onEdit(e) {
$(
'#ConfigCriteriaGrid'
).data().kendoGrid.dataSource.data(e.model.ConfigurationCriteria);
}
The popup editor throws the "The required antiforgery request token was not provided in either form field "__RequestVerificationToken" or header value "X-XSRF-TOKEN". " error message when attempting to update the grid row with inline editing. I do not have .Read (bound to model) or .Update actions on the child grid as I want it to get posted with the whole form. If I don't have a .Update action to attach a .Data property to so I can I solve the anti forgery issue?
Child grid:
@(Html.Kendo().Grid<
ConfigurationCriteriaModel
>()
.Name("ConfigCriteriaGrid")
.Editable(editable => editable.Mode(GridEditMode.InLine))
.ToolBar(toolbar =>
{
toolbar.Create();
})
.Columns(columns =>
{
columns.ForeignKey(p => p.Table_Name, (System.Collections.IEnumerable)ViewData["Tables"], "DisplayValue", "DisplayName").Width(300).EditorTemplateName("TableNameDropdown").ClientTemplate("#= getTextByValue(data, 'Table_Name') #" +
"<
input
type
=
'hidden'
name
=
'model.ConfigurationCriteria[#= index(data)#].Table_Name'
value
=
'#= Table_Name#'
/>");
columns.ForeignKey(o => o.Column_Name, (System.Collections.IEnumerable)ViewData["Attributes"], "DisplayValue", "DisplayName").Width(200).EditorTemplateName("TableAttributeDropdown").ClientTemplate("#= getTextByValue(data, 'Column_Name') #" +
"<
input
type
=
'hidden'
name
=
'model.ConfigurationCriteria[#= index(data)#].Column_Name'
value
=
'#= Column_Name#'
/>");
columns.ForeignKey(o => o.Target_Configuration_Operator_ID, (System.Collections.IEnumerable)ViewData["Operators"], "DisplayValue", "DisplayName").Width(100).EditorTemplateName("OperatorValueDropdown")
.ClientTemplate("#= getTextByValue(data, 'Target_Configuration_Operator_ID') # <
input
type
=
'hidden'
name
=
'model.ConfigurationCriteria[#= index(data)#].Target_Configuration_Operator_ID'
value
=
'#= Target_Configuration_Operator_ID#'
/>");
columns.Bound(o => o.ConfigurationCriteriaValues).ClientTemplate("#= Criteria_Values #" +
"<
input
type
=
'hidden'
name
=
'model.ConfigurationCriteria[#= index(data)#].Target_Asset_Transfer_Configuration_ID'
value
=
'#= Target_Asset_Transfer_Configuration_ID #'
/>").Width(300);
columns.Bound(p => p.Target_Asset_Transfer_Configuration_ID).Hidden().ClientTemplate("#= Target_Asset_Transfer_Configuration_ID #" +
"<
input
type
=
'hidden'
name
=
'model.ConfigurationCriteria[#= index(data)#].Target_Asset_Transfer_Configuration_ID'
value
=
'#= Target_Asset_Transfer_Configuration_ID #'
/>");
columns.Command(command =>
{
command.Edit(); command.Destroy();
}).Width(220);
})
.AutoBind(false)
.DataSource(d => d
.Ajax()
.Batch(true)
.ServerOperation(false)
.Model(m =>
{
m.Id("Target_Configuration_Criteria_ID");
m.Field(f => f.Target_Configuration_Criteria_ID).Editable(false);
m.Field(f => f.ConfigurationCriteriaValues).DefaultValue(new List<
ConfigurationCriteriaValueModel
>()).Editable(false);
})
.Events(events => events.Error("onError"))
)
.ToClientTemplate()
)
<
script
>
function index(dataItem)
{
var data = $("#ConfigCriteriaGrid").data("kendoGrid").dataSource.data();
return data.indexOf(dataItem);
}
</
script
>
Am I doing this correct or is there a better method?
Hello, Harsh,
The Detail grid has a Name which is not unique and that will lead to issues. The first thing that you should fix is the name of the child grid. The name is used as and id for the element from which the grid is initialized and you cannot have more than one element with the same id on the page. For example, you could do something like this:
.Name("grid_#=ParentIDField#") // template expression, to be evaluated in the master context
The POST could come from the child grid declaration. You can try using a Custom data source instead:
.DataSource(ds => ds.Custom())
It would be better if you use a new data source with a schema for the child grid so the data source can process the data. Another approach is to use the DetailInit() event handler:
function onDetailInit(e) {
var ds = new kendo.data.DataSource({
transport: {
read: function (e1) {
e.success(e.data.get("ParentCollectionField").toJSON());
}
},
schema: {
model: {
id: "Id"
}
}
});
var grid = $("#grid" + e.data.Id).data("kendoGrid"); // however the detail is named
grid.setDataSource(ds);
}
Regards,
Alex Hajigeorgieva
Progress Telerik
Our thoughts here at Progress are with those affected by the outbreak.

Is there any way I can apply the RequestVerificationToken to a C# Ajax post?
My code is:
public override void DataSourceA(Kendo.Mvc.UI.Fluent.DataSourceBuilder<dynamic> dataSource)
{
dataSource
.Ajax()
.Sort(s =>
{
s.Add("SortName").Ascending();
})
.Read(read => read.Action("ControllerMethod", "ControllerName"))
.PageSize(200)
.ShowProgress(true)
.ServerOperation(true);
}
Thanks
Hi, Merv,
You can use the Data() method:
https://docs.telerik.com/kendo-ui/knowledge-base/grid-send-antiforgery-token
.Read(read => read.Action("ControllerMethod", "ControllerName").Data("sendTokens"))
<script>
function sendTokens(){
return kendo.antiForgeryTokens();
}
<script>
Kind
Regards,
Alex Hajigeorgieva
Progress Telerik
Our thoughts here at Progress are with those affected by the outbreak.