我正在使用ASP.NET MVC 3 w / Razor开发一个新项目,并开发同一站点的2个不同视图,完整版和移动版。使用相同控制器的最佳实践/方法是什么,但是根据用户代理显示不同的视图?我应该在控制器中处理这个吗?似乎麻烦,冗余,容易出错,每个控制器操作中的if语句都会检查用户代理,然后根据其设备返回不同的视图。
答案 0 :(得分:9)
现在可以使用ASP.NET MVC的内置功能(从版本4开始)称为“DisplayModes”
默认情况下,ASP.NET MVC内置两种显示模式。有默认的显示模式,它可以像往常一样呈现“标准”视图,并且还有一个通用的“移动”显示模式。
这通过检测客户端设备是否是移动浏览器(其本身是通过嗅探客户端设备的User-Agent string来确定,因此不是100%可靠)来工作。如果确定设备是移动设备,则覆盖发送到客户端的实际MVC视图,并且替代地呈现并发送替代视图。在包含移动显示模式的情况下,它被配置为查找后缀为.mobile.cshtml
而不是.cshtml
的视图(如下面的屏幕截图所示)
这允许您设计完全不同的视图,这些视图将发送到移动设备和非移动设备,而不需要对控制器逻辑进行任何更改,因此您不需要包含任何条件在那里的逻辑。
如果您需要对发送到客户端设备的确切视图进行更细粒度的控制,则整个显示模式功能是可配置和可扩展的。您可以定义自己的显示模式(通常在“应用程序启动”中执行),这些模式可以特定于给定的浏览器,给定设备或您希望的任何任意定义。所有这些都基于来自客户端设备的用户代理字符串。
请考虑下面的代码片段,其中显示了在Application Start方法中为Windows Phone,iPhone和Android添加3个其他自定义显示模式:
protected void Application_Start()
{
DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("WP")
{
ContextCondition = (context => context.GetOverriddenUserAgent().
IndexOf("Windows Phone OS",StringComparison.OrdinalIgnoreCase) >= 0)
});
DisplayModeProvider.Instance.Modes.Insert(1, new DefaultDisplayMode("iPhone")
{
ContextCondition = (context => context.GetOverriddenUserAgent().
IndexOf("iPhone", StringComparison.OrdinalIgnoreCase) >= 0)
});
DisplayModeProvider.Instance.Modes.Insert(2, new DefaultDisplayMode("Android")
{
ContextCondition = (context => context.GetOverriddenUserAgent().
IndexOf("Android", StringComparison.OrdinalIgnoreCase) >= 0)
});
}
为每个显示模式提供ID和要与用户代理字符串匹配的字符串,以确定是否要使用此显示模式。如果是,则DisplayModeProvider将查找具有相同字符串后缀的View。 (即对于上面的iPhone显示模式,我们希望在用户代理字符串中的任何位置找到字符串“iPhone”,如果它存在,我们使用这种显示模式,使用iphone.cshtml
后缀而不是{{ {1}}后缀。
您可以在此处详细了解此功能: http://www.asp.net/mvc/overview/older-versions/aspnet-mvc-4-mobile-features 特别是在“覆盖视图,布局和部分视图”和“特定于浏览器的视图”部分中。