At my work place we are developing a web based application that is very data centric and involves a lot of Grids. After a lot of Grid survey we ended up using the Telerik Grids for MVC. The problem with the grid was that when it was used with ajax binding and the edit mode set to
So to filter out the identical form posting i wrote a helper method to generate a GUID
The complete demo can be found here
GridEditMode.PopUp
, of the user submits the form twice the value was inserted in the Database multiple times. Click here to enlarge the imageSo to filter out the identical form posting i wrote a helper method to generate a GUID
namespace Namespace.FilterAttributes { public static class GuidHelper{ public static MvcHtmlString GetGuid(this HtmlHelper helper) { var guid = Guid.NewGuid().ToString(); helper.ViewContext.HttpContext.Session[guid] = ""; return MvcHtmlString.Create(string.Form at("<input type='hidden' id='FormGuid' name='FormGuid' value='{0}' />", guid)); } }in the view to generate the GUID simply
<%@ Import Namespace="Namespace.FilterAttributes" %> <%:Html.GetGuid()%>attach a OnSave Client event to the grid so the GUID generate can be transported to the server
function onSave(e) { e.values["FormGuid"] = $("input[name='FormGuid']").val(); }in the ActionFilter attribute look in the session for the GUID if the session is null or empty put the value in the session so that the next time if the same form is posted again it should be filtered out.
public class MultiFormControlAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { var ctx = filterContext.HttpContext; var response = ctx.Response; var session = ctx.Session; var fGuid = ctx.Request.Form["FormGuid"]; if (ctx.Session["fGuid"] != null) { if (fGuid.Equals(ctx.Session["fGuid"].ToString())) { //kill the request kill it!!! //add the model error filterContext.Controller.ViewData.ModelState.AddModelError("", "Duplicate form post"); } ctx.Session["fGuid"] = fGuid; } else ctx.Session["fGuid"] = fGuid; } }Decorate the ActionResult responsible for the insertion of the values in the Grid with the MultiFormControl Attribute.
[GridAction,MultiFormControl] public ActionResult _AjaxBindingInsert(User _User) { if(ModelState.IsValid){ _users.Add(_User); Session[_user_key] = _users; } return View(new GridModel(_users)); }So far so good but the problem arises after the first value has been inserted upon inserting the second value the GUID was the same old one that was generated for the previous form it was not updated as the form was posted via AJAX. So to refresh the GUID upon submission of the form attach a OnDataBound client event to the Grid and reset the GUID
function OnDataBound(e) { $.post('<%= Url.Action("GetGuid") %>', function (data) { $("input[name='FormGuid']").val(data); }); }Add an overloaded helper to the GuidHelper class to generate the GUID OnDataBound
public static string GetGuid(HttpContextBase context) { var guid = Guid.NewGuid().ToString(); context.Session[guid] = "";// Not null return guid; }and an ActionResult by the name of GetGuid
public ActionResult GetGuid() { return Content(GuidHelper.GetGuid(HttpContext)); }Now upon each successful submission of the form the GUID is regenerate at the same time identical form submissions via ajax are filtered out.