Telerik blogs

Do you remember the Game Genie? If your childhood was anything like mine, then you remember this was a truly revolutionary device. Apple has nothing on the Game Genie.

If you don't remember this remarkable appliance, or you were born slightly later than myself and never really played on the original Nintendo, then let me tell you about this truly "magical" feat of technology.

Truly Magical

The Nintendo gaming world of the 80's was strewn with secret codes and cheats that could enable all sorts of powers, weapons, lives and the like in just about any game. One of the most popular was the Konami code. This one was famous for giving you 30 lives in Contra - making the game beatable in a single afternoon. Many of you are reciting this code right now in your head even as you read this. It was so popular that it lives on as a JavaScript library that you can drop on your page and then do something interesting when people enter the code. My personal site uses the Konami code to add a little bit of ridiculousness to your day should you choose to activate it.

The Game Genie took the concept to a whole different level. It was a device that you plugged into your NES console along with the game, and it would actually alter the game code at the byte level making anything possible. It unlocked all kinds of goodness - like giving you infinite "StarMan" in Super Mario Brothers 3, making you completely invincible, or allowing you to skip directly to the Tyson fight in "Mike Tyson's Punch-Out".

Game Genie For ASP.NET MVC

Wouldn't it be great if the same sort of apparatus existed for web development? Something you plugged in and immediately had all of the things you normally have to work so hard for. If you're developing with ASP.NET MVC, it's already here. We call it Telerik UI For ASP.NET MVC.

Now drawing a direct comparison between Telerik MVC components and the greatest invention of the late 80's is strong assertion, so lets break it down so you can see how UI For ASP.NET MVC makes web development fun.

Cheat 1: Intellisense

The ASP.NET MVC HTML helpers are server-side wrappers to the award-winning Telerik HTML5 and jQuery Kendo UI widgets. There is nothing wrong with writing JavaScript, so what's the advantage of having HTML helpers?

Simply put, the helpers allow you to construct widgets that are already correctly configured. One of the most frustrating things about web development is simply getting the JavaScript configured correctly. There is no type checking and no compiler. Visual Studio has some support for syntax, but it's nowhere near the support you enjoy with C# and VB.NET.

Let's have a look at an example. Let's say we have a dropdown list that we want to display some simple data in. A simple mistake in your dropdown list JavaScript configuration code, and it simply won't work. See if you can spot the error below:

Simple JavaScript Error

$("#dropdownlist").kendoDropDownList({
    datasource: {
        read: "api/things"
    },
    dataTextField: "name",
    dataValueField: "id"
});

If you ran this code, your DropDownList would be empty and there would be no errors in the console. Now you can debug this with the dev tools, but there is no way for Visual Studio to tell you at design time that "datasource" should be "dataSource". Intellisense, on the other hand, shows you exactly which methods are available, preventing you from calling methods that simply don't exist.

Having the intellisense is really the same as having the documentation for the API baked right into the IDE and sensitive to the context. You spend a lot less time running down simple mistakes this way.

Cheat 2: Fluent API

The fluent API allows you to configure a widget by "chaining" each method off the previous one. If you write jQuery, you are very familiar with this concept. It's a very elegant way to write code and keeps you from having to divide a single widget declaration up into separate statements.

Have a look at what it takes to configure a Grid, and how the fluent API lets you stay tight and focused on the task.

Notice how each method piggyback's on the previous one? Whenever you need to provide additional configuration for a method (like DataSource), you just drop into the method with a lambda expression and rock on.

Cheat 3: Descriptive Errors

There are some configuration properties that even Visual Studio cannot help you with. For instance, each widget has to have a Name() specified. What happens if you don't do that? You might accidentally write some code that leaves out the Name() method. I know I have done this personally several times.

That block of code looks innocuous enough, but it's missing the required Name() declaration. Let's see what happens if I try and run this.

That's incredibly helpful! Now I know that I need to specify the "Name" since apparently it can't be blank.

Cheat 4: Configuration

When you are configuring widgets with straight JavaScript, you have to provide the settings that the control will need to function. Sometimes, this is simple.

Simple Widget Configuration

$("#dropdownlist").kendoDropDownList({
    dataSource: {
        transport: {
            read: "api/things"
        }
    },
    dataTextField: "name",
    dataValueField: "id"
});

That's not so bad at all. However, when you begin configuring some of the really feature rich controls like the grid, you will discover that the configuration is really half the battle. You have to get it right and if you provide wrong values or not enough information, things just won't work - as we have already seen.

Let's go back to the grid example for just a minute. That grid is pageable, sortable, groupable, and filterable. Not to mention some of the columns like "UnitPrice" have special formatting or titles. When you configure a Kendo UI Grid with JavaScript, you need to give the DataSource a lot of information about the model of the data and what functions you want the grid to handle. Lets look at the JavaScript rendered by the Grid HTML Helper:

JavaScript Rendered By Grid Helper

jQuery(function(){
  jQuery("#Products").kendoGrid({
    "columns":[{"title":"Name", field":"Name", "filterable":{}, "encoded":true},
               {"title":"Supplier","field":"Supplier.Name","filterable":{},"encoded":true},
               {"title":"Category","field":"Category.Name","filterable":{},"encoded":true},
               {"title":"Unit Price","field":"UnitPrice","format":"{0:c}","filterable":{},"encoded":true},
               {"title":"Units In Stock","field":"UnitsInStock","filterable":{},"encoded":true},
               {"title":"Discontinued","field":"Discontinued","filterable":{},"encoded":true}],
    "groupable":{},
    "pageable":{"buttonCount":10},
    "sortable":true,
    "filterable":true,
    "scrollable":false,
    "dataSource":{
      "transport":{
          "prefix":"",
          "read":{"url":"/Products/Get"}
      },
      "pageSize":5,
      "page":1,
      "total":0,
      "serverPaging":true,
      "serverSorting":true,
      "serverFiltering":true,
      "serverGrouping":true,
      "serverAggregates":true,
      "type":"aspnetmvc-ajax",
      "filter":[],
      "schema":{
        "data":"Data",
        "total":"Total",
        "errors":"Errors",
        "model":{
            "fields":{
                "Id":{"type":"number"},
                "Name":{"type":"string"},
                "UnitPrice":{"type":"number","defaultValue":null},
                "UnitsInStock":{"type":"number","defaultValue":null},
                "Discontinued":{"type":"boolean"},
                "Supplier":{"type":"object"},
                "Category":{"type":"object"}
            }
        }
      }
    }
  });
});

Look at how much more terse the grid declaration is when using the wrappers! All of the configuration in JavaScript is handled for you, and you know it's going to be right. No more guessing.

Cheat 5: HTTP Request Deserialization

Of course, having the wrappers configure the client-side for you is great, but your application has a server component that is equally as important. UI For ASP.NET MVC is about .NET, and that means handling the server component as well.

Whenever the grid performs an operation such as paging, sorting, grouping, filtering and so forth, it sends an HTTP request to the server that contains the data that the server will need to have in order to perform the desired operation. It is then up to you to implement the server code that applies the parameters sent from the UI components to your database query. For instance, when you perform a filtering operation on the grid, the following request is sent to the controller:

This request tells the server to take the following actions...

Retrieve the first five records that contain the expression 'Ex' in their SupplierName field. Sort these records by the Supplier Name descending and group them by the Product Name ascending

Before these parameters can be applied to the query, they have to be parsed off of the request. You could create a class and do some property decorating to get the request to map properly, or you can just let Telerik extensions do it for you. UI For ASP.NET MVC includes some utlity classes that help you on the server. Since the components are configuring the JavaScript and all the widgets use the Kendo UI DataSource, we know exactly what the incoming request is going to look like. This means that you can simply parse the incoming request as a DataSourceRequest and all the mapping will be magically done for you.

Use DataSourceRequest To Map HTTP Request To Model

public JsonResult Get([DataSourceRequest]DataSourceRequest request) {
  var products = _context.Products.Select(p => new Models.Product {
                  Id = p.ProductID,
                  Name = p.ProductName,
                  UnitsInStock = p.UnitsInStock,
                  UnitPrice = p.UnitPrice,
                  Discontinued = p.Discontinued,
                  Supplier = new Models.Supplier {
                      Id = p.Supplier.SupplierID,
                      Name = p.Supplier.CompanyName
                  },
                  Category = new Models.Category {
                      Id = p.Category.CategoryID,
                      Name = p.Category.CategoryName
                  }
              });

  // HOW DO I USE THE REQUEST OBJECT?
}

Cheat 6: LINQ Helpers For Dynamic Queries

Now that you have this DataSourceRequest object, what do you do with it? How do you apply all of these parameters to your query? You can do it manually, but if you are using LINQ (which I assume most people are), you are going to be needing the Dynamic LINQ Library or some other query language extension in order to effectively execute a 'where' clause.

Kendo UI knows that this is a tricky area, so we included a complete set of LINQ helpers with the wrappers.  All you have to do is call ToDataSourceResult() on your LINQ query and pass in the request object. The query is formatted by Kendo UI based on the constraints in the DataSourceRequest object.

Apply Request Parameters To LINQ Queries

public JsonResult Get([DataSourceRequest]DataSourceRequest request) {
  var products = _context.Products.Select(p => new Models.Product {
                  Id = p.ProductID,
                  Name = p.ProductName,
                  UnitsInStock = p.UnitsInStock,
                  UnitPrice = p.UnitPrice,
                  Discontinued = p.Discontinued,
                  Supplier = new Models.Supplier {
                      Id = p.Supplier.SupplierID,
                      Name = p.Supplier.CompanyName
                  },
                  Category = new Models.Category {
                      Id = p.Category.CategoryID,
                      Name = p.Category.CategoryName
                  }
              });

  // SO EASY!
  return this.Json(products.ToDataSourceResult(request));
}

Elevate Your MVC Game

UI For ASP.NET MVC isn't just a set of wrappers around widgets, it's a powerhouse framework that abstracts away all of the tedious configuration so that you can focus on building your application and not waste precious hours fiddling with the details that should "just work". No need for up, down, up, down, left, right, left, right, b, a, b, a, select, start - just download UI For ASP.NET MVC and LEVEL UP!


Burke Holland is the Director of Developer Relations at Telerik
About the Author

Burke Holland

Burke Holland is a web developer living in Nashville, TN and was the Director of Developer Relations at Progress. He enjoys working with and meeting developers who are building mobile apps with jQuery / HTML5 and loves to hack on social API's. Burke worked for Progress as a Developer Advocate focusing on Kendo UI.

Comments

Comments are disabled in preview mode.