This is a migrated thread and some comments may be shown as answers.

Kendo Grid AntiForgeryToken

11 Answers 1196 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Nitin
Top achievements
Rank 1
Nitin asked on 26 Sep 2012, 09:50 AM
Hi,
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;
        }

Whenever Kendo grid is posting an Ajax request can we use the above extension method because this is the common code we have written. Seems like Kendo has its own way of sending an Ajax Request, how can we do changes in that. We want to do changes in the common method so that everything works fine.

11 Answers, 1 is accepted

Sort by
0
Petur Subev
Telerik team
answered on 29 Sep 2012, 02:20 PM
Hello Ninth,

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
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
BRIAN
Top achievements
Rank 1
answered on 27 Nov 2012, 06:03 PM
Thanks, exactly what I was looking for.
0
Mike
Top achievements
Rank 1
answered on 11 Jan 2017, 04:48 PM

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

 

 

0
Stefan
Telerik team
answered on 16 Jan 2017, 11:22 AM
Hello 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
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data (charts) and form elements.
0
John
Top achievements
Rank 1
answered on 08 Jan 2019, 03:08 PM

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));

0
Alex Hajigeorgieva
Telerik team
answered on 11 Jan 2019, 09:12 AM
Hello, John,

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
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
John
Top achievements
Rank 1
answered on 11 Jan 2019, 02:43 PM
Thanks Alex.  That fixed it.  
0
Harsh
Top achievements
Rank 1
answered on 18 Apr 2020, 03:46 PM

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?

0
Alex Hajigeorgieva
Telerik team
answered on 22 Apr 2020, 04:05 PM

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

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
0
Merv
Top achievements
Rank 1
answered on 29 May 2020, 12:54 PM

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

0
Alex Hajigeorgieva
Telerik team
answered on 03 Jun 2020, 10:02 AM

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

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
Tags
Grid
Asked by
Nitin
Top achievements
Rank 1
Answers by
Petur Subev
Telerik team
BRIAN
Top achievements
Rank 1
Mike
Top achievements
Rank 1
Stefan
Telerik team
John
Top achievements
Rank 1
Alex Hajigeorgieva
Telerik team
Harsh
Top achievements
Rank 1
Merv
Top achievements
Rank 1
Share this question
or