FlexGrid
AntiForgery
Features
Sample
Description
This sample shows how you can use C1AntiForgeryTokenAttribute to prevent forgery of a request.
The sample uses Html.AntiForgeryToken() to generate a token per every request so then no one can forge a form post.
To Test, remove Html.AntiForgeryToken() in AntiForgency.cshtml, then update data on grid, server will return an 500 Internal Server Error.
Source
AntiForgeryController.cs
using C1.Web.Mvc;
using MvcExplorer.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using C1.Web.Mvc.Serialization;
namespace MvcExplorer.Controllers
{
public partial class FlexGridController : Controller
{
public ActionResult AntiForgery()
{
ViewBag.Countries = Sale.GetCountries();
ViewBag.Products = Sale.GetProducts();
return View(Source);
}
[C1AntiForgeryTokenAttribute]
public ActionResult GridEditorsUpdateWithAntiForgery([C1JsonRequest]CollectionViewEditRequest<Sale> requestData)
{
return this.C1Json(CollectionViewHelper.Edit(requestData, sale =>
{
string error = string.Empty;
bool success = true;
var fSale = Source.Find(item => item.ID == sale.ID);
fSale.Country = sale.Country;
fSale.Amount = sale.Amount;
fSale.Start = sale.Start;
fSale.End = sale.End;
fSale.Product = sale.Product;
fSale.Active = sale.Active;
fSale.Amount2 = sale.Amount2;
fSale.Color = sale.Color;
return new CollectionViewItemResult<Sale>
{
Error = error,
Success = success && ModelState.IsValid,
Data = fSale
};
}, () => Source));
}
[C1AntiForgeryTokenAttribute]
public ActionResult GridEditorsCreateWithAntiForgery([C1JsonRequest]CollectionViewEditRequest<Sale> requestData)
{
return this.C1Json(CollectionViewHelper.Edit(requestData, item =>
{
string error = string.Empty;
bool success = true;
try
{
Source.Add(item);
item.ID = Source.Max(u => u.ID) + 1;
}
catch (Exception e)
{
error = e.Message;
success = false;
}
return new CollectionViewItemResult<Sale>
{
Error = error,
Success = success,
Data = item
};
}, () => Source));
}
[C1AntiForgeryTokenAttribute]
public ActionResult GridEditorsDeleteWithAntiForgery([C1JsonRequest]CollectionViewEditRequest<Sale> requestData)
{
return this.C1Json(CollectionViewHelper.Edit(requestData, item =>
{
string error = string.Empty;
bool success = true;
try
{
var resultItem = Source.Find(u => u.ID == item.ID);
Source.Remove(resultItem);
}
catch (Exception e)
{
error = e.Message;
success = false;
}
return new CollectionViewItemResult<Sale>
{
Error = error,
Success = success,
Data = item
};
}, () => Source));
}
}
}
AntiForgery.cshtml
@model IEnumerable<Sale>
@{
List<string> countries = ViewBag.Countries;
List<string> products = ViewBag.Products;
}
@section Scripts{
<script type="text/javascript">
c1.documentReady(function () {
var grid = wijmo.Control.getControl('#customGridEditorsGrid');
grid.hostElement.addEventListener('keydown', function (e) {
if (e.keyCode == 32) {
e.preventDefault();
}
});
});
function removeAnti()
{
$("input[name='__RequestVerificationToken']").remove();
}
function restoreAnti() {
location.reload();
}
</script>
}
@(Html.C1().InputDate()
.Id("dateEditor")
.Format("d")
.IsRequired(false) // add this for new row
.CssStyle("width", "100%") // full with the cell
)
@(Html.C1().InputTime()
.Id("timeEditor")
.Step(30)
.Format("t")
.IsRequired(false) // add this for new row
.CssStyle("width", "100%") // full with the cell
)
@(Html.C1().InputNumber()
.Id("amountEditor")
.Format("c2")
.IsRequired(false) // add this for new row
.CssStyle("width", "100%") // full with the cell
.Step(10)
)
@(Html.C1().ComboBox()
.Id("countryEditor")
.IsEditable(false)
.Bind(countries)
.CssStyle("width", "100%") // full with the cell
)
@(Html.C1().InputColor()
.Id("colorEditor")
.CssStyle("width", "100%") // full with the cell
)
@Html.AntiForgeryToken()
<!-- FlexGrid hosting the custom editors -->
@(Html.C1().FlexGrid<Sale>()
.Id("customGridEditorsGrid")
.KeyActionTab(C1.Web.Mvc.Grid.KeyAction.Cycle)
.AllowAddNew(true)
.AllowDelete(true)
.AutoGenerateColumns(false)
.Columns(bl =>
{
bl.Add(cb => cb.Binding("ID").Width("0.4*").IsReadOnly(true));
bl.Add(cb => cb.Binding("Start").Header("Date").Width("*").Format("d").Editor("dateEditor"));
bl.Add(cb => cb.Binding("End").Header("Time").Width("*").Format("t").Editor("timeEditor"));
bl.Add(cb => cb.Binding("Country").Width("1.5*").Editor("countryEditor"));
bl.Add(cb => cb.Binding("Product").Width("1.5*"));
bl.Add(cb => cb.Binding("Amount").Format("n2").Width("1.5*").Editor("amountEditor"));
bl.Add(cb => cb.Binding("Amount2").Format("n2").Width("1.5*"));
bl.Add(cb => cb.Binding("Color").Width("1.5*").Editor("colorEditor"));
bl.Add(cb => cb.Binding("Active").Width("1.5*"));
})
.Bind(bl => bl.Update(Url.Action("GridEditorsUpdateWithAntiForgery"))
.Create(Url.Action("GridEditorsCreateWithAntiForgery"))
.Delete(Url.Action("GridEditorsDeleteWithAntiForgery"))
.Bind(Model))
.CssStyle("height", "500px")
)
<div id="buttonsDiv">
<button class="btn" id="removeAnti" onclick="removeAnti();">@Html.Raw(Resources.FlexGrid.AntiForgency_Text3)</button>
<button class="btn" id="restoreAnti" onclick="restoreAnti();">@Html.Raw(Resources.FlexGrid.AntiForgency_Text4)</button>
</div>
@section Description{
<p>@Html.Raw(Resources.FlexGrid.AntiForgency_Text0)</p>
<p>@Html.Raw(Resources.FlexGrid.AntiForgency_Text1)</p>
<p>@Html.Raw(Resources.FlexGrid.AntiForgency_Text2)</p>
}
Documentation