This post is part of a series describing a demo project that employs various real-world patterns and tools to provide access to data in a MongoDB database for the DevExtreme grid widgets. You can find the introduction and overview to the post series by following this link.
I have created a branch that uses ASP.NET Core MVC and our controls for that platform for the frontend application of my demo project. Follow this link to access the branch. Please pay attention to the Prerequisites section below if you want to try this branch for yourself.
Prerequisites
The general instructions outlined in the README still apply for this branch. There is a caveat with regard to the runtime environment: I have not checked into options for live-debugging of the .NET Core based application, and I’m also not mounting the project directories into the running Docker container for this application, since this resulted in issues with dynamic compilation.
One important step you have to take before you run this branch is to configure your .NET Core nuget sources to include the DevExpress specific URL with our own access key. Details about our nuget repository can be found here and my recent blog post describes how to configure a Linux system correctly. I have not tested this yet, but I assume the instructions from my post apply to Mac computers as well.
The front-end project for this branch is configured with a reference to DevExtreme.AspNet.Core
, and the modules-install
step of the README documentation calls dotnet restore
. The DevExtreme assembly will only be restored if you have configured your nuget sources correctly! Please feel free to get back to me if you need any further help with this.
Details
Generally, the controls from our DevExtreme ASP.NET MVC Core package work as generators, translating the Razor syntax you use in your views into jQuery calls that are embedded in the rendered view HTML. As a result, the views DataGrid.cshtml and PivotGrid.cshtml are translations of the original JavaScript code. Here’s a snippet from DataGrid.cshtml
:
... .Summary(summary => { summary.TotalItems(ti => { ti.Add() .Column("date1") .SummaryType(SummaryType.Max); ti.Add() .Column("int1") .SummaryType(SummaryType.Avg); ti.Add() .Column("int1") .SummaryType(SummaryType.Sum); }); summary.GroupItems(ti => { ti.Add() .Column("date1") .SummaryType(SummaryType.Max); ti.Add() .Column("int1") .SummaryType(SummaryType.Avg); ti.Add() .Column("int1") .SummaryType(SummaryType.Sum); ti.Add().SummaryType(SummaryType.Count); }); })
One major difference compared to JavaScript is that the initialization code uses a fluent structure of method calls and lambdas. This results in a compact structure and a good Intellisense experience while writing the code.
You can also see that “known values” used in JavaScript are represented by enums. As long as Intellisense is available, this is easy enough to work with - as it happens, Razor Intellisense is quite flaky for me in VS 2017, and then it’s a bit of a hassle in comparison. Importantly, this makes your initialization code statically typed, which is expected in the .NET environment.
Translating the code to set up the widgets was easy, and I used the code of the demo DevExtreme.NETCore.Demos (from the DevExtreme package) in cases where structure or enums were not obvious to me.
Setting up the data sources for the grids turned out to be most complicated aspect. The controls actually have impressive support for data binding, which is documented here in detail. However, I already have a JavaScript implementation of the custom store that interfaces with my JavaScript service, and I want to use that - the examples in our documentation mostly refer to scenarios where the data service is implemented in .NET.
The steps I had to make were simple in the end. For the DataGrid, I initialized my data source using a small JavaScript block:
<script> var dataSource = new DevExpress.data.DataSource({ store: dataStore });</script>
The dataSource
variable is then injected into the grid configuration using this syntax:
@(Html.DevExtreme().DataGrid() .ID("grid") .DataSource(new JS("dataSource")) ...
The only difference to the JavaScript version of my code is that the convenience initialization mechanisms for the dataSource
property are not available in Razor, so I had to set up my own DataSource
instance.
For the PivotGrid, things are a bit different because the data source setup is more complicated and includes the pivot field configuration. Our documentation as well as the demo code show the use of the Store
method, which again supports various data binding scenarios where you’re either using a read-only web service or a WebApi service in your .NET Core server application. However, it turned out the overload that would allow me to pass a new JS(...)
is currently missing from this method. This has been noted and it will be fixed soon.
Meanwhile, I ended up using a workaround with the Option
method, which can set any JavaScript property on the object being configured. At the end of PivotGrid.cshtml you can see the configuration line that binds the PivotGrid to my existing custom data store:
... .Option("store", new JS("dataStore")); ...
Try it!
Please give this new front-end version a spin and let me know what you think!