FlexGrid
AntiForgery
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.
Features
ID
Date
Time
Country
Product
Amount
Amount2
Color
Active
1
1/25/2025
12:00 AM
German
Gadget
581.61
1,030.17
Green
2
2/25/2025
1:30 AM
Italy
Gadget
-4,673.75
3,499.71
Green
3
3/25/2025
2:00 AM
China
Gadget
-2,265.49
4,535.49
Black
4
4/25/2025
3:30 AM
France
Widget
3,964.40
432.90
Green
5
5/25/2025
4:00 AM
UK
Widget
-1,744.99
3,355.18
Red
6
6/25/2025
5:30 AM
France
Gadget
4,276.37
1,106.71
Red
7
7/25/2025
6:00 AM
US
Widget
-4,376.92
1,408.24
Green
8
8/25/2025
7:30 AM
Japan
Gadget
1,996.52
3,077.04
Black
9
9/25/2025
8:00 AM
Korea
Widget
-3,442.35
4,068.26
Red
10
10/25/2025
9:30 AM
US
Widget
-2,973.96
4,568.15
Green
11
11/25/2025
10:00 AM
Canada
Widget
-3,217.79
4,414.46
Green
12
12/25/2025
11:30 AM
UK
Gadget
1,556.19
1,705.14
Red
13
1/25/2025
12:00 PM
Canada
Gadget
-4,981.75
4,917.13
Red
14
2/25/2025
1:30 PM
China
Gadget
-397.56
1,702.41
Green
15
3/25/2025
2:00 PM
Italy
Widget
199.60
4,148.18
Green
16
4/25/2025
3:30 PM
China
Gadget
-176.56
506.04
Green
17
5/25/2025
4:00 PM
Canada
Widget
-542.28
1,471.61
Black
18
6/25/2025
5:30 PM
Japan
Gadget
4,319.97
4,562.80
Red
19
7/25/2025
6:00 PM
France
Gadget
-1,397.67
3,784.00
Green
20
8/25/2025
7:30 PM
UK
Widget
-3,476.95
4,926.25
Black
ID
Date
Time
Country
Product
Amount
Amount2
Color
Active
0
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | 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)); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | @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 > } |