Feel free to share demo-related thoughts here.
If you have technical questions, please create a support ticket in the DevExpress Support Center.
Thank you for the feedback!
If you have technical questions, please create a support ticket in the DevExpress Support Center.
Backend API
@(Html.DevExtreme().DataGrid<DevExtreme.NETCore.Demos.Models.Northwind.Order>()
.DataSource(d => d.Mvc()
.Controller("DataGridWebApi")
.LoadAction("Orders")
.InsertAction("InsertOrder")
.UpdateAction("UpdateOrder")
.DeleteAction("DeleteOrder")
.Key("OrderID")
)
.RemoteOperations(true)
.Columns(columns => {
columns.AddFor(m => m.CustomerID)
.Lookup(lookup => lookup
.DataSource(d => d.Mvc().Controller("DataGridWebApi").LoadAction("CustomersLookup").Key("Value"))
.ValueExpr("Value")
.DisplayExpr("Text")
);
columns.AddFor(m => m.OrderDate);
columns.AddFor(m => m.Freight)
.HeaderFilter(f => f.GroupInterval(100));
columns.AddFor(m => m.ShipCountry);
columns.AddFor(m => m.ShipVia)
.Lookup(lookup => lookup
.DataSource(d => d.Mvc().Controller("DataGridWebApi").LoadAction("ShippersLookup").Key("Value"))
.ValueExpr("Value")
.DisplayExpr("Text")
);
})
.FilterRow(f => f.Visible(true))
.HeaderFilter(f => f.Visible(true))
.GroupPanel(p => p.Visible(true))
.Scrolling(s => s.Mode(GridScrollingMode.Virtual))
.Width("100%")
.Height(600)
.ShowBorders(true)
.MasterDetail(md => md
.Enabled(true)
.Template(@<text>
@(Html.DevExtreme().DataGrid()
.DataSource(d => d.Mvc()
.Controller("DataGridWebApi")
.LoadAction("OrderDetails")
.LoadParams(new { orderID = new JS("data.OrderID") })
)
.ShowBorders(true)
)
</text>)
)
.Editing(e => e.AllowAdding(true).AllowDeleting(true).AllowUpdating(true))
.Grouping(g => g.AutoExpandAll(false))
.Summary(s => s
.TotalItems(totalItems => {
totalItems.AddFor(m => m.Freight).SummaryType(SummaryType.Sum);
})
.GroupItems(groupItems => {
groupItems.AddFor(m => m.Freight).SummaryType(SummaryType.Sum);
groupItems.Add().SummaryType(SummaryType.Count);
})
)
)
using DevExtreme.NETCore.Demos.Models;
using DevExtreme.NETCore.Demos.Models.DataGrid;
using DevExtreme.NETCore.Demos.Models.SampleData;
using Microsoft.AspNetCore.Mvc;
using System.Linq;
namespace DevExtreme.NETCore.Demos.Controllers {
public class DataGridController : Controller {
public ActionResult WebAPIService() {
return View();
}
}
}
using DevExtreme.AspNet.Data;
using DevExtreme.AspNet.Mvc;
using DevExpress.Utils.Serializing.Helpers;
using DevExtreme.NETCore.Demos.Models.DataGrid;
using DevExtreme.NETCore.Demos.Models.Northwind;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections.Generic;
using System.Linq;
namespace DevExtreme.NETCore.Demos.Controllers.ApiControllers {
[Route("api/[controller]/[action]")]
public class DataGridWebApiController : Controller {
InMemoryNorthwindContext _nwind;
public DataGridWebApiController(NorthwindContext nwind, IHttpContextAccessor httpContextAccessor, IMemoryCache memoryCache) {
_nwind = new InMemoryNorthwindContext(nwind, httpContextAccessor, memoryCache);
}
[HttpGet]
public object Orders(DataSourceLoadOptions loadOptions) {
return DataSourceLoader.Load(_nwind.Orders, loadOptions);
}
[HttpPost]
public IActionResult InsertOrder(string values) {
var newOrder = new Order();
JsonPopulateObjectExtensions.PopulateObject(values, newOrder);
if(!TryValidateModel(newOrder))
return BadRequest(ModelState.GetFullErrorMessage());
_nwind.Orders.Add(newOrder);
_nwind.SaveChanges();
return Ok(newOrder);
}
[HttpPut]
public IActionResult UpdateOrder(int key, string values) {
var order = _nwind.Orders.First(o => o.OrderID == key);
JsonPopulateObjectExtensions.PopulateObject(values, order);
if(!TryValidateModel(order))
return BadRequest(ModelState.GetFullErrorMessage());
_nwind.SaveChanges();
return Ok(order);
}
[HttpDelete]
public void DeleteOrder(int key) {
var order = _nwind.Orders.First(o => o.OrderID == key);
_nwind.Orders.Remove(order);
_nwind.SaveChanges();
}
// additional actions
[HttpGet]
public object OrderDetails(int orderID, DataSourceLoadOptions loadOptions) {
return DataSourceLoader.Load(
from i in _nwind.Order_Details
where i.OrderID == orderID
select new {
Product = i.Product.ProductName,
Price = i.UnitPrice,
i.Quantity,
Sum = i.UnitPrice * i.Quantity
},
loadOptions
);
}
[HttpGet]
public object ShippersLookup(DataSourceLoadOptions loadOptions) {
var lookup = from i in _nwind.Shippers
orderby i.CompanyName
select new {
Value = i.ShipperID,
Text = i.CompanyName
};
return DataSourceLoader.Load(lookup, loadOptions);
}
[HttpGet]
public object CustomersLookup(DataSourceLoadOptions loadOptions) {
var lookup = from i in _nwind.Customers
let text = i.CompanyName + " (" + i.Country + ")"
orderby i.CompanyName
select new {
Value = i.CustomerID,
Text = text
};
return DataSourceLoader.Load(lookup, loadOptions);
}
[HttpPost]
public object Batch([FromBody] 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") {
JsonPopulateObjectExtensions.PopulateObject(change.Data.ToString(), order);
if(!TryValidateModel(order))
return 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 Ok(changes);
}
}
}
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections.Generic;
namespace DevExtreme.NETCore.Demos.Models.Northwind {
public class InMemoryNorthwindContext : InMemoryDataContext<Order> {
NorthwindContext _nwind;
public InMemoryNorthwindContext(NorthwindContext nwind, IHttpContextAccessor contextAccessor, IMemoryCache memoryCache)
: base(contextAccessor, memoryCache) {
_nwind = nwind;
}
public ICollection<Order> Orders => ItemsInternal;
public DbSet<Customer> Customers => _nwind.Customers;
public DbSet<Order_Detail> Order_Details => _nwind.Order_Details;
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;
}
}