2

我正在尝试让我的 Action 针对不同的平台返回不同的视图,同时尊重路由配置。如果我创建自定义 ViewResult,我会覆盖 FindView 方法吗?如果是这样,我该如何修改自动找到的视图?

例如:HomeController.About 动作将在计算机上显示 View\Home\About.cshtml,在平板电脑上显示 View\Home\AboutTablet.cshtml,在手机上显示 View\Home\AboutMobile.cshtml

4

5 回答 5

2

有一个 NuGet 适合您:MobileViewEngines。ScottHa 在一篇文中介绍了它。它的规范与 ASP.NET MVC 4 兼容,您可以轻松摆脱它,因为此功能是内置的。

于 2012-07-26T06:56:06.187 回答
2

你可以像这样定义一个 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 库来检测平板电脑,您可以考虑使用不同的技术。然而,这是一个不同的话题。

于 2012-07-29T14:03:18.260 回答
0

如果您想在 MVC4 之前执行此操作,请查看 Christopher Bennage 的这篇博文

http://dev.bennage.com/blog/2012/04/27/render-action/

我对 ContentTypeAwareResult 类特别感兴趣,它看起来可能就是您正在寻找的。

https://github.com/liike/reference-application/blob/master/MileageStats.Web/ContentTypeAwareResult.cs

于 2012-07-16T20:59:54.043 回答
0

您必须创建自己的ViewEngine(可能是从您正在使用的那个派生的)并覆盖FindViewand FindPartialView。您可以提供备用方案(即,如果没有找到平板电脑,则使用通用视图)。

最麻烦的是定义区分不同“模式”的标准。

于 2012-07-24T15:09:52.827 回答
0

构建自定义 ViewEngine 是 MVC3 中满足此要求的首选方法。供您参考 - MVC4 开箱即用地支持此功能。

有关设备特定视图的更多信息,在 StackOverflow 上发布了类似的答案https://stackoverflow.com/a/1387555/125651

于 2012-07-26T06:51:05.633 回答