Mobile ASP.NET Development: Indentifying the main Japanese carriers (DoCoMo, Softbank, AU KDDI, JPhone, Vodafone)

Introduction
Those of you who have delved into developing mobile sites with ASP.NET mobile controls, may have come up against a lack of real world examples in the documentation. The benefits of dynamic rendering and device specific rendering look great on paper, but as I have found, while it works a lot of the time there are some limitations. In Japan there are several main carriers who each offer different browsers and capabilities, while this article doesn’t dig deeply into these as there are plenty of online resources and each of the carriers have their own development portals where you can easily find the information you may need. This article describes a way of identifying the main Japanese carriers so that you can handle the user experience accordingly.

Method

So how do you do that then? well simply put, each of these carriers browsers have distinct user agents, so we are going create a custom capabilities class to parse the user agent string. To make this work we also need to add a deviceFilters section to our web.config file and lastly we are going to use a DeviceSpecific control in our mobile ASPX page to dynamically render content on a per carrier basis.

Mobile ASPX
The string you use for the choice filter must match the name of the device filter in your web.config it is case specific so be careful. Also note that I have surrounded the deviceSpecific control with a panel, this then enables me to find the control in ContentTemplate that I want to manipulate:


Literal litLink = (Literal)pnCarrier.Content.FindControl("litLink");



<mobile:Panel ID="pnlCarrier" runat="server">
<DeviceSpecific ID="dsCarrier" runat="server">
<Choice Filter="isDocomo">
<ContentTemplate>
<asp:literal id="litLink" runat="server" /><mobile:TextView ID="tvBreak" Runat="server"><br></mobile:TextView>
</ContentTemplate>
</Choice>
<Choice Filter="isSoftbank">
<ContentTemplate>
<asp:literal id="litLink" runat="server" /><mobile:TextView ID="tvBreak" Runat="server"><br></mobile:TextView>
</ContentTemplate>
</Choice>
<Choice Filter="isAuKddi">
<ContentTemplate>
<asp:literal id="litLink" runat="server" /><mobile:TextView ID="tvBreak" Runat="server"><br></mobile:TextView>
</ContentTemplate>
</Choice>
<Choice Filter="isJPhone">
<ContentTemplate>
<asp:literal id="litLink" runat="server" /><mobile:TextView ID="tvBreak" Runat="server"><br></mobile:TextView>
</ContentTemplate>
</Choice>
</DeviceSpecific>
</mobile:Panel>



Code Behind
This code evaluates the selected choice in the device specific control and renders a string accordingly, obviously you would do some more exciting stuff once you have determined the carrier, I used a literal to assign a string for example purposes.



if (dsCarrier.SelectedChoice == null) return;

Literal litLink = (Literal)pnCarrier.Content.FindControl("litLink");
switch (dsCarrier.SelectedChoice.Filter)
{
case MobileFilterNames.isDocomo:
litLink.Text = "DoCoMo";
break;
case MobileFilterNames.isAuKddi:
litLink.Text = "AU KDDI";
break;
case MobileFilterNames.isSoftbank:
litLink.Text = "SoftBank";
break;
case MobileFilterNames.isJPhone:
litLink.Text = "J-Phone";
break;
}



Custom Capabilities Class Code

Each of the methods which evaluate the carrier take the parameters MobileCapabilities and a string argument, they are also public and static and return boolean values.


using System.Web;
using System.Web.Mobile;

namespace Dlr
{
public class MobileCapabilityEvaluators
{
#region MemberVariables

private readonly static string[] SoftBankUserAgentList = new string[]
{
"Vodafone",
"SoftBank",
};

private readonly static string[] JphoneUserAgentList = new string[]
{
"J-PHONE",
};

private readonly static string[] AuKddiUserAgentList = new string[]
{
"KDDI",
};

private readonly static string[] DocomoUserAgentList = new string[]
{
"DOCOMO/2.0",
};

private readonly static string[] RegularUserAgentList = new string[]
{
"Mozilla/4.0",
"Mozilla/5.0",
};

#endregion

#region isSoftBank

/// <summary>
/// Determines whether [is soft bank] [the specified capabilities].
/// </summary>
/// <param name="capabilities">The capabilities.</param>
/// <param name="argument">The argument.</param>
/// <returns>
/// <c>true</c> if [is soft bank] [the specified capabilities]; otherwise, <c>false</c>.
/// </returns>
public static bool IsSoftbank(MobileCapabilities capabilities, string argument)
{
if (HttpContext.Current.Request.UserAgent != null)
{
string[] agentInfo = HttpContext.Current.Request.UserAgent.Split('/');
if (agentInfo.Length == 0)
return false;
foreach (string agent in SoftBankUserAgentList)
if (agentInfo[0].ToLower().Contains(agent.ToLower()))
return true;
}
return false;
}

#endregion

#region isJPhone

/// <summary>
/// Determines whether [is soft bank] [the specified capabilities].
/// </summary>
/// <param name="capabilities">The capabilities.</param>
/// <param name="argument">The argument.</param>
/// <returns>
/// <c>true</c> if [is soft bank] [the specified capabilities]; otherwise, <c>false</c>.
/// </returns>
public static bool IsJPhone(MobileCapabilities capabilities, string argument)
{
if (HttpContext.Current.Request.UserAgent != null)
{
string[] agentInfo = HttpContext.Current.Request.UserAgent.Split('/');
if (agentInfo.Length == 0)
return false;
foreach (string agent in JphoneUserAgentList)
if (agentInfo[0].ToLower().Contains(agent.ToLower()))
return true;
}
return false;
}

#endregion

#region isAuKddi

/// <summary>
/// Determines whether [is au kddi] [the specified capabilities].
/// </summary>
/// <param name="capabilities">The capabilities.</param>
/// <param name="argument">The argument.</param>
/// <returns>
/// <c>true</c> if [is au kddi] [the specified capabilities]; otherwise, <c>false</c>.
/// </returns>
public static bool IsAuKddi(MobileCapabilities capabilities, string argument)
{
if (HttpContext.Current.Request.UserAgent != null)
{
string[] agentInfo = HttpContext.Current.Request.UserAgent.Split('/');
if (agentInfo.Length == 0)
return false;
foreach (string agent in AuKddiUserAgentList)
if (agentInfo[0].ToLower().Contains(agent.ToLower()))
return true;
}
return false;
}

#endregion

#region isDocomo

/// <summary>
/// Determines whether [is docomo] [the specified capabilities].
/// </summary>
/// <param name="capabilities">The capabilities.</param>
/// <param name="argument">The argument.</param>
/// <returns>
/// <c>true</c> if [is docomo] [the specified capabilities]; otherwise, <c>false</c>.
/// </returns>
public static bool IsDocomo(MobileCapabilities capabilities, string argument)
{
if (HttpContext.Current.Request.UserAgent != null)
{
string userAgent = HttpContext.Current.Request.UserAgent;
if (userAgent.Length == 0)
return false;
foreach (string agent in DocomoUserAgentList)
if (userAgent.ToLower().Contains(agent.ToLower()))
return true;
}
return false;
}

#endregion

#region isRegular

/// <summary>
/// Determines whether [is regular] [the specified capabilities].
/// </summary>
/// <param name="capabilities">The capabilities.</param>
/// <param name="argument">The argument.</param>
/// <returns>
/// <c>true</c> if [is regular] [the specified capabilities]; otherwise, <c>false</c>.
/// </returns>
public static bool IsRegular(MobileCapabilities capabilities, string argument)
{
if (HttpContext.Current.Request.UserAgent != null)
{
string userAgent = HttpContext.Current.Request.UserAgent;
if (userAgent.Length == 0)
return false;
foreach (string agent in RegularUserAgentList)
if (userAgent.ToLower().Contains(agent.ToLower()))
return true;
}
return false;
}

#endregion
}
}


web.config
Notice each filter has a unique name, points to the class and assembly and lastly indicates the method in the class used to determine whether the filter returns true.


<deviceFilters>
<filter name="isDocomo" type="Dlr.MobileCapabilityEvaluators,Dlr " method="IsDocomo"/>
<filter name="isSoftbank" type="Dlr.MobileCapabilityEvaluators,Dlr " method="IsSoftbank"/>
<filter name="isAuKddi" type="Dlr.MobileCapabilityEvaluators,Dlr " method="IsAuKddi"/>
<filter name="isRegular" type="Dlr.MobileCapabilityEvaluators,Dlr " method="IsRegular"/>
<filter name="isJPhone" type="Dlr. MobileCapabilityEvaluators,Dlr " method="IsJPhone"/>
</deviceFilters>

kick it on DotNetKicks.com