网站就必须用响应式布局吗?MVC视图展现模式之移动布局:http://www.cnblogs.com/dunitian/p/5213787.html

demo:http://pan.baidu.com/s/1bnTUaKJ

有人会疑问,为什么他能识别.mobile的后缀却不能识别例如:.mac .dnt 等等后缀呢?这些又是放在哪里的呢?

mobile 这个后缀其实是存放在:DisplayModeProvider.Instance.Modes 里面的,我们监视一下,发现里面就一个mobile,还有一个是默认的

可以猜想,运行的时候是从上往下匹配的,“”的是通用匹配,那么我们加入一个自定义的后缀看看==>(可以思考一下,为什么用 insert 不用 add)

            //添加一个自定义后缀
DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("dnt")
{
ContextCondition = (Context) => Context.Request.UserAgent.Contains("dnt")
});

可能你不是很理解 DefaultDisplayMode,看看反编译吧----构造函数为suffix赋值(后缀)

添加一个自定义的后缀视图

打开谷歌浏览器,设置一下User-Agent Switcher的浏览模式

附录:

DisplayModeProvider:

// Generated by .NET Reflector from F:\Work\Net\Mobile\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll
namespace System.Web.WebPages
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Web; public sealed class DisplayModeProvider
{
private static readonly object _displayModeKey = new object();
private readonly List<IDisplayMode> _displayModes;
private static readonly DisplayModeProvider _instance = new DisplayModeProvider();
public static readonly string DefaultDisplayModeId = string.Empty;
public static readonly string MobileDisplayModeId = "Mobile"; internal DisplayModeProvider()
{
List<IDisplayMode> list = new List<IDisplayMode>();
DefaultDisplayMode item = new DefaultDisplayMode(MobileDisplayModeId) {
ContextCondition = context => context.GetOverriddenBrowser().IsMobileDevice
};
list.Add(item);
list.Add(new DefaultDisplayMode());
this._displayModes = list;
} private int FindFirstAvailableDisplayMode(IDisplayMode currentDisplayMode, bool requireConsistentDisplayMode)
{
if (!requireConsistentDisplayMode || (currentDisplayMode == null))
{
return ;
}
int index = this._displayModes.IndexOf(currentDisplayMode);
if (index < )
{
return this._displayModes.Count;
}
return index;
} public IEnumerable<IDisplayMode> GetAvailableDisplayModesForContext(HttpContextBase httpContext, IDisplayMode currentDisplayMode)
{
return this.GetAvailableDisplayModesForContext(httpContext, currentDisplayMode, this.RequireConsistentDisplayMode);
} internal IEnumerable<IDisplayMode> GetAvailableDisplayModesForContext(HttpContextBase httpContext, IDisplayMode currentDisplayMode, bool requireConsistentDisplayMode)
{
int iteratorVariable0 = this.FindFirstAvailableDisplayMode(currentDisplayMode, requireConsistentDisplayMode);
for (int i = iteratorVariable0; i < this._displayModes.Count; i++)
{
IDisplayMode iteratorVariable2 = this._displayModes[i];
if (iteratorVariable2.CanHandleContext(httpContext))
{
yield return iteratorVariable2;
}
}
} public DisplayInfo GetDisplayInfoForVirtualPath(string virtualPath, HttpContextBase httpContext, Func<string, bool> virtualPathExists, IDisplayMode currentDisplayMode)
{
return this.GetDisplayInfoForVirtualPath(virtualPath, httpContext, virtualPathExists, currentDisplayMode, this.RequireConsistentDisplayMode);
} internal DisplayInfo GetDisplayInfoForVirtualPath(string virtualPath, HttpContextBase httpContext, Func<string, bool> virtualPathExists, IDisplayMode currentDisplayMode, bool requireConsistentDisplayMode)
{
for (int i = this.FindFirstAvailableDisplayMode(currentDisplayMode, requireConsistentDisplayMode); i < this._displayModes.Count; i++)
{
IDisplayMode mode = this._displayModes[i];
if (mode.CanHandleContext(httpContext))
{
DisplayInfo info = mode.GetDisplayInfo(httpContext, virtualPath, virtualPathExists);
if (info != null)
{
return info;
}
}
}
return null;
} internal static IDisplayMode GetDisplayMode(HttpContextBase context)
{
if (context == null)
{
return null;
}
return (context.Items[_displayModeKey] as IDisplayMode);
} internal static void SetDisplayMode(HttpContextBase context, IDisplayMode displayMode)
{
if (context != null)
{
context.Items[_displayModeKey] = displayMode;
}
} public static DisplayModeProvider Instance
{
get
{
return _instance;
}
} public IList<IDisplayMode> Modes
{
get
{
return this._displayModes;
}
} public bool RequireConsistentDisplayMode { get; set; } [CompilerGenerated]
private sealed class <GetAvailableDisplayModesForContext>d__4 : IEnumerable<IDisplayMode>, IEnumerable, IEnumerator<IDisplayMode>, IEnumerator, IDisposable
{
private int <>1__state;
private IDisplayMode <>2__current;
public IDisplayMode <>3__currentDisplayMode;
public HttpContextBase <>3__httpContext;
public bool <>3__requireConsistentDisplayMode;
public DisplayModeProvider <>4__this;
private int <>l__initialThreadId;
public int <first>5__5;
public int <i>5__6;
public IDisplayMode <mode>5__7;
public IDisplayMode currentDisplayMode;
public HttpContextBase httpContext;
public bool requireConsistentDisplayMode; [DebuggerHidden]
public <GetAvailableDisplayModesForContext>d__4(int <>1__state)
{
this.<>1__state = <>1__state;
this.<>l__initialThreadId = Environment.CurrentManagedThreadId;
} private bool MoveNext()
{
switch (this.<>1__state)
{
case :
this.<>1__state = -;
this.<first>5__5 = this.<>4__this.FindFirstAvailableDisplayMode(this.currentDisplayMode, this.requireConsistentDisplayMode);
this.<i>5__6 = this.<first>5__5;
goto Label_00A5; case :
this.<>1__state = -;
break; default:
goto Label_00BD;
}
Label_0097:
this.<i>5__6++;
Label_00A5:
if (this.<i>5__6 < this.<>4__this._displayModes.Count)
{
this.<mode>5__7 = this.<>4__this._displayModes[this.<i>5__6];
if (this.<mode>5__7.CanHandleContext(this.httpContext))
{
this.<>2__current = this.<mode>5__7;
this.<>1__state = ;
return true;
}
goto Label_0097;
}
Label_00BD:
return false;
} [DebuggerHidden]
IEnumerator<IDisplayMode> IEnumerable<IDisplayMode>.GetEnumerator()
{
DisplayModeProvider.<GetAvailableDisplayModesForContext>d__4 d__;
if ((Environment.CurrentManagedThreadId == this.<>l__initialThreadId) && (this.<>1__state == -))
{
this.<>1__state = ;
d__ = this;
}
else
{
d__ = new DisplayModeProvider.<GetAvailableDisplayModesForContext>d__4() {
<>4__this = this.<>4__this
};
}
d__.httpContext = this.<>3__httpContext;
d__.currentDisplayMode = this.<>3__currentDisplayMode;
d__.requireConsistentDisplayMode = this.<>3__requireConsistentDisplayMode;
return d__;
} [DebuggerHidden]
IEnumerator IEnumerable.GetEnumerator()
{
return this.System.Collections.Generic.IEnumerable<System.Web.WebPages.IDisplayMode>.GetEnumerator();
} [DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
} void IDisposable.Dispose()
{
} IDisplayMode IEnumerator<IDisplayMode>.Current
{
[DebuggerHidden]
get
{
return this.<>2__current;
}
} object IEnumerator.Current
{
[DebuggerHidden]
get
{
return this.<>2__current;
}
}
}
}
}

DefaultDisplayMode:

// Generated by .NET Reflector from F:\Work\Net\Mobile\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll
namespace System.Web.WebPages
{
using System;
using System.IO;
using System.Runtime.CompilerServices;
using System.Web; public class DefaultDisplayMode : IDisplayMode
{
private readonly string _suffix; public DefaultDisplayMode() : this(DisplayModeProvider.DefaultDisplayModeId)
{
} public DefaultDisplayMode(string suffix)
{
this._suffix = suffix ?? string.Empty;
} public bool CanHandleContext(HttpContextBase httpContext)
{
if (this.ContextCondition != null)
{
return this.ContextCondition(httpContext);
}
return true;
} public virtual DisplayInfo GetDisplayInfo(HttpContextBase httpContext, string virtualPath, Func<string, bool> virtualPathExists)
{
string arg = this.TransformPath(virtualPath, this._suffix);
if ((arg != null) && virtualPathExists(arg))
{
return new DisplayInfo(arg, this);
}
return null;
} protected virtual string TransformPath(string virtualPath, string suffix)
{
if (string.IsNullOrEmpty(suffix))
{
return virtualPath;
}
string extension = Path.GetExtension(virtualPath);
return Path.ChangeExtension(virtualPath, suffix + extension);
} public Func<HttpContextBase, bool> ContextCondition { get; set; } public virtual string DisplayModeId
{
get
{
return this._suffix;
}
}
}
}

参考:https://msdn.microsoft.com/en-us/magazine/hh975347.aspx

http://www.asp.net/mvc/overview/older-versions/aspnet-mvc-4-mobile-features

http://stackoverflow.com/questions/9354188/asp-net-mvc-4-mobile-display-modes-stop-working

MVC视图展现模式之移动布局解析-续集的更多相关文章

  1. 网站就必须用响应式布局吗?MVC视图展现模式之移动布局

    本文先引入给读者一个自己研究的机会,下次深入说明一下: 废话不多说,直接上图 新建一个mvc的项目 在视图里面添加一个移动端视图 正常访问一下 Bootstrap自带的响应式的方式(页面代码并没有改变 ...

  2. MVC视图展现模式之移动布局

    参考:http://www.cnblogs.com/dunitian/p/5218140.html 简单点,直接上用法 新建MVC项目,在golbal.asax中添加如下代码 //添加一个自定义后缀 ...

  3. Spring MVC视图解析器

    Spring MVC提供的视图解析器使用ViewResolver进行视图解析,实现浏览器中渲染模型.ViewResolver能够解析JSP.Velocity模板.FreeMarker模板和XSLT等多 ...

  4. ASP.NET Core 入门教程 6、ASP.NET Core MVC 视图布局入门

    一.前言 1.本教程主要内容 ASP.NET Core MVC (Razor)视图母版页教程 ASP.NET Core MVC (Razor)带有Section的视图母版页教程 ASP.NET Cor ...

  5. 模型-视图-控制器模式(MVC模式,10种常见体系架构模式之一)

    一.简介: 架构模式是一个通用的.可重用的解决方案,用于在给定上下文中的软件体系结构中经常出现的问题.架构模式与软件设计模式类似,但具有更广泛的范围. 模型-视图-控制器模式,也称为MVC模式.是软件 ...

  6. ASP.NET Core 入门笔记7,ASP.NET Core MVC 视图布局入门

    一.前言 1.本教程主要内容 ASP.NET Core MVC (Razor)视图母版页教程 ASP.NET Core MVC (Razor)带有Section的视图母版页教程 ASP.NET Cor ...

  7. 二、ASP.NET MVC Controller 控制器(一:深入解析控制器运行原理)

    阅读目录: 1.开篇介绍 2.ASP.NETMVC Controller 控制器的入口(Controller的执行流程) 3.ASP.NETMVC Controller 控制器的入口(Controll ...

  8. NET/ASP.NET MVC Controller 控制器(一:深入解析控制器运行原理)

    阅读目录: 1.开篇介绍 2.ASP.NETMVC Controller 控制器的入口(Controller的执行流程) 3.ASP.NETMVC Controller 控制器的入口(Controll ...

  9. Asp.net MVC 视图之公用代码

    一.公共模板 转自:http://www.cnblogs.com/kissdodog/archive/2013/01/07/2848881.html 1.@RenderBody() 在网站公用部分通过 ...

随机推荐

  1. NodeJs之pm2

    pm2 pm2是一个进程管理工具,可以用它来管理你的node进程,并查看node进程的状态,当然也支持性能监控,进程守护,负载均衡等功能. 开发过程中建议时不时的参看官方详细命令行使用:命令行 pm2 ...

  2. 通过ProGet搭建一个内部的Nuget服务器

    .NET Core项目完全使用Nuget 管理组件之间的依赖关系,Nuget已经成为.NET 生态系统中不可或缺的一个组件,从项目角度,将项目中各种组件的引用统统交给NuGet,添加组件/删除组件/以 ...

  3. UWP学习目录整理

    UWP学习目录整理 0x00 可以忽略的废话 10月6号靠着半听半猜和文字直播的补充看完了微软的秋季新品发布会,信仰充值成功,对UWP的开发十分感兴趣,打算后面找时间学习一下.谁想到学习的欲望越来越强 ...

  4. 戏说HTML5

    如果有非技术人员问你,HTML5是什么,你会怎么回答? 新的HTML规范... 给浏览器提供了牛逼能力,干以前不能干的事...(确切地说应该是给浏览器规定了许多新的接口标准,要求浏览器实现牛逼的功能. ...

  5. 【HanLP】资料链接汇总

    Java中调用HanLP配置 HanLP自然语言处理包开源官方文档 了解HanLP的全部 自然语言处理HanLP 开源自由的汉语言处理包主页 GitHub源码 基于hanLP的中文分词详解-MapRe ...

  6. $ORACLE_HOME变量值末尾多“/”惹的祸

    之前一直误以为$ORACLE_HOME变量的路径中末尾多写一个"/"不会有影响. 今天做实验时碰到一个情景,发现并不是这样. 环境:OEL 5.7 + Oracle 10.2.0. ...

  7. Asp.Net WebApi核心对象解析(上篇)

    生活需要自己慢慢去体验和思考,对于知识也是如此.匆匆忙忙的生活,让人不知道自己一天到晚都在干些什么,似乎每天都在忙,但又好似不知道自己到底在忙些什么.不过也无所谓,只要我们知道最后想要什么就行.不管怎 ...

  8. MySQL 系列(三)你不知道的 视图、触发器、存储过程、函数、事务、索引、语句

    第一篇:MySQL 系列(一) 生产标准线上环境安装配置案例及棘手问题解决 第二篇:MySQL 系列(二) 你不知道的数据库操作 第三篇:MySQL 系列(三)你不知道的 视图.触发器.存储过程.函数 ...

  9. C# 程序中嵌入百度地图

    本例是对WinForm中使用百度地图的简要介绍.百度地图目前支持Android开发,IOS开发,Web开发,服务接口,具体可以参照'百度地图开放平台'. [动态加载百度地图]涉及到的知识点: WebB ...

  10. EntityFramework 6 + Mysql 生成POCOs

    问题 使用EDMX文件 EF Power Tools参数不正确的解决方法 对于"异常来自 HRESULT:0x80070057 (E_INVALIDARG)",有方法说" ...