zoukankan      html  css  js  c++  java
  • MVC视图展现模式之移动布局解析-续集

    网站就必须用响应式布局吗?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:WorkNetMobilepackagesMicrosoft.AspNet.WebPages.3.2.3lib
    et45System.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:WorkNetMobilepackagesMicrosoft.AspNet.WebPages.3.2.3lib
    et45System.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

    参考: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

  • 相关阅读:
    Note/Solution 转置原理 & 多点求值
    Note/Solution 「洛谷 P5158」「模板」多项式快速插值
    Solution 「CTS 2019」「洛谷 P5404」氪金手游
    Solution 「CEOI 2017」「洛谷 P4654」Mousetrap
    Solution Set Border Theory
    Solution Set Stirling 数相关杂题
    Solution 「CEOI 2006」「洛谷 P5974」ANTENNA
    Solution 「ZJOI 2013」「洛谷 P3337」防守战线
    Solution 「CF 923E」Perpetual Subtraction
    KVM虚拟化
  • 原文地址:https://www.cnblogs.com/dunitian/p/5218140.html
Copyright © 2011-2022 走看看