Make ASP.NET Web Forms Feel Native with KendoUI Mobile

kendoui_astroturf_header

In 1965, a patent was filed for a synthetic grass product that would go on to be implemented in the world’s first indoor baseball stadium. The following year, the Houston Astrodome opened and was instantly famous for its green carpet that simulated grass. The thing is that real grass is expensive to add and even more expensive to maintain, a problem astroturf solves.

In the world of web development, native apps can be similarly expensive to build and maintain, as can re-engineering a desktop site to work on mobile. Thankfully, like Astroturf, we have tools that can make a website look and feel like a native app on a mobile device but also minimize the difficulty and cost of building and maintaining. KendoUI Mobile is one such tool.

I have a number of websites out there that were designed and built in ASP.NET with the desktop browser in mind. They’ve been running for some time, and they just don’t look and feel right on a phone. Any way you cut it, no matter the amount of zooming, pinching, or squinting, its a painful user experience.

In this article, I’m going to show you a sample ASP.NET Web Forms application and how quickly we can add capabilities for native mobile rendering with KendoUI Mobile capabilities.

Two options – Adaptive Rendering and Alternative Rendering

When building and thinking about web sites on mobile, we have two general approaches we can take in developing our user interface:

  1. Adaptive Rendering is an approach that builds an interface that will stretch, shrink, and shift content appropriately for any sized browser.
  2. Alternative Rendering is an approach that provides a new user interface specific to the needs of specific browsers, or even entire classes of browsers.

Of course, there is a third option: do nothing and expect the mobile browsers to just get better at handling desktop sized content. This might be a good option for you, as we are finding that phones are getting larger and larger screen sizes:

Huge phones

Huge phones

The Nokia Lumia 1520 and Samsung Galaxy Note barely fit in my pants pockets, and you won’t find me carry a man-purse for one of these giant phones. My old websites look just fine on these giant phones, but I don’t want to rely on my customers buying a phablet just so they can access my applications.

In our case, we will be writing an alternative rendering for a sample web site that provides a native-like experience to mobile browsers for their specific type of device.

Our Sample Web Site

For this sample, I have mocked up a search and edit screen for a hypothetical board game shop. I love board games, so I enjoy using this sample. This will demonstrate the concepts of implementing mobile capabilities over standard search and edit screens.

The product search screen is a simple ASP.NET GridView with ModelBinding configured:

My Games for Sale Grid

My Games for Sale Grid

The source code is very simple, with a default style applied from the Visual Studio wizard:

<asp:GridView runat="server" ID="grid" DataKeyNames="ID"
SelectMethod="Get" AllowSorting="true" AutoGenerateColumns="false" 
CellPadding="4" ForeColor="#333333" GridLines="None">

<Columns>
    <asp:BoundField DataField="Id" HeaderText="Id" SortExpression="id" />
    <asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" ItemStyle-Width="200" />
    <asp:BoundField DataField="Price" HeaderText="Price $$$" SortExpression="Price" ItemStyle-Width="100" DataFormatString="${0:0.00}" ItemStyle-HorizontalAlign="Right" />
    <asp:BoundField DataField="NumInStock" HeaderText="# in Stock" SortExpression="NumInStock" ItemStyle-Width="100" ItemStyle-HorizontalAlign="Right" />
    <asp:HyperLinkField DataNavigateUrlFields="Id" DataNavigateUrlFormatString="/Products/Edit/{0}" Text="Edit"></asp:HyperLinkField>
</Columns>

<!-- Style code here... omitted for brevity -->

</asp:GridView>

There’s no real magic going on there. For my edit page, I take advantage of ASP.NET Dynamic Data to deliver an appropriate set of markup for my BoardGame class in the following asp:FormView markup:

<asp:FormView runat="server" ID="myForm" DefaultMode="Edit"
    SelectMethod="myForm_GetItem" 
    UpdateMethod="myForm_UpdateItem"
    ItemType="KendoMobile.Models.BoardGame"
    DataKeyNames="Id"
    >

    <EditItemTemplate>

        <h2>Editing <%#: Item.Name %> (<%#: Item.Id %>)</h2>

        <fieldset>

            <ol>
                <asp:DynamicEntity runat="server" Mode="Edit"></asp:DynamicEntity>
            </ol>

            <asp:Button runat="server" ID="submit" Text="Save Changes" CommandName="Update" />
            <asp:Button runat="server" ID="cancel" Text="Cancel Changes" CommandName="Cancel" CausesValidation="false" OnClick="cancel_Click" />

        </fieldset>

    </EditItemTemplate>

</asp:FormView>

Once again, I’m using the ModelBinding attributes to specify a Select and Update method that will handle those data-access methods for this form. My DynamicEntity is loading templates using the DynamicDataTemplatesCS NuGet package. With this package, all of the input boxes and labels will be created properly in edit mode for this BoardGame object.

Simple Edit Form for desktop browsers

Simple Edit Form for desktop browsers

Transition to a new Render Mode

The key ASP.NET feature that will allow me to bridge from the markup intended for Desktop browsers to one intended for Mobile browsers is called FriendlyUrls. With this feature, ASP.NET will help make URLs requested of our server look more SEO-friendly. It will automatically take a URL like this:

http://www.mywebsite.com/Products/Edit.aspx?id=2&Name=Chess

…and reformat it to look something a bit more friendly like this:

http://www.mywebsite.com/Products/Edit/2/Chess

That’s a lot easier for humans to read, and with the help of the FriendlyUrls NuGet package, easy for ASP.NET to understand.

To assist the Get method on the Edit page in fetching the appropriate value from the path, we simply add a FriendlyUrlSegments hint to the arguments.

public Models.BoardGame myForm_GetItem([FriendlyUrlSegments(0)]int? id)

Note that I use a nullable integer for this input parameter. That allows me to add an error check scenario in my method to verify that an appropriate (if any) id was submitted to this page. I can then redirect to a “Product Not Found” page or handle it in some other graceful manner that makes my customers happy.

The real feature of FriendlyUrls that I want to show you is the mobile device detection and re-routing. This means that the ASP.NET router will detect that a mobile device is requesting a page and search for a .mobile.aspx page with the same base-name. For that request to that device, it will serve the content of this alternate page, and not the content of the .aspx to the requester.

Since ASP.NET 4.0 we have had routing in all segments of ASP.NET, including web forms. With this routing feature enabled in RouteConfig.cs as follows, we can take advantage of adding alternate renderings for our pages:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.EnableFriendlyUrls();
}

Now we can start to add mobile-friendly renderings into our web application without modifying our existing ASPX pages. In effect, we can add this secondary rendermode risk-free… developing a mobile version of the application next to our existing pages without disturbing them.

Adding Mobile Rendering

To add the native mobile renderings to my site, I started adding a separate Site.Mobile.Master file that would contain all of the framework styling and scripting necessary for KendoUI Mobile. In this case, I added links to the public CDN instances of the CSS and JavaScript files in the KendoUI Core library:

<title><%: Page.Title %></title>
<meta name="viewport" content="width=device-width" />
<link href="http://cdn.kendostatic.com/2014.2.716/styles/kendo.common.core.min.css" rel="stylesheet" />
<link href="http://cdn.kendostatic.com/2014.2.716/styles/kendo.default.min.css" rel="stylesheet" />
<link href="http://cdn.kendostatic.com/2014.2.716/styles/kendo.mobile.all.min.css" rel="stylesheet" />

<script src="http://cdn.kendostatic.com/2014.2.716/js/jquery.min.js"></script>
<script src="http://cdn.kendostatic.com/2014.2.716/js/kendo.ui.core.min.js"></script>

Note the ViewPort meta tag. This is important to force the content to the width of the device. On a phone the browser is always the full width of the device, and is not rendered in a smaller window like on a desktop.

I also added a small block of CSS style to force the HTML and the FORM to the full size of the device and remove any margins around the content:

<style>
  /* stretch the form element */
  html, body, FORM { height: 100%; }

  /* remove margin and padding */
  body { margin: 0; padding: 0; }

</style>

Next, in my master page I need to wrap the content of my child pages in a KendoUI view object so that it a correct layout is applied to the content:

<form id="form1" runat="server" style="width: 100%; height: 100%;">

    <div data-role="view" data-title="<%: Page.Title %>" data-layout="layout">

     <asp:ContentPlaceHolder runat="server" ID="mainContent"></asp:ContentPlaceHolder>

    </div>

    <div data-role="layout" data-id="layout">
      <header data-role="header">
        <div data-role="navbar">
          <span data-role="view-title"></span>
        </div>
      </header>
      <footer data-role="footer">
        <uc1:ViewSwitcher runat="server" ID="ViewSwitcher" />
      </footer>
    </div>

</form>

The standard ASP.NET form is forced to full-size, and the content of the child page is entered into the asp:ContentPlaceHolder called mainContent. Below that, I specified the layout of the page on the device and added a nav-bar to contain the title of the page was well as a footer to contain a standard view-switcher. This ViewSwitcher usercontrol is deployed with FriendlyUrls and allows the end-user to easily switch between mobile and desktop renderings of the page.

The final bit on the page, the secret sauce that tells KendoUI to start rendering, is a small block of JavaScript at the very bottom of the page, outside of the form tag:

<script>
  var app = new kendo.mobile.Application (document.getElementById("form1"));
</script>

That’s it! Now the application is ready to render any content that references this site.mobile.master page in a mobile-like manner. Let’s look at how the mobile search page is written to present this content:

<%@ Page Title="Games for Sale" Language="C#" AutoEventWireup="true" 
CodeBehind="Default.mobile.aspx.cs" Inherits="KendoMobile.Products.Default_mobile" 
EnableViewState="false" MasterPageFile="~/Site.mobile.Master" %>

<asp:Content runat="server" ContentPlaceHolderID="mainContent">

    <asp:ListView runat="server" ID="gameList"
      ItemType="KendoMobile.Models.BoardGame"
      ItemPlaceholderID="items"
      SelectMethod="Get">

      <LayoutTemplate>
        <ul data-role="listview" data-style="inset">
          <asp:PlaceHolder runat="server" ID="items" />
        </ul>
      </LayoutTemplate>

      <ItemTemplate>
        <li><a data-rel="external" href="Edit/<%#: Item.ID %>"><%#: Item.Name %></a></li>
      </ItemTemplate>

    </asp:ListView>

</asp:Content>

This looks fairly standard for a child page. Let’s look at the few changes that I’ve added:

  • ViewState is turned off. This is a good practice, but especially on mobile where we don’t want to ship all of that extra nonsense over a wireless connection. In this case, we’re not using ViewState at all, so let’s just turn it off.
  • I have replaced the GridView with a ListView that is showing just the names of the board games. I could add more details to my template, and I’ll leave that experimentation to you with the source attached at the end of this article.
  • The anchor for each item links to Edit/Item.ID This is an example of the FriendUrl that users will see when they visit my application. It’s much easier to manage this way.
  • The link to the item has a data-rel of external, telling KendoUI to load the content as an external URL and not as another div inside this page.

Thanks to the adaptive CSS styling of KendoUI mobile, this page will detect the type of mobile device and the mobile OS requesting content and style it appropriately. Check out how some popular phones render this page:

SearchAllPhones

The C# action behind the Get method is the same as the standard search page. In fact, if I was using the same controls on this page, I could use the same code-behind across both pages. Hmmm…with a little creative planning, I was able to do just that with my Edit.mobile.aspx page:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Edit.aspx.cs" 
  Inherits="KendoMobile.Products.Edit" MasterPageFile="~/Site.mobile.Master" %>

<asp:Content runat="server" ContentPlaceHolderID="mainContent">

    <asp:FormView runat="server" ID="myForm" 
    DefaultMode="Edit" DataKeyNames="Id"
    ItemType="KendoMobile.Models.BoardGame"
    SelectMethod="myForm_GetItem"
    UpdateMethod="myForm_UpdateItem"
    RenderOuterTable="false">

    <EditItemTemplate>

      <ul data-role="listview" data-style="inset">

        <asp:DynamicEntity runat="server" Mode="Edit"></asp:DynamicEntity>

      </ul>

      <div style="width: 100%; text-align: center;">
      <asp:LinkButton data-rel="external" runat="server" ID="submit" CommandName="Update" Text="Save Changes" CssClass="k-button selected-button" data-role="button" />
      <asp:LinkButton data-rel="external" runat="server" ID="cancel" CommandName="Cancel" Text="Cancel" CausesValidation="false" CssClass="k-button " data-role="button" OnClick="cancel_Click" />
        </div>

    </EditItemTemplate>


  </asp:FormView>

</asp:Content>

Other than the extra CssClass and data-role attributes on the LinkButtons at the bottom, it is the same page. I even have the CodeBehind and Inherits attributes pointing to the same files as the original Edit page. The edit page now looks like this:

EditIphone5

Summary

It’s easy to modify an existing ASP.NET project to start adding mobile capabilities to it. If you want your application to act native, to feel native to the mobile users browsing it, give KendoUI Mobile a shot. It’s available as part of KendoUI Core’s Open Source package and you can add references to the Telerik CDN to start using it now. Learn more about how I wrote this and download the source code for this article now: https://github.com/csharpfritz/KendoMobile.

Comments