Since releasing the DevExtreme ASP.NET MVC Controls in May 2017, we've received some great feedback on bugs, improvements, feature requests, etc.
And thanks to your feedback, we're improving "DataSource URL generation" in the DevExtreme v17.1.5 release. First, let's look at the feature and the problem we aim to solve:
DataSource URLs
The DevExtreme ASP.NET MVC Controls are client-side JavaScript DevExtreme controls that are wrapped in native ASP.NET MVC Server controls. Therefore, they handle things like data-binding and events differently than typical ASP.NET MVC Server controls.
Data-binding is different for client-side controls because you need a web service to deliver that data to the client-side control. With the DevExtreme ASP.NET MVC Controls, we've made that aspect easier for you by providing 'DataSources'. So whether you're using a static collection, ASP.NET Web API, OData, OLAP Cube, or read-only JSON then our DataSource objects help you to data bind them to a DevExtreme ASP.NET MVC Control. I recommend reading the excellent data-binding help topic to learn more.
Problem
Now let's dive into the specific issue and solution with DataSource URLs. The two most common ways to specify data sources for our MVC controls are connecting them to an MVC or a Web API controller:
// MVC @(Html.DevExtreme().DataGrid() .DataSource(d => d.Mvc().Controller("Data").LoadAction("Get"))
or
// WebAPI @(Html.DevExtreme().DataGrid() .DataSource(d => d.WebApi().Controller("Data").LoadAction("Get"))
From the earliest release candidate builds, we've used certain defaults when configuring data access in this manner. Specifically:
- We automatically assign the route name depending on the platform and the controller type:
ASP.NET MVC 5 | ASP.NET Core | |
.Mvc() | "Default" | "default" |
.WebApi() | "DefaultApi" | - |
- For
.WebApi()
, we automatically configure all CRUD actions ("Get", "Post", "Put", "Delete")
While those default settings work well, we've discovered the following issues with them:
Attribute routing does not work out of the box (except for
.WebApi()
in .NET Core because we do not assign a route name). Developers need to manually specify.RouteName(null)
or.RouteName("MyRoute")
to make them work.Full CRUD actions for
.WebApi()
are not always needed because in many cases, you may just need to display some data. To disable the generation of redundant URLs, developers have to assign.UpdateAction(null)
,.InsertAction(null)
, etc.For most WebAPI route patterns (including the one declared in the WebAPI project template), our predefined action names appear in the query string producing ugly URLs like
/api/Orders?action=Get
.
Solution
To solve the above mentioned issues, we're introducing a new global flag named UseLegacyRouting
and its default value is set to true
. This new flag will be part of the DevExtreme v17.1.5 release.
The new UseLegacyRouting
flag is fully backwards compatible too.
If you set it to false
, then no default route names and no default actions will be used thereby avoiding any unexpected effects we mentioned above.
For ASP.NET MVC 5 applications, enable it in Global.asax.cs:
protected void Application_Start() { DevExtreme.AspNet.Mvc.Compatibility.DataSource.UseLegacyRouting = false; // ... the rest of your code ... }
For .NET Core apps, add the line to Startup.cs:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { DevExtreme.AspNet.Mvc.Compatibility.DataSource.UseLegacyRouting = false; // ... the rest of your code ... }
What to expect when the flag is set to false
Besides the improvements (working attribute routing and cleaner URLs), you may face the following changes in behavior:
If you have custom routing rules declared before the default one, or using attribute routes with
{controller}
and{action}
placeholders, then they may take precedence and change resulting URLs. You might need to specify.RouteName(...)
explicitly to restore the previous behavior.For
.WebApi()
, insert, update, and delete action URLs won't be generated by default. You need to specify them explicitly. For example, to enable update URL, add.UpdateAction("Put")
for routes based on action names or.UpdateAction(true)
for routes based on HTTP verbs.
Recommendations - true or false?
I recommend that for existing projects you set the UseLegacyRouting
flag to true
. For new projects, or those that you'd like to upgrade to the new approach, set the flag to false
. This will help you transition to future versions of the DevExtreme ASP.NET MVC controls.
We're considering changing the default value of UseLegacyRouting
to false
in the next major release (17.2) and we'd like your feedback.
What do you think about the DevExtreme ASP.NET MVC Controls? Drop me a line below.
Email: mharry@devexpress.com
Twitter: @mehulharry
Create highly responsive web apps for touch-enabled devices and traditional desktops.
From desktops to mobile devices, DevExtreme HTML5 Data Grid delivers the flexibility you’ll need to build apps that reach the widest audience and deliver touch-first user experiences to power your next great interactive website.
Download a free and fully-functional version of DevExtreme now: Download DevExtreme