Display device specific views in MVC 3
In MVC 3, view can be render based in requested device, each
request come with browser type string called “User-Agent” string.
Example of user-agent sting as below
Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_3 like Mac OS X;
en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2
Safari/6533.18.5
Mozilla/5.0 (iPad; U; CPU OS 4_3_3 like Mac OS X; en-us)
AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2
Safari/6533.18.5
Mozilla/5.0 (Linux; U; Android 2.3.5; en-us; HTC Vision
Build/GRI40) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile
Safari/533.1
Mozilla/5.0 (BlackBerry; U; BlackBerry 9850; en-US)
AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.0.0.115 Mobile Safari/534.11+
BlackBerry9700/5.0.0.862 Profile/MIDP-2.1
Configuration/CLDC-1.1 VendorID/167
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 7.1;
Trident/5.0)
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64;
Trident/5.0; SLCC2; Media Center PC 6.0; InfoPath.3; MS-RTC LM 8; Zune 4.7)
To override default behaviour of MVC rendering engine, create a class with inherit from RazorViewEngine as below;
Internal class MobileViewEngine : RazorViewEngine
{
public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
ViewEngineResult result = null;
var request = controllerContext.HttpContext.Request;
if (request.IsSupportedMobileDevice() && HttpExtentions.HasMobileSpecificViews)
{
var viewPathAndName = request.GetMobileViewsDirectoryName() + viewName;
result = base.FindView(controllerContext, viewPathAndName, masterName, true);
if (result == null || result.View == null)
{
result = base.FindView(controllerContext, viewPathAndName, masterName, false);
}
}
else
{
result = base.FindView(controllerContext, viewName, masterName, useCache);
}
return result;
}
protected override bool FileExists(ControllerContext controllerContext, string virtualPath)
{
return base.FileExists(controllerContext, virtualPath);
}
public override ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
{
return base.FindPartialView(controllerContext, partialViewName, useCache);
}
}
<configSections>
<!--your other sections-->
<section name="viewTypeSettings" type="Mvc3Demo.Core.ViewTypeSettings,Mvc3Demo" />
</configSections>
<viewTypeSettings>
<viewTypes>
<viewType name="Phone" deviceIdentifiers="iPhone,iPod,Droid,Blackberry"></viewType>
<viewType name="Tablet" deviceIdentifiers="iPad,Playbook,Transformer,Xoom"></viewType>
</viewTypes>
</viewTypeSettings>
If you request URL is http://youdomain.com/home/ from desktop then Home/index.schtml view will be displayed, if request come from any tablet then Home/Tablet/index.schtml view will be displayed, if request come from any mobile then Home/Mobile/index.schtml view will be displayed.
In the MobileViewEngine, we have used an extension method which is a static class as below
public static class HttpExtentions
{
private static readonly bool ConfigCheck;
private static readonly IEnumerable<DeviceType> MobileDevicesList;
static HttpExtentions()
{
var customSettins = ViewTypeSettings.Settings;
MobileDevicesList = customSettins.ViewTypes
.Select(x => new DeviceType
{
ViewType = x.Name,
DeviceIdentifiers = x.DeviceIdentifiers.Split(',')
})
.ToList();
ConfigCheck = MobileDevicesList.Any();
}
public static bool HasMobileSpecificViews
{
get { return ConfigCheck; }
}
/// <summary>
/// Used to enable debugging using alternative devices
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public static bool IsSupportedMobileDevice(this HttpRequestBase request)
{
bool isMobile = request.Browser.IsMobileDevice;
string userAgent = request.UserAgent.ToLowerInvariant();
isMobile = isMobile || MobileDevicesList.Any(x => x.DeviceIdentifiers.Any(userAgent.Contains));
return isMobile;
}
/// <summary>
/// Gets the name of the mobile views directory.
/// </summary>
/// <value>
/// The name of the mobile views directory.
/// </value>
public static string GetMobileViewsDirectoryName(this HttpRequestBase request)
{
var directoryName = string.Empty;
string userAgent = request.UserAgent.ToLowerInvariant();
var deviceType = MobileDevicesList
.First(x => x.DeviceIdentifiers.Any(userAgent.Contains));
if (deviceType != null)
{
directoryName = deviceType.ViewType;
}
return !string.IsNullOrEmpty(directoryName) ? String.Format("{0}/", directoryName) : string.Empty;
}
public static string GetUserIpAddress(this HttpRequestBase request)
{
return request.UserHostAddress;
//return request.ServerVariables["REMOTE_ADDR"];
}
public static string GetHostName(this HttpRequestBase request)
{
IPHostEntry ip = Dns.GetHostEntry(request.UserHostName);
return ip.HostName;
}
}
internal class DeviceType
{
public string ViewType { get; set; }
public string[] DeviceIdentifiers { get; set; }
}
No comments :
Post a Comment