MVC4 : Mobile Routing : Part 2


Updated 12 March 2012 to support the MVC4 Beta

In part one of this series I showed a brief intro into the view routing capabilities of MVC4. In this article we are going to dig a bit deeper and explore how it can be extended.

While just havingthe ability to redirect to a mobile view is neat, it would be even better to be able to add more conditions and view types than just the existing mobile one.

Fortunately the framework does have this ability.

To create new view versions (DefaultDisplayModes), you add each DefaultDisplayMode in the Application_Start event of the global.asax.cs.  The running application will the select which view to use based on declared conditions being met.

Here is an example of an a DefaultDisplayMode being added to the DisplayModes list

DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("iPhone")
{
ContextCondition = (ctx => ctx.Request.UserAgent.IndexOf(
"iPhone", StringComparison.OrdinalIgnoreCase) >= 0)
});

DisplayModeProvider.Instance is an IList and Modes.Insert is a standard insert with an index and item to be inserted.

The concise format is;

DisplayModeProvider.Instance.Modes.Insert({index}, new DefaultDisplayMode("{DisplayModeName}") {Context})

{Context} is evaluated at runtime and must return a Boolean, If a true is returned then the View Engine attempts to load a view with that Display mode name.

{ActionName}.{DisplayModeName}.{fileType}

The viewengine starts with the very first displaymode in the Displaymodes<IList>  which is at index 0 and iterates through the  Displaymodes<IList>  until a matching view is found.

So given these inserts in this order in code (no context to keep it simple)

DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("Mobile")
DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("Tablet")
DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("AndroidTablet")

The veiwengine would evaluate for AndroidTablet if that fails go to Tablet, then evaluate for mobile.

There already is a default DefaultDisplayMode(“Mobile”) already baked into the framework. Adding another DefaultDiplayMode named mobile does not erase that display mode it just adds another conditional to direct the view engine to use

{Viewname}.mobile.{fileType}

Complex Conditionals

Remember that the evaluation must return a Boolean ? Well that lets you create fairly complex conditions such as this one below.

<p>DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("Mobile")
{
ContextCondition = (ctx =>
ctx.Request.UserAgent.IndexOf("iPad", StringComparison.OrdinalIgnoreCase) >= 0 ||
ctx.Request.UserAgent.IndexOf("android", StringComparison.OrdinalIgnoreCase) >= 0 ||
ctx.Request.UserAgent.IndexOf("iPhone", StringComparison.OrdinalIgnoreCase) >= 0 ||
ctx.Request.UserAgent.IndexOf("Windows Phone OS",StringComparison.OrdinalIgnoreCase)>= 0
)
});

Here the condition is checking for a variety of user agent strings using the OR (||) operator.

To see how far some have taken this, I highly recomend reading Eric Sowell’s blog at www.thecodinghumanist.com

Conclusion 

We really cant wait till this becomes RTM. No really we can’t, we are running  Mobivant.com on the developer’s preview of MVC 4.

I do hope this has helped some of you out there. I promise I will add more as I get time. Wish me luck.

Advertisements