1. 程式人生 > >MVC檢視展現模式之移動佈局解析-續集

MVC檢視展現模式之移動佈局解析-續集

有人會疑問,為什麼他能識別.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 0; } int index = this._displayModes.IndexOf(currentDisplayMode); if (index < 0) { 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 0: this.<>1__state = -1; this.<first>5__5 = this.<>4__this.FindFirstAvailableDisplayMode(this.currentDisplayMode, this.requireConsistentDisplayMode); this.<i>5__6 = this.<first>5__5; goto Label_00A5; case 1: this.<>1__state = -1; 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 = 1; 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 == -2)) { this.<>1__state = 0; d__ = this; } else { d__ = new DisplayModeProvider.<GetAvailableDisplayModesForContext>d__4(0) { <>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; } } } } }
View Code

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;
            }
        }
    }
}
View Code

相關推薦

MVC檢視展現模式移動佈局解析-續集

有人會疑問,為什麼他能識別.mobile的字尾卻不能識別例如:.mac .dnt 等等字尾呢?這些又是放在哪裡的呢? mobile 這個字尾其實是存放在:DisplayModeProvider.Instance.Modes 裡面的,我們監視一下,發現裡面就一個mobile,還有一個是預設的 可

網站就必須用響應式佈局嗎?MVC檢視展現模式移動佈局

本文先引入給讀者一個自己研究的機會,下次深入說明一下: 廢話不多說,直接上圖 新建一個mvc的專案 在視圖裡面新增一個移動端檢視 正常訪問一下 Bootstrap自帶的響應式的方式(頁面程式碼並沒有改變) 我們來模擬一下移動端訪問: 谷歌或者火狐藉助:user-a

java開發-23種設計模式菜鳥解析1

java開發有23種設計模式,很多工齡沒那麼長的java開發程式設計師可能都不會特意去了解它們,其實它存在的意義不只是應對各種面試,而是在開發過程中簡化、邏輯化、分類化你的程式碼,讓你的程式碼可讀性更高,為你的開發帶來便利的東西。廢話不多說,開始正題 首先大家要了解設計模式的分類,一般分為三個型

java 開發模式十九 :解析模式

原理或定義 給定一個語言,定義它的文法的一種表示,並定義一個直譯器,這個直譯器使用該表示來解釋語言中的句子。屬於行為類模式 結構 AbstractExpression:宣告一個抽象的Interpret方法,抽象語法樹中所有的節點都必須實現該抽象方法。 TerminalExp

MVC檢視【分部檢視】【佈局頁】初瞭解

MVC專案中新建一個檢視,會出現以下介面: 之前一直不清楚【建立為分部檢視】和【使用佈局頁】選項的作用,今天看了一些資料,有了一點基本的瞭解,所以寫這篇文章,當筆記來用,避免以後忘記。 -------------------------------------------

設計模式叠代器模式解析學習源碼(十八)

定義 cas blank 變量 學習 叠代器模式 array 叠代器 壓入 原文獻上, 點擊滴滴滴 叠代器模式(Iterator)定義: 提供一種方法順序訪問聚合對象的各個元素嗎而又不暴露該對象的內部展示 不用Iterator的壞處 原文中編寫了三個簡單的集合 A

設計模式---領域規則模式解析模式(Interpreter)

語法規則 規則 urn air 業務 變化 img bsp span 前提:領域規則模式 在特定領域內,某些變化雖然頻繁,但可以抽象為某種規則。這時候,結合特定領域,將問題抽象為語法規則,從而給出該領域下的一般性解決方案。 典型模式 解析器模式:Inter

單例模式懶漢單例(延遲初始化)多執行緒再解析

單例模式之懶漢單例(延遲初始化)多執行緒再解析 1、多執行緒下的懶漢單例: public class Lazysingleton { private static Lazysingleton m_instance = null; // 私有預設構造方法

淺談MVC模式——複合模式

檢視:用來呈現模型。通常需要從模型中取得它需要的狀態與資料。 控制器:取得使用者的輸入並解讀出其對模型的意思。 模型:持有所有的資料、狀態個程式邏輯。 使用者和檢視互動。檢視告訴控制器你做了什麼。控制器解讀你的動作並告知模型如何做出對應的動作,控制器也可能告知模型做出改變。模型改變時,會通知檢視。 &

ASP.NET Core 入門教程 6、ASP.NET Core MVC 檢視佈局入門

一、前言 1、本教程主要內容 ASP.NET Core MVC (Razor)檢視母版頁教程 ASP.NET Core MVC (Razor)帶有Section的檢視母版頁教程 ASP.NET Core MVC (Razor)檢視全域性程式碼(_ViewStart.csht

Spring MVC 檢視解析 VIEW

轉發和重定向: /** * 轉發 forward:資源路徑 * 重定向 redirect:資源路徑 */ @RequestMapping("demo8") public String demo8() { return "r

常用設計模式代理模式解析

1.  簡介      代理模式(Proxy Pattern)是常用設計模式之一。代理模式的定義:Provide a surrogate or placeholder for another object to controlaccess to

python3搭建web框架django(MVC和MTV模式)

什麼是web框架? 框架,即framework,特指為解決一個開放性問題而設計的具有一定約束性的支撐結構,使用框架可以幫你快速開發特定的系統,簡單地說,就是你用別人搭建好的舞臺來做表演。 對於所有的Web應用,本質上其實就是一個socket服務端,使用者的瀏覽器其實就是一個socke

單例模式執行緒安全解析

面試的時候,常常會被問到這樣一個問題:請您寫出一個單例模式(Singleton Pattern)吧。     單例的目的是為了保證執行時Singleton類只有唯一的一個例項,最常用的地方比如拿到資料庫的連線,Spring的中建立BeanFactory這些開銷比較大的操作,

SAP-MM-移動型別解析發貨

4. 發貨到資產類 241  Consumption for asset from warehouse有關資產的發貨(從倉庫) 241 K Consumption for asset fromconsignment 242  Consumption for asset from warehouse - re

從零開始學 Web 移動Web(六)響應式佈局

大家好,這裡是「 從零開始學 Web 系列教程 」,並在下列地址同步更新...... github:https://github.com/Daotin/Web 部落格園:http://www.cnblogs.com/lvonve/ CSDN:https://blog.csdn.net/lvonve/

MapKit大頭針全面解析(使用系統大頭針、自定義大頭針callout檢視、使用圖片顯示大頭針)

1:使用系統樣式大頭針檢視和系統大頭針模型、 2:使用圖片顯示大頭針檢視,並使用自定義大頭針模型、 3:自定義彈出檢視、 4:適用於頂部title,底部自定義檢視 ios9之後 程式碼部分: class SecondViewController: UIViewController { la

Android開發模式MVC,MVP和MVVM的簡單介紹與區別

相信大家對MVC,MVP和MVVM都不陌生,作為三個最耳熟能詳的Android框架,它們的應用可以是非常廣泛的,但是對於一些新手來說,可能對於區分它們三個都有困難,更別說在實際的專案中應用了,有些時候想用MVP的,程式碼寫著寫著就變成了MVC,久而久之就對它們三個的選擇產生了

移動WEB佈局使用less語法header佈局

      從今天開始小編會出一系列的移動web的常見佈局型別的佈局這裡我們先來的是對於常見頭部佈局以及頭部的一些細節問題的解決,首先先來一張圖來解析一下我們要佈局的頭部,接下來要分佈開始我們的講解啦

解析Android的MVC和MVP模式

1.     MVC          mvc是model、view、controller的縮寫。Android 鼓勵弱耦合和元件的重用,android 中mvc的具體體現如下:   · 模型(mod