Book Review: Architecting Mobile Solutions for the Enterprise by Dino Esposito, O’Reilly

Dino Esposito is the iconic author in Microsoft Press.  His book “.NET: Architecting for Enterprise” is one of my favorite.  Sequel to this, this book covers wide variety of patterns in addition to practical approaches on various mobile development problems.

First six chapters are worthful sharing of mobile development experience.  The remaining five chapters are splendid collections of design patterns for mobile enterprise.  He shared the design approaches, concepts with very neutral way.  He showcases the approaches iPhone, iPad, Android and Windows Phone respectively.  Unlike part is, Silverlight for Windows Phone.  I really expects Windows 8 series.

Chapter 1 starts with various delivery model, cost of various Marketplaces and device detection strategy.  This is the decent start.  No boring theory…no specific vendor based introduction.  “Marketplace Tax” is the eye-opener for mobile developers.

Chapter 2 covers mobile sites vs native applications.  Though this is not very uncommon, he has given some real truth on problem with mobile web site.  Some of the detailed explanation on taking decision between native vs web can be short.

Chapter 3 covers mobile architecture.  It explains some know myths about mobile architecture.  Good start on architecture perspective.  “Use case for mobile is one of the important step in mobile architecture” is the excellent point to mention.  Dino explains interestingly about the priority of use cases varied from desktop web site to mobile web site.  When your business requires a mobile web site, Dino highly recommend to have separate application layer for mobile web site.  Multiserving is nicely explained.  I enjoyed the WOW concept.

Dino shares his experience on Chapter 4 about “Building mobile web sites”, instead of giving philosophy.  This reaches our mind smoothly.  The way he explained SIP is very practical.  The next two chapters cover HTML 5, jQuery Mobile and Responsive Web design.

The remaining chapters are full-fledged coverage of general patterns, patterns specific to iOS, Android, Windows Phone and PhoneGap.

In this industry, books are still be the main medium.  We may see so many irresponsive and untested philosophy as books.  Dino and Microsoft Press always be cautious about this.  Definitely, this book is MUST HAVE for every mobile developers.  Dino’s coverage is more truthful, tested and consistent.

Well done Dino.

Purchase this book at http://shop.oreilly.com/product/0790145336224.do

Partial View Auto Refresh in ASP.NET MVC3

Problem

A partial view in ASP.NET MVC3 needs to be refreshed on every particular interval.

Let us take a typical ASP.NET MVC3 application. In the HomeController, there is a action called “Quote” which displays funny software quote for every new request like below:

public class HomeController : Controller
{
	public static string[] quotes = {
		"The first 90% of the code accounts for the first 90% of the development time. The remaining 10% of the code accounts for the other 90% of the development time",
		"In order to understand recursion, one must first understand recursion",
		"I have always wished for my computer to be as easy to use as my telephone; my wish has come true because I can no longer figure out how to use my telephone.",
		"The gap between theory and practice is not as wide in theory as it is in practice.",
		"Nine people can’t make a baby in a month"
	};

	// other actions

	public ActionResult Quote()
	{
		var r = new Random();
		var rv = r.Next(0, 4);
		ViewBag.Quote = quotes[rv];
		return PartialView("_Quote");
	}
}

The partial view “_Quote.cshtml” has nothing other than the code below


<h3>@ViewBag.Quote</h3>

This whole thing needs to be refreshed without any user interaction on every 10 seconds

Solution

Use setInterval() at client side and set up OutputCacheAttribute on the respective action. The duration should be same on both side.

In the corresponding script of this view, place the below JavaScript:


// jQuery used

setInterval("$('#quote').load('/home/quote')", 10000); // every 10 sec

In the main view, create a div with id “quote” like:

In the action method set the OutputCacheAttribute like:

[OutputCache(NoStore=true, Location = OutputCacheLocation.Client, Duration = 10)] // every 10 sec
public ActionResult Quote()
{
...
}

Collection Binding in ASP.NET MVC3 with AJAX

There is a less-common scenario in web applications where we need to edit collection of objects and submit the whole back to the system. For example, let us take the below view model:

public class FruitModel...
        public string Name { get; set; }
        public bool IsFresh { get; set; }
        public bool IsPacked { get; set; }
		public decimal UnitPrice { get; set; }

The UI for this scenario is shown below:

Leave the top and bottom “Lorem ipsum” text, these are just gap fillers.  The user can change the “IsFresh” and “IsPacked” settings of the fruits and the unit prices.

Challenge

This post addresses the following simple problems when using ASP.NET MVC3:

  • Sending back collection of data to a MVC action
  • Also send back additional parameter(s) to the same MVC action
  • Sending back read-only data
  • By Ajax

Solution

When the user hitting this site, the HomeController’s Index will be called:
public ActionResult Index()...
	List<FruitModel> collection = new List<FruitModel>()
	{
		new FruitModel {Name = "Apple", IsFresh=true, IsPacked=false, UnitPrice = 10M},
		new FruitModel {Name = "Orange", IsFresh=false, IsPacked=false, UnitPrice = 5M},
		new FruitModel {Name = "Strawberry", IsFresh=true, IsPacked=true, UnitPrice = 15M}
	};
	ViewBag.NetAmount = IncludeTax(collection.Sum(fm => fm.UnitPrice));
	ViewBag.ShopId = Guid.NewGuid();
	return View(collection);
In the Index view, I’ve used NetAmount value of ViewBag as shown below:
</div>
<div>
<pre><h2>Welcome to Fruit Shop</h2>
<div>Lorem ipsum... </div>
<div>
	@Html.Partial("_Fruit", (List<MvcApplication1.Models.FruitModel>)Model)
</div>
<div id="netAmountDiv" name="netAmountDiv" style="color:Blue">
	Net Amount: @ViewBag.NetAmount
</div>
<div>Lorem ipsum...</div>
The main part of the Fruit Shop is defined in _Fruit partial view.  It requires the FruitModel collection and shop ID (in ViewBag).
Simply passing the Model in @Html.Partial(…) will throw the error “‘System.Web.Mvc.HtmlHelper<dynamic>’ has no applicable method named ‘Partial’ but appears to have an extension method by that name. Extension methods cannot be dynamically dispatched. Consider casting the dynamic arguments or calling the extension method without the extension method syntax.”.  So, cast it to appropriate type, here List<MvcApplication1.Models.FruitModel>.
The partial view _Fruit is
</div>
<div>
<pre>@model List<MvcApplication1.Models.FruitModel>

@using (Ajax.BeginForm(new AjaxOptions
        {
            HttpMethod = "Post",
            UpdateTargetId = "netAmountDiv"
        }
))
{

<table>
    <tr>
        <th>
            Name
        </th>
        <th>
            IsFresh
        </th>
        <th>
            IsPacked
        </th>
        <th>Unit Price</th>
    </tr>

@for (int i = 0; i < Model.Count; i++)
{
    <tr>
        <td>
            @Html.DisplayFor(modelItem => Model[i].Name)
            @Html.HiddenFor(modelItem => Model[i].Name)
        </td>
        <td>
            @Html.EditorFor(modelItem => Model[i].IsFresh)
        </td>
        <td>
            @Html.EditorFor(modelItem => Model[i].IsPacked)
        </td>
        <td>
            @Html.EditorFor(modelItem => Model[i].UnitPrice)
        </td>
    </tr>
}

</table>
        <input type="hidden" id="shopId" name="shopId" value="@ViewBag.ShopId" />
        <div>
		    <input name="submitFruit" type="submit" value="Change" />
	    </div>
}
Now the important point here is, when you want to post back collection of FruitModel, the naming pattern of every HTML item in the collection should be “obj-name[index].property-name”.  For example, for the above code, ASP.NET generates HTML for an item like below:
</div>
<div>
<pre><td>
	Apple
	<input name="[0].Name" type="hidden" value="Apple" />
</td>
<td>
	<input checked="checked" class="check-box" data-val="true" data-val-required="The IsFresh field is required." name="[0].IsFresh" type="checkbox" value="true" /><input name="[0].IsFresh" type="hidden" value="false" />
</td>
<td>
	<input class="check-box" data-val="true" data-val-required="The IsPacked field is required." name="[0].IsPacked" type="checkbox" value="true" /><input name="[0].IsPacked" type="hidden" value="false" />
</td>
<td>
	<input class="text-box single-line" data-val="true" data-val-number="The field UnitPrice must be a number." data-val-required="The UnitPrice field is required." name="[0].UnitPrice" type="text" value="10.00" />
</td></pre>
</div>
<div>
This HTML code actually generate a post back collection as shown below when submitting the form.
submitFruit=Change&[0].Name=Apple&[0].IsFresh=true&[0].IsFresh=false&[0].IsPacked=false&
[0].UnitPrice=10.00&[1].Name=Orange&[1].IsFresh=false&[1].IsPacked=true&[1].IsPacked=false&
[1].UnitPrice=5.00&[2].Name=Strawberry&[2].IsFresh=true&[2].IsFresh=false&[2].IsPacked=true&
[2].IsPacked=false&[2].UnitPrice=25&shopId=c9517c6b-c911-4a28-9a0a-3e47ccb60bd8&X-Requested-With=XMLHttpRequest
The above data matched with List<FruitModel> model and with the other parameter name too.  The additional parameter I’m passing is “shopId” hidden value which is received from ViewBag.ShopId.  The main changes I did in the above code are:
  • Used List<T> for @model instead of IEnumerable<T>, hence I can use Count property.
  • Used for i = 0…List<T>.Count instead of foreach.
ASP.NET MVC3 uses “name.propertyname” pattern, if you use “foreach”.  This wouldn’t send back the collection to the server.  Now, let us see the Index action for POST:
</div>
<div>
<pre>[HttpPost]
public ActionResult Index(Guid shopId, List<FruitModel> collection)...
	decimal addlTax = 0M;
	if (collection.Any(fm => fm.UnitPrice > 200)) addlTax += 2M;
	return Content("Net Amount: " + IncludeTax(collection.Sum(fm => fm.UnitPrice) + addlTax).ToString());</pre>
</div>
<div>
Leave the tax calculation stuff, it is just for making some difference from GET Index().  The above method send back the tax calculation as plain text to the client.  This is the place for AJAX.  This can be achieved by Ajax.BeginForm() in the above code, where I’ve mentioned that the result should be placed on an element with id “netAmountDiv”.  So, we can get the result asynchronously.  To make this AJAX.BeginForm() to work, you have to:
  • include jQuery’s unobtrusive AJAX script (jquery.unobtrusive-AJAX.min.js)
  • add “<add key=”UnobtrusiveJavaScriptEnabled” value=”true” />” option in appsetting section of web.config

Also, note that to send read-only item as part of the collection, in the above example FruitModel.Name, use hidden input control also.