Perform CRUD operation using anti-forgery token
21 Dec 202220 minutes to read
Anti-forgery token is used between the client and server to prevent cross-site request forgery (CSRF) attack. For more information on preventing CSRF attack, refer to the link.
While performing grid save operation, you can send anti-forgery token along with the save request using the below custom adaptor.
This custom adaptor will read the anti-forgery token from the hidden element and send it along with the request. Also content type is set to application/x-www-form-urlencoded; charset=UTF-8 since the ValidateAntiForgeryToken will look for the token in the form encoded data.
<script>
window.customAdaptor = new ej.data.RemoteSaveAdaptor();
customAdaptor = ej.base.extend(customAdaptor, {
insert(dm, data, tableName) {
this.updateType = 'add';
return {
url: dm.dataSource.insertUrl || dm.dataSource.crudUrl || dm.dataSource.url,
data: $.param({
//Added the anti-forgery token.
__RequestVerificationToken: document.getElementsByName("__RequestVerificationToken")[0].value,
value: data,
table: tableName,
action: 'insert'
}),
contentType: 'application/x-www-form-urlencoded; charset=UTF-8'
};
},
update(dm, keyField, value, tableName) {
debugger;
this.updateType = 'update';
this.updateKey = keyField;
return {
type: 'POST',
url: dm.dataSource.updateUrl || dm.dataSource.crudUrl || dm.dataSource.url,
data: $.param({
//Added the anti-forgery token.
__RequestVerificationToken: document.getElementsByName("__RequestVerificationToken")[0].value,
value: value,
action: 'update',
keyColumn: keyField,
key: value[keyField],
table: tableName
}),
contentType: 'application/x-www-form-urlencoded; charset=UTF-8'
};
},
remove(dm, keyField, value, tableName) {
ej.data.JsonAdaptor.prototype.remove(dm, keyField, value);
return {
type: 'POST',
url: dm.dataSource.removeUrl || dm.dataSource.crudUrl || dm.dataSource.url,
data: $.param({
//Added the anti-forgery token.
__RequestVerificationToken: document.getElementsByName("__RequestVerificationToken")[0].value,
key: value,
keyColumn: keyField,
table: tableName,
action: 'remove'
}),
contentType: 'application/x-www-form-urlencoded; charset=UTF-8'
};
}
});
</script>
Now assign the custom adaptor to the grid as follows.
<script>
function load(args) {
this.dataSource.adaptor = customAdaptor;
}
</script>
@using Syncfusion.EJ2
@Html.AntiForgeryToken()
<div>
<ejs-grid id="Grid" load="load" toolbar="@(new List<string>() { "Add","Delete","Update", "Cancel" })" allowPaging="true">
<e-data-manager json="@ViewBag.data" adaptor="RemoteSaveAdaptor" insertUrl="/Home/Insert" updateUrl="/Home/Update" removeUrl="/Home/Delete"></e-data-manager>
<e-grid-editSettings allowDeleting="true" allowEditing="true" allowAdding="true" mode="Normal"></e-grid-editSettings>
<e-grid-pagesettings pageCount="5"></e-grid-pagesettings>
<e-grid-columns>
<e-grid-column field="OrderID" headerText="Order ID" isPrimaryKey="true" validationRules="@(new { required=true})" textAlign="Right" width="120"></e-grid-column>
<e-grid-column field="CustomerID" headerText="Customer Name" validationRules="@(new { required=true})" width="150"></e-grid-column>
<e-grid-column field="Freight" headerText="Freight" validationRules="@(new { required=true})" textAlign="Right" editType="numericedit" format="C2" width="120"></e-grid-column>
<e-grid-column field="ShipCity" headerText="Ship City" width="170"></e-grid-column>
</e-grid-columns>
</ejs-grid>
</div>
<script type="text/javascript">
window.customAdaptor = new ej.data.RemoteSaveAdaptor();
customAdaptor = ej.base.extend(customAdaptor, {
insert(dm, data, tableName) {
this.updateType = 'add';
return {
url: dm.dataSource.insertUrl || dm.dataSource.crudUrl || dm.dataSource.url,
data: $.param({
//Added the anti-forgery token.
__RequestVerificationToken: document.getElementsByName("__RequestVerificationToken")[0].value,
value: data,
table: tableName,
action: 'insert'
}),
contentType: 'application/x-www-form-urlencoded; charset=UTF-8'
};
},
update(dm, keyField, value, tableName) {
debugger;
this.updateType = 'update';
this.updateKey = keyField;
return {
type: 'POST',
url: dm.dataSource.updateUrl || dm.dataSource.crudUrl || dm.dataSource.url,
data: $.param({
//Added the anti-forgery token.
__RequestVerificationToken: document.getElementsByName("__RequestVerificationToken")[0].value,
value: value,
action: 'update',
keyColumn: keyField,
key: value[keyField],
table: tableName
}),
contentType: 'application/x-www-form-urlencoded; charset=UTF-8'
};
},
remove(dm, keyField, value, tableName) {
ej.data.JsonAdaptor.prototype.remove(dm, keyField, value);
return {
type: 'POST',
url: dm.dataSource.removeUrl || dm.dataSource.crudUrl || dm.dataSource.url,
data: $.param({
//Added the anti-forgery token.
__RequestVerificationToken: document.getElementsByName("__RequestVerificationToken")[0].value,
key: value,
keyColumn: keyField,
table: tableName,
action: 'remove'
}),
contentType: 'application/x-www-form-urlencoded; charset=UTF-8'
};
}
});
function load(args) {
this.dataSource.adaptor = customAdaptor;
}
</script>
public class HomeController : Controller
{
public static List<Orders> order = new List<Orders>();
public ActionResult Index()
{
if (order.Count == 0)
BindDataSource();
ViewBag.data = order.ToArray();
return View();
}
public void BindDataSource()
{
int code = 10000;
for (int i = 1; i < 10; i++)
{
order.Add(new Orders(code + 1, "VINET", i + 0, 2.3 * i, new DateTime(1991, 05, 15), "Berlin"));
order.Add(new Orders(code + 2, "ANATR", i + 2, 3.3 * i, new DateTime(1990, 04, 04), "Madrid"));
order.Add(new Orders(code + 3, "ANTON", i + 1, 4.3 * i, new DateTime(1957, 11, 30), "Cholchester"));
order.Add(new Orders(code + 4, "BLONP", i + 3, 5.3 * i, new DateTime(1930, 10, 22), "Marseille"));
order.Add(new Orders(code + 5, "BOLID", i + 4, 6.3 * i, new DateTime(1953, 02, 18), "Tsawassen"));
code += 5;
}
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Update(Orders value, string action)
{
var data = order.Where(or => or.OrderID == value.OrderID).FirstOrDefault();
if (data != null)
{
data.OrderID = value.OrderID;
data.CustomerID = value.CustomerID;
data.EmployeeID = value.EmployeeID;
data.Freight = value.Freight;
data.OrderDate = value.OrderDate;
data.ShipCity = value.ShipCity;
}
return Json(value);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Insert(Orders value, string action)
{
order.Insert(0, value);
return Json(value);
}
[HttpPost]
[ValidateAntiForgeryToken]
public void Remove(int key)
{
var data = order.Where(or => or.OrderID == key).FirstOrDefault();
if (data != null)
{
order.Remove(data);
}
}
public class Orders
{
public Orders()
{
}
public Orders(long OrderId, string CustomerId, int EmployeeId, double Freight, DateTime OrderDate, string ShipCity)
{
this.OrderID = OrderId;
this.CustomerID = CustomerId;
this.EmployeeID = EmployeeId;
this.Freight = Freight;
this.OrderDate = OrderDate;
this.ShipCity = ShipCity;
}
public long OrderID { get; set; }
public string CustomerID { get; set; }
public int EmployeeID { get; set; }
public double Freight { get; set; }
public DateTime OrderDate { get; set; }
public string ShipCity { get; set; }
}
}
NOTE
You can find the full sample at our GitHub repository.