次のように Actionfilter を定義できます。
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);
}
}
次に、必要なアクション/コントローラーに次のように注釈を付けることができます。
[SetDeviceDependantView]
public ActionResult About()
{
return View();
}
または、global.asax でグローバルに設定します。
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new SetDeviceDependantView());
}
ここではタブレットを検出するために 51degrees ライブラリに依存していることに注意してください。別の手法の使用を検討することもできます。ただし、それは別のトピックです。