You could define an Actionfilter like this:
public class SetDeviceDependantView : ActionFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
// Only works on ViewResults...
ViewResultBase viewResult = filterContext.Result as ViewResultBase;
if (viewResult != null)
{
if (filterContext == null)
throw new ArgumentNullException("context");
// Default the viewname to the action name
if (String.IsNullOrEmpty(viewResult.ViewName))
viewResult.ViewName = filterContext.RouteData.GetRequiredString("action");
// Add suffix according to device type
if (IsTablet(filterContext.HttpContext))
viewResult.ViewName += "Tablet";
else if (IsMobile(filterContext.HttpContext))
viewResult.ViewName += "Mobile";
}
base.OnResultExecuting(filterContext);
}
private static bool IsMobile(HttpContextBase httpContext)
{
return httpContext.Request.Browser.IsMobileDevice;
}
private static bool IsTablet(HttpContextBase httpContext)
{
// this requires the 51degrees "Device Data" package: http://51degrees.mobi/Products/DeviceData/PropertyDictionary.aspx
var isTablet = httpContext.Request.Browser["IsTablet"];
return isTablet != null && isTablet.Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase);
}
}
Then you can either annotate the required Actions / Controllers like this:
[SetDeviceDependantView]
public ActionResult About()
{
return View();
}
Or set it globally in the global.asax:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new SetDeviceDependantView());
}
Note, that I'm relying here on the 51degrees library to detect the tablet, you could consider using a different technique. However, that's a different topic.