Kendo UI Suite and Version - v2012.2.710
|
|
jQuery Version - v 1.7.1
|
|
Supported Browsers and Platforms - all
|
|
Components/Widgets used - ListView
|
|
Cross Domain Mobile WebApi Sample
This application is an example of how you can setup your application architecture to use the ASP.NET 4.x version of the WebApi framework for nice REST-ful client communication.
The goal here is to help demonstrate how to get past some of the pitfalls when using cross-domain communication with a web service such as WebApi.
With this example, it simply shows how you provide GET requests to the WebApi service to return json data to the HTML client application. There are no POST, PUT or DELETE examples in this application. You can easily test them out using Fiddler.
How to run this application
1) The first thing to do is to open the solution in Visual Studio 2010
2) Then select the WebApi project and then select the Debug menu and then Start without debugging. Or press Ctrl-F5. This will start the WebApi service so ajax calls can be made to it.
3) In the Presentation Layer, right-click on the index.html file in the Mobile client application, and select "View in browser".
You should see a list of products displayed in mobile view. You can click the "Flat" or "Grouped" tabstrip items to toggle between the two views.
n-Tier Architecture
This application is built with four (4) separate projects:
--
Presentation Layer - HTML Client - a simple HTML page for the mobile application that can display either a list of Products or a grouped list. Similar to the Kendo example, but this actually hits a datasource repository.
--
Business Objects - POCO classes - these might be used with Entity Framework code-first
--
Services - WebApi - this is the REST-ful service that communicates with the Data Objects repositories
--
Data Objects - repositories - there are two (2) repositories, one for Products and one for Categories
Data Objects
The Repository Pattern is used here and the WebApi service implements Dependency Injection on the repository interfaces, so the underlying repository implementation can change without affecting the WebApi service.
This example uses an in-memory example of the data source, so no database setup is necessary to run the application.
The ProductRepository and CategoryRepository implement interfaces which are used in the WebApi controller via Dependency Injection. These classes contain the basic REST-ful CRUD operations plus some custom operations for non-CRUD actions, like GetProductsByCategory, etc.
In this example only the GET methods are implemented.
WebApi Service
This is where most of the work takes place. The WebApi controllers query the repositories and return the proper responses to the client.
This project was created from an Empty Web Application and then various NuGet packages.
NuGet packages used to create this project:
--
Microsoft.AspNet.WebApi - this is the WebApi framework
--
Unity.WebApi - this is the Unity IoC container for WebApi
--
WebApiContrib.Formatting.Jsonp - this is the necessary MediaTypeFormatter for cross-domain communication
--
WebActivator - this is used to enable Unity outside of the Global.asax file
There is a single controller for this application, the ProductController which inherits from ApiController. It contains basic REST-ful CRUD operations, plus two extra example actions for returning Products by category or by product name.
You can play with the REST-ful operations directly in the browser by entering any of the following sample routes:
--
/api/product - get all products
--
/api/product/4 - get a selected product by id
--
/api/product/byname/crossbow - get a selected product by name
--
/api/product/category/electronics - get products by category name
These are the two custom actions:
Client Application
The client application is a KendoUI Mobile application that you can easily test in a normal browser to see how it operates.
It's a single HTML page with multiple mobile views. One view displays a ListView with all the Products, and another view displays the Products grouped by Category.
The Flat view displays data using a KendoUI template.
The Grouped view uses a simple inline template.
I had help from the nice folks at Telerik to get the currency formatting working correctly.
The data is received from the remote WebApi service via the KendoUI Datasource object. To keep things DRY, a shared transport object is created that contains the 'read' method to get the data from the service. It is then used with both jQuery functions for the Flat and Grouped views in different ways.
The transport object is applied to a shared Kendo Datasource object and used with the Flat function. And it is used with an inline kendo Datasource object for the Grouped function since this datasource object needs to contain the group method.
This is the code for the Ajax calls using the Kendo Datasource object.
<script>
// The base remote Url
// Create a reusable shared Transport object
var
productTransport =
new
kendo.data.RemoteTransport({
read: {
url: base_url +
"/api/product"
,
dataType:
'jsonp'
,
// jsonp is necessary here for cross domain calls, not just json
type:
'GET'
}
});
// Create a reusable shared DataSource object
var
datasource =
new
kendo.data.DataSource({
transport: productTransport
});
// This function is data-bound to the flat listview
function
mobileProductDataBind() {
$(
"#flat-listview"
).kendoMobileListView({
dataSource: datasource,
template: kendo.template($(
"#listviewHeadersTemplate"
).html())
});
}
// This function is data-bound to the grouped listview
function
mobileProductGroupedDataBind() {
$(
"#grouped-listview"
).kendoMobileListView({
dataSource: kendo.data.DataSource.create({
transport: productTransport,
group: { field:
"Category.CategoryName"
}
}),
template:
"#= Name # - #= kendo.format('{0:c}', Price) #"
,
fixedHeaders:
true
});
}
</script>
That's it!
In Conclusion
This is obviously a very simple application but it attempts to demonstrate how a real world mobile application is built with cross-domain data access calls.
The important point to remember for cross-domain applications using JSON, is to use "jsonp". You need to remember to set it in the client as "dataType: 'jsonp'" and include the MediaTypeFormatter for Jsonp in the Application_Start. I have it included in the App_Start/FormattersConfig.cs file. You can add others that you need here also.