Perks of using UI for ASP.NET MVC

Whether you code in pure JavaScript, Angular, Microsoft's ASP.NET MVC or PHP, Kendo UI allows you to code in whatever language you're most comfortable with. Kendo UI has implementations for jQuery, Angular 1.x and 2.x, ASP.NET AJAX, ASP.NET MVC (and .NET Core), Java and PHP.

Being a .NET developer, my choice is the UI for ASP.NET MVC. In this article, we'll cover what I think are the most useful parts of using the ASP.NET MVC wrappers.

Razor Syntax

UI for ASP.NET MVC allows .NET web developers to use the Razor syntax they know and love to render Kendo widgets on their pages. This is a huge bonus as it reduces "context switching" while working on a view. Developers less-familiar with JavaScript can get the benefits of a powerful UI toolset while using the toolset they are most comfortable with.

Let's look at a date picker as an example. Using plain HTML and jQuery, a date picker would be defined as:

<input type="text" name="mydate" id="my-date" />
<script>
  // Either directly under the input or at the bottom of page
  $(document).ready(function(){
    $('#my-date').kendoDatePicker(); // Optionally specify config
  })
</script>

To create the same date picker with the server side wrappers, one would write the following:

@Html.Kendo().DatePicker().Name("my-date")

Additionally, you can strongly type your Kendo widgets to a property on your view's model. Assuming your model has a DateTime property called StartDate, you could do:

@Html.Kendo().DatePickerFor(x => x.StartDate)

Obviously, widgets such as the grid are much more complex and require more configuration, but the same principals of the Razor syntax apply.

Leveraging Server-side Operations

One of the most powerful Kendo UI widgets is the Grid. The Kendo Grid can display almost any type and amount of data with optimal performance. One extremely useful component of the server-side wrappers is the IQueryable<T> extensions. Using these extensions, operations such as filtering, paging and sorting can be deferred to your database later to reduce the amount of query sets and data going over the wire.

Assuming you have a grid with an AJAX binding, your controller action would look like this:

public ActionResult([DataSourceRequest] DataSourceRequest request)
{
    // request has operational parameters defined by the grid

    var customers = _dbContext.Customers.Where(x => x.IsActive);

    // .ToDataSourceResult() is where the "magic" happens
    return Json(customers.ToDataSourceResult(request));
}

The magic happens in the .ToDataSourceResult(request) call. If you are using IQueryable<T> return types on your methods (which a DbSet essentially is), Kendo will use the parameters for filtering, paging, etc from the DataSourceRequest parameter (sent with the request from the grid by default when using the Razor helpers) to generate the appropriate SQL and defer its execution to the database level. A word of warning: I've noticed when using older versions of EntityFramework, if you are retrieving navigational properties, that the generated SQL can be a little unwieldy.

Type Reflection

If you are using strongly-typed models, there is a very nifty feature in the Grid's Razor helpers that make "scaffolding" a cinch. As an example, let's say you have a simple ContactModel that you wanted to display in a grid. For demonstration purposes, our model will look like this:

public class ContactModel
{
    public int Id { get; set; }

    public string Company { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    [Display(Name = "Email")]
    public string EmailAddress { get; set; }

    [Display(Name = "Phone")]
    public string PhoneNumber { get; set; }

    [Display(Name = "Birth date")]
    public DateTime? BirthDate { get; set; }
}

We'll also define a simple grid using the razor syntax:

@(Html.Kendo().Grid<ContactModel>()
    .Name("contacts-grid")
    .DataSource(ds => ds.Ajax().Read("MyAction", "Controller")))

You may be thinking, "But there's no column definitions there!" You are correct. Thanks to Kendo's server-side wrapper reflection, it can detect what the columns should be. Therefore, you'll end up with 6 columns in your grid (it doesn't include "ID" by default).

You'll also notice that some of the properties have Display attributes. By default, Kendo will separate your property names on upper-case characters ("FirstName" becomes "First Name") to use as the column titles unless a Display attribute is present. If you'd rather, you can explicitly define each column and its properties such as Title using the Razor helpers.

Let's take the type reflection a step further. Notice that there's a DateTime property on the class above. Without any additional code, the Grid helpers will wire that column up as a date column. If you have filtering enabled, the filter UI will be a date (or date time) picker.

Lastly, the power of reflection is apparent in editing mode. Using the same principle as filtering, the grid will use the proper widgets for the form. This includes things such as bool (a checkbox), date/time pickers, and so forth.

Custom Editor Templates

While using the jQuery framework, you can define custom templates for editing, UI for ASP.NET MVC makes this a little easier. If you have a grid with editing enabled (in popup mode), you can define a razor partial view strongly typed to your ContactModel to customize how the modal window appears.

Let's make a simple editor template and use the bootstrap form classes for demonstration purposes.

@model ContactModel

<div class="form-group">
    @Html.LabelFor(x => x.FirstName)
    @Html.TextBoxFor(x => x.FirstName, new {@class = "from-control"})
</div>

<div class="form-group">
    @Html.LabelFor(x => x.LastName)
    @Html.TextBoxFor(x => x.LastName, new {@class = "from-control"})
</div>

<div class="form-group">
    @Html.LabelFor(x => x.FirstName)
    @Html.Kendo().DatePickerFor(x => x.BirthDate)
</div>

You'll notice here that we don't have all our properties of our model defined here. This is by design to demonstrate that you could use custom editor templates to change the editable fields and their layout.

Further, if your view is named the same as your class (ContactModel.cshtml in this case) and placed in the /Views/Shared/EditorTemplates folder, Kendo will automatically find and wire it up with no additional code.

Conclusion

While the UI for ASP.NET MVC helpers may not be for everyone, and may not solve every need, they certainly make the life of creating an excellent user interface easier for a .NET MVC developer. Additionally, the time to deliver results is dramatically decreased. These same principals apply to the other server-side wrappers, so check out the framework for the language of your choice today.

Comments