在 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
(可能是从您正在使用的那个派生而来)并覆盖FindView
和FindPartialView
。您可以提供备用方案(即,如果没有找到平板电脑,则使用通用视图)。
最麻烦的是定义区分不同“模式”的标准。
【讨论】:
【参考方案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 中创建带有可点击选项的水平条形图? [关闭]