@(Html.DevExtreme().DataGrid<DevExtreme.MVC.Demos.Models.Northwind.Order>() .ID("gridContainer") .DataSource(d => d.WebApi() .RouteName("DataGridBatchUpdateWebApi") .LoadAction("Orders") .Key("OrderID") ) .Pager(p => p.Visible(true)) .ShowBorders(true) .RemoteOperations(true) .RepaintChangesOnly(true) .Editing(e => e .Mode(GridEditMode.Batch) .AllowAdding(true) .AllowDeleting(true) .AllowUpdating(true) ) .Columns(columns => { columns.AddFor(m => m.OrderID).AllowEditing(false); columns.AddFor(m => m.ShipName); columns.AddFor(m => m.ShipCountry); columns.AddFor(m => m.ShipCity); columns.AddFor(m => m.ShipAddress); columns.AddFor(m => m.OrderDate).DataType(GridColumnDataType.Date); columns.AddFor(m => m.Freight); }) .OnSaving("onSaving") ) <script> function onSaving(e) { e.cancel = true; if (e.changes.length) { const changes = normalizeChanges(e.changes); e.promise = sendBatchRequest('@Url.HttpRouteUrl("DataGridBatchUpdateWebApi", new { action = "Batch" })', changes).done(() => { e.component.refresh(true).done(() => { e.component.cancelEditData(); }); }); } } function normalizeChanges(changes) { return changes.map(c => { switch (c.type) { case 'insert': return { type: c.type, data: c.data, }; case 'update': return { type: c.type, key: c.key, data: c.data, }; case 'remove': return { type: c.type, key: c.key, }; } }); } function sendBatchRequest(url, changes) { var d = $.Deferred(); $.ajax(url, { method: "POST", data: JSON.stringify(changes), cache: false, contentType: 'application/json', xhrFields: { withCredentials: true } }).done(d.resolve).fail(function (xhr) { d.reject(xhr.responseJSON ? xhr.responseJSON.Message : xhr.statusText); }); return d.promise(); } </script>
using DevExtreme.MVC.Demos.Models; using DevExtreme.MVC.Demos.Models.DataGrid; using DevExtreme.MVC.Demos.Models.SampleData; using System; using System.Linq; using System.Web.Mvc; namespace DevExtreme.MVC.Demos.Controllers { public class DataGridController : Controller { public ActionResult BatchUpdateRequest() { return View(); } } }
using DevExtreme.AspNet.Data; using DevExtreme.AspNet.Mvc; using Newtonsoft.Json; using System; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; using DevExtreme.MVC.Demos.Models.Northwind; using DevExtreme.MVC.Demos.Models.DataGrid; using System.Collections.Generic; namespace DevExtreme.MVC.Demos.Controllers { [Route("api/DataGridBatchUpdateWebApi/{action}", Name = "DataGridBatchUpdateWebApi")] public class DataGridBatchUpdateWebApiController : ApiController { InMemoryNorthwindContext _nwind = new InMemoryNorthwindContext(); [HttpGet] public HttpResponseMessage Orders(DataSourceLoadOptions loadOptions) { return Request.CreateResponse(DataSourceLoader.Load(_nwind.Orders, loadOptions)); } [HttpPost] public HttpResponseMessage Batch(List<DataChange> changes) { foreach(var change in changes) { Order order; if(change.Type == "update" || change.Type == "remove") { var key = Convert.ToInt32(change.Key); order = _nwind.Orders.First(o => o.OrderID == key); } else { order = new Order(); } if(change.Type == "insert" || change.Type == "update") { JsonConvert.PopulateObject(change.Data.ToString(), order); Validate(order); if(!ModelState.IsValid) return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState.GetFullErrorMessage()); if(change.Type == "insert") { _nwind.Orders.Add(order); } change.Data = order; } else if(change.Type == "remove") { _nwind.Orders.Remove(order); } } _nwind.SaveChanges(); return Request.CreateResponse(HttpStatusCode.OK, changes); } } }
using System.Text.Json.Serialization; namespace DevExtreme.MVC.Demos.Models.DataGrid { public class DataChange { [JsonPropertyName("key")] public int Key { get; set; } [JsonPropertyName("type")] public string Type { get; set; } [JsonPropertyName("data")] public object Data { get; set; } } }
using System; using System.Collections.Generic; using System.Data.Entity; namespace DevExtreme.MVC.Demos.Models.Northwind { public class InMemoryNorthwindContext : InMemoryDataContext<Order> { readonly NorthwindContext _nwind = new NorthwindContext(); public DbSet<Customer> Customers => _nwind.Customers; public DbSet<Order_Detail> Order_Details => _nwind.Order_Details; public ICollection<Order> Orders => ItemsInternal; public DbSet<Shipper> Shippers => _nwind.Shippers; protected override IEnumerable<Order> Source => _nwind.Orders; protected override int GetKey(Order item) => item.OrderID; protected override void SetKey(Order item, int key) => item.OrderID = key; } }
#gridContainer { height: 440px; }