在 ASP.NET MVC 3 中创建基于平台显示不同视图的自定义 ViewResult

Posted

技术标签:

【中文标题】在 ASP.NET MVC 3 中创建基于平台显示不同视图的自定义 ViewResult【英文标题】:Creating a custom ViewResult that displays a different view based on platform in ASP.NET MVC 3 【发布时间】:2012-07-16 20:45:43 【问题描述】:

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

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

【问题讨论】:

为什么不指定不同的样式表而不是不同的视图?这似乎与 MVC 模式背道而驰。 因为这些页面上的内容不同,我们希望使用相同的控制器。 MVC4 使用 DisplayModes 可能会做得更好,如果您可以等待 MVC4 到 RTM。 @vcsjones 我更愿意在某种程度上模拟该功能。 【参考方案1】:

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

【讨论】:

我不确定它是否能开箱即用,但源代码应该足以让我继续前进。谢谢!【参考方案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 库来检测平板电脑,您可以考虑使用不同的技术。但是,这是一个不同的主题。

【讨论】:

【参考方案3】:

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

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

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

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

【讨论】:

【参考方案4】:

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

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

【讨论】:

【参考方案5】:

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

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

【讨论】:

以上是关于在 ASP.NET MVC 3 中创建基于平台显示不同视图的自定义 ViewResult的主要内容,如果未能解决你的问题,请参考以下文章

使用 C# 在 ASP.NET MVC 3 中创建级联下拉列表的最简单方法

在 Asp.net Identity MVC 5 中创建角色

如何在 ASP .net MVC 4 应用程序的 HTML5 中创建带有可点击选项的水平条形图? [关闭]

如何在 ASP.NET MVC 中创建 CheckBoxListFor 扩展方法?

ASP.NET MVC 3 - 部分与显示模板与编辑器模板

如何在 C# Asp.net MVC 中创建 websocket 客户端?