ASP.NET MVC Preview生命周期分析

namespace System.Web.Mvc {
    public class WebFormViewLocator : ViewLocator {
        public WebFormViewLocator() {
            ViewLocationFormats = new[] {
                “~/Views/{1}/{0}.aspx”,
                “~/Views/{1}/{0}.ascx”,
                “~/Views/Shared/{0}.aspx”,
                “~/Views/Shared/{0}.ascx”
            };
            MasterLocationFormats = new[] {
                “~/Views/{1}/{0}.master”,
                “~/Views/Shared/{0}.master”
            };
        }
    }
}

将同台传递过来的有关 “数据” (上下文)ControllerContext
再一次卷入成ViewContext
。当然,这一次照例会多出些东西,里面就有大家向视图传递的数据 —— viewData
和tempData。作为默认选项,MVC 创造 WebForm
视图引擎来展现结果。其他的视图引擎可以去看mvccontrib,那多少个项目就是整合:Castle
Windsor

StructureMap
Spring.NET
等IoC框架以及视图引擎,包括Castle
MonoRail所用的NVelocityView视图引擎、NHamlView视图引擎、XsltViewEngine视图引擎等等。

 

Ajax 1[SuppressMessage(“Microsoft.Design”, “CA1011:ConsiderPassingBaseTypesAsParameters”,
Ajax 2     Justification = “We use MethodInfo since it represents only methods and not constructors.” +
Ajax 3     “This method only makes sense for use with methods.”)]
Ajax 4Ajax 5protected internal virtual void InvokeActionMethod(MethodInfo methodInfo, RouteValueDictionary values) Ajax 6{
Ajax 7Ajax 8     if (methodInfo == null) Ajax 9{
Ajax 10         throw new ArgumentNullException(“methodInfo”);
Ajax 11     }
Ajax 12Ajax 13     if (values == null) Ajax 14{
Ajax 15         values = new RouteValueDictionary();
Ajax 16     }
Ajax 17Ajax 18     if (methodInfo.ContainsGenericParameters) Ajax 19{
Ajax 20         throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, MvcResources.Controller_ActionCannotBeGeneric, methodInfo.Name));
Ajax 21     } 
Ajax 22
Ajax 23     ParameterInfo[] methodParameters = methodInfo.GetParameters();
Ajax 24     object[] parameterValues = null;
Ajax 25Ajax 26     if (methodParameters.Length > 0) Ajax 27
Ajax 28
Ajax 29         parameterValues = new object[methodParameters.Length];
Ajax 30Ajax 31         for (int i = 0; i < methodParameters.Length; i++) Ajax 32{
Ajax 33             ParameterInfo pi = methodParameters[i]; 
Ajax 34
Ajax 35Ajax 36             if (pi.IsOut || pi.ParameterType.IsByRef) Ajax 37{
Ajax 38                 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, MvcResources.Controller_ReferenceParametersNotSupported, pi.Name, methodInfo.Name));
Ajax 39             } 
Ajax 40
Ajax 41             bool valueRequired = true;
Ajax 42Ajax 43             if (pi.ParameterType.IsClass) Ajax 44{
Ajax 45                 // Classes (ref types) don’t require values since we can pass in null
Ajax 46                 valueRequired = false;
Ajax 47             }
Ajax 48Ajax 49             else Ajax 50{
Ajax 51                 if ((pi.ParameterType.IsGenericType && !pi.ParameterType.IsGenericTypeDefinition) &&
Ajax 52Ajax 53                     (pi.ParameterType.GetGenericTypeDefinition() == typeof(Nullable<>))) Ajax 54{
Ajax 55                     // Nullable types don’t require values since we can pass in null
Ajax 56                     valueRequired = false;
Ajax 57                 }
Ajax 58             } 
Ajax 59
Ajax 60             // Try to get a value for the parameter. We use this order of precedence:
Ajax 61             // 1. Explicitly-provided extra parameters in the call to InvokeAction()
Ajax 62             // 2. Values from the RouteData (could be from the typed-in URL or from the route’s default values)
Ajax 63             // 3. Request values (query string, form post data, cookie)
Ajax 64             object parameterValue = null;
Ajax 65Ajax 66             if (!values.TryGetValue(methodParameters[i].Name, out parameterValue)) Ajax 67{
Ajax 68Ajax 69                 if (RouteData == null || !RouteData.Values.TryGetValue(methodParameters[i].Name, out parameterValue)) Ajax 70{
Ajax 71Ajax 72                     if (Request != null) Ajax 73{
Ajax 74                         parameterValue = Request[methodParameters[i].Name];
Ajax 75                     }
Ajax 76                 }
Ajax 77             } 
Ajax 78
Ajax 79Ajax 80             if (parameterValue == null && valueRequired) Ajax 81{
Ajax 82                 throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, MvcResources.Controller_MissingParameter, pi.Name, methodInfo.Name));
Ajax 83             } 
Ajax 84
Ajax 85Ajax 86             try Ajax 87{
Ajax 88                 parameterValues[i] = ConvertParameterType(parameterValue, methodParameters[i].ParameterType, methodParameters[i].Name, methodInfo.Name);
Ajax 89             }
Ajax 90Ajax 91             catch (Exception ex) Ajax 92{
Ajax 93                 // Parameter value conversion errors are acceptable unless the value is required
Ajax 94Ajax 95                 if (valueRequired) Ajax 96{
Ajax 97                     throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, MvcResources.Controller_MissingParameter, pi.Name, methodInfo.Name), ex);
Ajax 98                 }
Ajax 99             }
Ajax 100         }
Ajax 101     } 
Ajax 102
Ajax 103Ajax,     InvokeActionMethodFilters(methodInfo, () => methodInfo.Invoke(this, parameterValues));
Ajax 104}

 上述代码来自[翻译]行使asp.net mvc再造一个digg
第一有的
的kigg。回到上文,在取得
RoteCollection 之后,通过调用 GetRouteData(context) 重回一个 RouteData
对象,该目的内部含有了俺们报了名 Route 时的相关安装,包括下边所急需的
MvcRouteHandler。接下来,该方法将 routeData 和上下文一起打包成
RequestContext,这就是为有关处理准备的上下文环境。通过调用
IRouteHandler.GetHttpHandler()方法,终于抵达流程的首要IHttpHandler(MvcHandler)。在WebForm中大家知晓每一个页面都是一个HttpHandler,Asp.net
mvc也不例外。

        #region IViewDataContainer Members
        object IViewDataContainer.ViewData {
            get {
                EnsureViewData();
                return _viewData;
            }
        }
        #endregion

        public TempDataDictionary TempData {
            get {
                return ViewContext.TempData;
            }
        }

此处得到了MvcHandler:

Ajax 105Ajax 106namespace System.Web.Mvc Ajax 107{
Ajax 108    using System.Web.Routing; 
Ajax 109
Ajax 110    [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
Ajax 111    [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
Ajax 112Ajax 113    public class ControllerContext : RequestContext Ajax 114{
Ajax 115        public ControllerContext(HttpContextBase httpContext, RouteData routeData, IController controller)
Ajax 116Ajax 117            : base(httpContext, routeData) Ajax 118{
Ajax 119Ajax 120            if (controller == null) Ajax 121{
Ajax 122                throw new ArgumentNullException(“controller”);
Ajax 123            }
Ajax 124            Controller = controller;
Ajax 125        } 
Ajax 126
Ajax 127        public ControllerContext(RequestContext requestContext, IController controller)
Ajax 128Ajax 129            : this(GetRequestContext(requestContext).HttpContext, GetRequestContext(requestContext).RouteData, controller) Ajax 130{
Ajax 131        } 
Ajax 132
Ajax 133Ajax 134        public IController Controller Ajax 135{
Ajax 136            get;
Ajax 137            private set;
Ajax 138        } 
Ajax 139
Ajax 140Ajax 141        internal static RequestContext GetRequestContext(RequestContext requestContext) Ajax 142{
Ajax 143Ajax 144            if (requestContext == null) Ajax 145{
Ajax 146                throw new ArgumentNullException(“requestContext”);
Ajax 147            }
Ajax 148            return requestContext;
Ajax 149        }
Ajax 150    }
Ajax 151

来看了来自RouteTable,这不正是在Global.asax.cs 中加上的 Route 集合:

Ajax 152    public System.Web.Routing.RouteCollection RouteCollection
Ajax 153Ajax 154        Ajax 155{
Ajax 156            get
Ajax 157Ajax 158            Ajax 159{
Ajax 160                if (this._routeCollection == null)
Ajax 161Ajax 162                Ajax 163{
Ajax 164                    this._routeCollection = RouteTable.Routes;
Ajax 165                }
Ajax 166                return this._routeCollection;
Ajax 167            }
Ajax 168            set
Ajax 169Ajax 170            Ajax 171{
Ajax 172                this._routeCollection = value;
Ajax 173            }
Ajax 174        } 
Ajax 175

        #region IViewDataContainer Members
        object IViewDataContainer.ViewData {
            get {
                return _viewData;
            }
        }
        #endregion
    }
}

下边看看ViewPage和ViewUserControl的代码:

第一会创建一个 WebFormViewLocator 对象来赢得视图存放路径。

        public AjaxHelper Ajax {
            get;
            set;
        }

       
[System.Diagnostics.CodeAnalysis.SuppressMessage(“Microsoft.Design”,
“CA1024:UsePropertiesWhereAppropriate”,
           Justification = “There is already a ViewData property and it
has a slightly different meaning.”)]
        protected internal virtual void SetViewData(object viewData) {
            _viewData = viewData;
        }

 

(1) 日常状态下,重返一个默认的 DefaultControllerFactory 实例。
(2) 大家得以在 Application_Start 中经过
ControllerBuilder.Current.SetControllerFactory
方法来注册一个我们自定义的工厂。
(3) 主旨代码: factory =
(IControllerFactory)Activator.CreateInstance(controllerFactoryType),通过反射创设IControllerFactory;

做ASP.NET WebForm开发都了解,ASP.NET有复杂的生命周期,学习ASP.NET
MVC就要浓厚领会它的生命周期。后天从CodePlex上下载了ASP.NET Preview
2
的源代码,还有多个程序集Routing与Abstractions并未披露,可是这两个程序集的类并不多,可以用NET反编译工具
Reflector
解开来探望,可惜这两个程序集用的是VS2008使用.net
3.5开发的,用了c# 3.0的居多表征,Reflector反编译不完全。

Ajax 176<httpModules>
Ajax 177     <add name=”UrlRoutingModule” type=”System.Web.Routing.UrlRoutingModule, System.Web.Routing” />
Ajax 178</httpModules> 

它通过反射获取具有同名 Action 方法消息;其次,它过滤掉所有有
NonActionAttribute 和 IsSpecialName 标记的方法;第三,当同名有效 Action
被重载时它会抛出特别(指示Controller_MoreThanOneAction),继续调用InvokeActionMethod:

        public ViewData ViewData {
            get {
                return new ViewData(_viewData);
            }
        }

在获取路径后,WebFormViewEngine 通过一个装进类 BuildManagerWrapper
直接调用 System.Web.Compilation.BuildManager 的静态方法
CreateInstanceFromVirtualPath()将视图举办编译,并赶回一个目标实例。(System.Web.Compilation.BuildManager
BuildManager 类管理应用程序的程序集和页的编译过程),后边通过 as
转换结果来判断视图是 ViewPage 仍旧 ViewUserControl。ViewPage
继承自我们所熟谙的 System.Web.UI.Page,它的 RenderView()方法也就是到位WebForm的 Page.ProcessRequest()的处理而已,也就完事了对WebForm模型的交换。

        public AjaxHelper Ajax {
            get {
                return ViewPage.Ajax;
            }
        }

 

 

            ProcessRequest(HttpContext.Current);
        }

倘诺大家自定义MvcHandler,则需要出色的看看ControllerBuilder.Current:

OnApplicationPostMapRequestHandler 被实践。在 PostMapRequestHandler
中,它提取了前头预先准备好的上下文,并修改了 HttpContext.Handler,使得
MvcHandler 接管默认的WebForm的HttpHandler,才是履行ASP.NET
MVC的流水线。现在来持续看MvcHandler。

接轨看IController的默认实现类Controller:

Ajax 179Ajax 180namespace System.Web.Mvc Ajax 181{
Ajax 182    using System.Web.Routing; 
Ajax 183
Ajax 184    [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
Ajax 185    [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
Ajax 186Ajax 187    public class MvcRouteHandler : IRouteHandler Ajax 188{
Ajax 189Ajax 190        protected virtual IHttpHandler GetHttpHandler(RequestContext requestContext) Ajax 191{
Ajax 192            return new MvcHandler(requestContext);
Ajax 193        } 
Ajax 194
Ajax 195Ajax 196        IRouteHandler Members#region IRouteHandler Members
Ajax 197Ajax 198        IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext) Ajax 199{
Ajax 200            return GetHttpHandler(requestContext);
Ajax 201        }
Ajax 202        #endregion
Ajax 203    }
Ajax 204

到此开首进入终极的视图显示阶段,可以把数量表现到视图上,Controller
提供了多少个重载的 RenderView() 来成功这个工作。

        public HtmlTextWriter Writer {
            get;
            private set;
        }

        public UrlHelper Url {
            get;
            set;
        }

 

        private ViewPage ViewPage {
            get {
                ViewPage viewPage = Page as ViewPage;
                if (viewPage == null) {
                    throw new
InvalidOperationException(String.Format(CultureInfo.CurrentUICulture,
MvcResources.ViewUserControl_RequiresViewPage));
                }
                return viewPage;
            }
        }

先来看看MvcRouteHandler:

Ajax 205Ajax 206namespace System.Web.Mvc Ajax 207{
Ajax 208    using System;
Ajax 209    using System.Diagnostics.CodeAnalysis;
Ajax 210    using System.Globalization;
Ajax 211    using System.Web;
Ajax 212    using System.Web.Mvc.Resources; 
Ajax 213
Ajax 214    [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
Ajax 215    [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
Ajax 216Ajax 217    public class ControllerBuilder Ajax 218{
Ajax 219        private static ControllerBuilder _instance = new ControllerBuilder();
Ajax 220        private Func<IControllerFactory> _factoryThunk; 
Ajax 221
Ajax 222Ajax 223        public ControllerBuilder() Ajax 224{
Ajax 225            SetControllerFactory(new DefaultControllerFactory());
Ajax 226        } 
Ajax 227
Ajax 228Ajax 229        public static ControllerBuilder Current Ajax 230{
Ajax 231Ajax 232            get Ajax 233{
Ajax 234                return _instance;
Ajax 235            }
Ajax 236        } 
Ajax 237
Ajax 238        [SuppressMessage(“Microsoft.Design”, “CA1024:UsePropertiesWhereAppropriate”,
Ajax 239            Justification = “Calling method multiple times might return different objects.”)]
Ajax 240Ajax 241        public IControllerFactory GetControllerFactory() Ajax 242{
Ajax 243            IControllerFactory controllerFactoryInstance = _factoryThunk();
Ajax 244            return controllerFactoryInstance;
Ajax 245        } 
Ajax 246
Ajax 247Ajax 248        public void SetControllerFactory(IControllerFactory controllerFactory) Ajax 249{
Ajax 250Ajax 251            if (controllerFactory == null) Ajax 252{
Ajax 253                throw new ArgumentNullException(“controllerFactory”);
Ajax 254            } 
Ajax 255
Ajax 256            _factoryThunk = () => controllerFactory;
Ajax 257        } 
Ajax 258
Ajax 259Ajax 260        public void SetControllerFactory(Type controllerFactoryType) Ajax 261{
Ajax 262Ajax 263            if (controllerFactoryType == null) Ajax 264{
Ajax 265                throw new ArgumentNullException(“controllerFactoryType”);
Ajax 266            }
Ajax 267Ajax 268            if (!typeof(IControllerFactory).IsAssignableFrom(controllerFactoryType)) Ajax 269{
Ajax 270                throw new ArgumentException(
Ajax 271                    String.Format(
Ajax 272                        CultureInfo.CurrentUICulture,
Ajax 273                        MvcResources.ControllerBuilder_MissingIControllerFactory,
Ajax 274                        controllerFactoryType),
Ajax 275                    “controllerFactoryType”);
Ajax 276            } 
Ajax 277
Ajax 278Ajax 279            _factoryThunk = delegate() Ajax 280{
Ajax 281Ajax 282                try Ajax 283{
Ajax 284                    return (IControllerFactory) Activator.CreateInstance(controllerFactoryType);
Ajax 285                }
Ajax 286Ajax 287                catch (Exception ex) Ajax 288{
Ajax 289                    throw new InvalidOperationException(
Ajax 290                        String.Format(
Ajax 291                            CultureInfo.CurrentUICulture,
Ajax 292                            MvcResources.ControllerBuilder_ErrorCreatingControllerFactory,
Ajax 293                            controllerFactoryType),
Ajax 294                        ex);
Ajax 295                }
Ajax 296            };
Ajax 297        }
Ajax 298    }
Ajax 299

率先从 RouteData 中提取 Controller 的名字(这一个名字是我们在
Global.asax.cs RegisterRoutes 中注册 Route 时提供的),然后拿走
ControllerFactory,只可是这其中特别提供了一个 ControllerBuilder。

ASP.NET MVC通过HttpModule(UrlRoutingModule)起初她的进行流程

本条主意首先将默认的过滤器 ControllerActionFilter
加到列表,然后提取所有继续层次上基类的过滤器特性。最终将这多少个过滤器集合、过滤上下文,连同前一个形式传递进入的
Action 执行委托(continuation) 再一次传递给了一个 ActionFilterExecutor
对象实例,并调用其 Execute 方法。

        protected override void Render(HtmlTextWriter writer) {
            Writer = writer;
            try {
                base.Render(writer);
            }
            finally {
                Writer = null;
            }
        }

上述UrlRoutingModule订阅了六个 HttpApplication
事件,PostResolveRequestCache 要比 PostMapRequestHandler
更早举行,先看PostResolveRequestCache 事件,他第一从第一从
RouteCollection 中得到一个 RouteData 对象。看看RouteCollection 属性:

        public ViewContext ViewContext {
            get;
            private set;
        }

  1. 对请求举办求证,将检查浏览器发送的音讯,并确定其是否包含潜在恶意标记。

  2. 假诺已在 Web.config 文件的 UrlMappingsSection 节中布置了别样
    URL,则实施 URL 映射。

  3. 引发 BeginRequest 事件。

  4. 引发 AuthenticateRequest 事件。

  5. 引发 PostAuthenticateRequest 事件。

  6. 引发 AuthorizeRequest 事件。

  7. 引发 PostAuthorizeRequest 事件。

  8. 引发 ResolveRequestCache 事件。

  9. 引发 PostResolveRequestCache 事件。

  10. 据悉所请求资源的文件扩大名(在应用程序的布置文件中映射),选用实现
    IHttpHandler 的类,对请求举行拍卖。假设该请求针对从 Page
    类派生的靶子(页),并且需要对该页举行编译,则 ASP.NET
    会在创制该页的实例在此之前对其进展编译。

  11. 引发 PostMapRequestHandler 事件。

  12. 引发 AcquireRequestState 事件。

  13. 引发 PostAcquireRequestState 事件。

  14. 引发 PreRequestHandlerExecute 事件。

  15. 为该请求调用合适的 IHttpHandler 类的 ProcessRequest
    方法(或异步版
    BeginProcessRequest)。例如,如果该请求针对某页,则当前的页实例将拍卖该请求。

  16. 引发 PostRequestHandlerExecute 事件。

  17. 引发 ReleaseRequestState 事件。

  18. 引发 PostReleaseRequestState 事件。

  19. 设若定义了 Filter 属性,则执行响应筛选。

  20. 引发 UpdateRequestCache 事件。

  21. 引发 PostUpdateRequestCache 事件。

  22. 引发 EndRequest 事件。

 

   
[AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand,
Level = AspNetHostingPermissionLevel.Minimal)]
   
[AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand,
Level = AspNetHostingPermissionLevel.Minimal)]
    public class ViewUserControl : UserControl, IViewDataContainer {
        private string _viewDataKey;
        private object _viewData;

Ajax 300
Ajax 301
Ajax 302Ajax 303namespace System.Web.Mvc Ajax 304{
Ajax 305    using System;
Ajax 306    using System.Globalization;
Ajax 307    using System.Web.Compilation;
Ajax 308    using System.Web.Resources;
Ajax 309    using System.Web.Routing;
Ajax 310    using System.Web.Mvc.Resources; 
Ajax 311
Ajax 312    [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
Ajax 313    [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
Ajax 314Ajax 315    public class WebFormViewEngine : IViewEngine Ajax 316{
Ajax 317        private IBuildManager _buildManager;
Ajax 318        private IViewLocator _viewLocator; 
Ajax 319
Ajax 320Ajax 321        internal IBuildManager BuildManager Ajax 322{
Ajax 323Ajax 324            get Ajax 325{
Ajax 326Ajax 327                if (_buildManager == null) Ajax 328{
Ajax 329                    _buildManager = new BuildManagerWrapper();
Ajax 330                }
Ajax 331                return _buildManager;
Ajax 332            }
Ajax 333Ajax 334            set Ajax 335{
Ajax 336                _buildManager = value;
Ajax 337            }
Ajax 338        } 
Ajax 339
Ajax 340Ajax 341        public IViewLocator ViewLocator Ajax 342{
Ajax 343Ajax 344            get Ajax 345{
Ajax 346Ajax 347                if (_viewLocator == null) Ajax 348{
Ajax 349                    _viewLocator = new WebFormViewLocator();
Ajax 350                }
Ajax 351                return _viewLocator;
Ajax 352            }
Ajax 353Ajax 354            set Ajax 355{
Ajax 356                _viewLocator = value;
Ajax 357            }
Ajax 358        } 
Ajax 359
Ajax 360Ajax 361        protected virtual void RenderView(ViewContext viewContext) Ajax 362{
Ajax 363Ajax 364            if (viewContext == null) Ajax 365{
Ajax 366                throw new ArgumentNullException(“viewContext”);
Ajax 367            } 
Ajax 368
Ajax 369            string viewPath = ViewLocator.GetViewLocation(viewContext, viewContext.ViewName);
Ajax 370Ajax 371            if (String.IsNullOrEmpty(viewPath)) Ajax 372{
Ajax 373                throw new InvalidOperationException(
Ajax 374                    String.Format(
Ajax 375                        CultureInfo.CurrentUICulture,
Ajax 376                        MvcResources.WebFormViewEngine_ViewNotFound,
Ajax 377                        viewContext.ViewName));
Ajax 378            }
Ajax 379            object viewInstance = BuildManager.CreateInstanceFromVirtualPath(viewPath, typeof(object));
Ajax 380Ajax 381            if (viewInstance == null) Ajax 382{
Ajax 383                throw new InvalidOperationException(
Ajax 384                    String.Format(
Ajax 385                        CultureInfo.CurrentUICulture,
Ajax 386                        MvcResources.WebFormViewEngine_ViewCouldNotBeCreated,
Ajax 387                        viewPath));
Ajax 388            } 
Ajax 389
Ajax 390            ViewPage viewPage = viewInstance as ViewPage; 
Ajax 391
Ajax 392Ajax 393            if (viewPage != null) Ajax 394
Ajax 395
Ajax 396Ajax 397                if (!String.IsNullOrEmpty(viewContext.MasterName)) Ajax 398{
Ajax 399                    string masterLocation = ViewLocator.GetMasterLocation(viewContext, viewContext.MasterName);
Ajax 400Ajax 401                    if (String.IsNullOrEmpty(masterLocation)) Ajax 402{
Ajax 403                        throw new InvalidOperationException(
Ajax 404                            String.Format(
Ajax 405                                CultureInfo.CurrentUICulture,
Ajax 406                                MvcResources.WebFormViewEngine_MasterNotFound,
Ajax 407                                viewContext.MasterName));
Ajax 408                    } 
Ajax 409
Ajax 410                    // We don’t set the page’s MasterPageFile directly since it will get
Ajax 411                    // overwritten by a statically-defined value. In ViewPage we wait until
Ajax 412                    // the PreInit phase until we set the new value.
Ajax 413                    viewPage.MasterLocation = masterLocation;
Ajax 414                }
Ajax 415                viewPage.SetViewData(viewContext.ViewData);
Ajax 416                viewPage.RenderView(viewContext);
Ajax 417            }
Ajax 418Ajax 419            else Ajax 420{
Ajax 421                ViewUserControl viewUserControl = viewInstance as ViewUserControl;
Ajax 422Ajax 423                if (viewUserControl != null) Ajax 424{
Ajax 425Ajax 426                    if (!String.IsNullOrEmpty(viewContext.MasterName)) Ajax 427{
Ajax 428                        throw new InvalidOperationException(MvcResources.WebFormViewEngine_UserControlCannotHaveMaster);
Ajax 429                    } 
Ajax 430
Ajax 431                    viewUserControl.SetViewData(viewContext.ViewData);
Ajax 432                    viewUserControl.RenderView(viewContext);
Ajax 433                }
Ajax 434Ajax 435                else Ajax 436{
Ajax 437                    throw new InvalidOperationException(
Ajax 438                        String.Format(
Ajax 439                            CultureInfo.CurrentUICulture,
Ajax 440                            MvcResources.WebFormViewEngine_WrongViewBase,
Ajax 441                            viewPath));
Ajax 442                }
Ajax 443            }
Ajax 444        } 
Ajax 445
Ajax 446Ajax 447        IViewEngine Members#region IViewEngine Members
Ajax 448Ajax 449        void IViewEngine.RenderView(ViewContext viewContext) Ajax 450{
Ajax 451            RenderView(viewContext);
Ajax 452        }
Ajax 453        #endregion
Ajax 454    }
Ajax 455

InvokeActionMethodFilters(methodInfo, () => methodInfo.Invoke(this,
parameterValues));

MvcHandler.ProcessRequest(),在得到控制器实例后,MvcHandler 开头了调用
Controller.Execute()来一发继承操作,同时对其上下文进一步封装,除了前面创造的
RequestContext,还加上了现阶段以此 Controller
对象的引用,类名叫ControllerContext。

        public HtmlTextWriter Writer {
            get {
                return ViewPage.Writer;
            }
        }

Ajax 456Ajax 457namespace System.Web.Mvc Ajax 458{
Ajax 459    using System.Globalization;
Ajax 460    using System.Web.Mvc.Resources;
Ajax 461    using System.Web.Routing;
Ajax 462    using System.Web.SessionState; 
Ajax 463
Ajax 464    [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
Ajax 465    [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
Ajax 466Ajax 467    public class MvcHandler : IHttpHandler, IRequiresSessionState Ajax 468{
Ajax 469        private ControllerBuilder _controllerBuilder; 
Ajax 470
Ajax 471Ajax 472        public MvcHandler(RequestContext requestContext) Ajax 473{
Ajax 474Ajax 475            if (requestContext == null) Ajax 476{
Ajax 477                throw new ArgumentNullException(“requestContext”);
Ajax 478            }
Ajax 479            RequestContext = requestContext;
Ajax 480        } 
Ajax 481
Ajax 482Ajax 483        protected virtual bool IsReusable Ajax 484{
Ajax 485Ajax 486            get Ajax 487{
Ajax 488                // REVIEW: What’s this?
Ajax 489                return false;
Ajax 490            }
Ajax 491        } 
Ajax 492
Ajax 493Ajax 494        internal ControllerBuilder ControllerBuilder Ajax 495{
Ajax 496Ajax 497            get Ajax 498{
Ajax 499Ajax 500                if (_controllerBuilder == null) Ajax 501{
Ajax 502                    _controllerBuilder = ControllerBuilder.Current;
Ajax 503                }
Ajax 504                return _controllerBuilder;
Ajax 505            }
Ajax 506Ajax 507            set Ajax 508{
Ajax 509                _controllerBuilder = value;
Ajax 510            }
Ajax 511        } 
Ajax 512
Ajax 513Ajax 514        public RequestContext RequestContext Ajax 515{
Ajax 516            get;
Ajax 517            private set;
Ajax 518        } 
Ajax 519
Ajax 520Ajax 521        protected virtual void ProcessRequest(HttpContext httpContext) Ajax 522{
Ajax 523            HttpContextBase iHttpContext = new HttpContextWrapper2(httpContext);
Ajax 524            ProcessRequest(iHttpContext);
Ajax 525        } 
Ajax 526
Ajax 527Ajax 528        protected internal virtual void ProcessRequest(HttpContextBase httpContext) Ajax 529{
Ajax 530            // Get the controller type
Ajax 531            string controllerName = RequestContext.RouteData.GetRequiredString(“controller”); 
Ajax 532
Ajax 533            // Instantiate the controller and call Execute
Ajax 534            IControllerFactory factory = ControllerBuilder.GetControllerFactory();
Ajax 535            IController controller = factory.CreateController(RequestContext, controllerName);
Ajax 536Ajax 537            if (controller == null) Ajax 538{
Ajax 539                throw new InvalidOperationException(
Ajax 540                    String.Format(
Ajax 541                        CultureInfo.CurrentUICulture,
Ajax 542                        MvcResources.ControllerBuilder_FactoryReturnedNull,
Ajax 543                        factory.GetType(),
Ajax 544                        controllerName));
Ajax 545            }
Ajax 546Ajax 547            try Ajax 548{
Ajax 549                ControllerContext controllerContext = new ControllerContext(RequestContext, controller);
Ajax 550                controller.Execute(controllerContext);
Ajax 551            }
Ajax 552Ajax 553            finally Ajax 554{
Ajax 555                factory.DisposeController(controller);
Ajax 556            }
Ajax 557        } 
Ajax 558
Ajax 559Ajax 560        IHttpHandler Members#region IHttpHandler Members
Ajax 561Ajax 562        bool IHttpHandler.IsReusable Ajax 563{
Ajax 564Ajax 565            get Ajax 566{
Ajax 567                return IsReusable;
Ajax 568            }
Ajax 569        } 
Ajax 570
Ajax 571Ajax 572        void IHttpHandler.ProcessRequest(HttpContext httpContext) Ajax 573{
Ajax 574            ProcessRequest(httpContext);
Ajax 575        }
Ajax 576        #endregion
Ajax 577    }
Ajax 578}

Ajax 579Ajax 580       protected void RenderView(string viewName) Ajax 581{
Ajax 582           RenderView(viewName, String.Empty, ViewData);
Ajax 583       } 
Ajax 584
Ajax 585Ajax 586       protected void RenderView(string viewName, string masterName) Ajax 587{
Ajax 588           RenderView(viewName, masterName, ViewData);
Ajax 589       } 
Ajax 590
Ajax 591Ajax 592       protected void RenderView(string viewName, object viewData) Ajax 593{
Ajax 594           RenderView(viewName, String.Empty, viewData);
Ajax 595       } 
Ajax 596
Ajax 597Ajax 598       protected virtual void RenderView(string viewName, string masterName, object viewData) Ajax 599{
Ajax 600           ViewContext viewContext = new ViewContext(ControllerContext, viewName, masterName, viewData, TempData);
Ajax 601           ViewEngine.RenderView(viewContext);
Ajax 602       } 
Ajax 603

经过反射来创制 Controller 实例,GetControllerType
里面做了些缓存处理,以此来制止频繁利用反射造成的属性问题。继续

        public HtmlHelper Html {
            get {
                return ViewPage.Html;
            }
        }

到了这一步,MVC
框架已经准备好了相应的施行场景,接下去就是修改默认(指WebForm)的实践流程了。

详见看看InvokeAction形式的推行:

ExecuteRecursive使用了递归算法,通过迭代器 MoveNext()方法提取一个过滤器对象,执行其 OnActionExecuting 方法。 假如该格局设置了
filterContext.Cancel =
true,则吐弃继续执行代码。这种机制为大家提供了更好的主宰,例如用它来贯彻伪静态页。一层一层调用所有的
ActionFilterAttribute.OnActionExecuting 方法,直到 MoveNext() == false。
在结尾五次递归调用时,由于 enumerator.MoveNext() == false,
_continuation() 方法被实践。这一个就是前面给传递过来的 Action
方法委托,Action 方法总算是实施了。 在 Action
委托执行到位后,递归调逐级往上回顾,直到最初这么些形式堆栈。这样具有ActionFilterAttribute.OnActionExecuted
也被实践到位。

Ajax 604Ajax 605private void InvokeActionMethodFilters(MethodInfo methodInfo, Action continuation) Ajax 606
Ajax 607
Ajax 608           // filters should execute in this order:
Ajax 609           // controller virtual overrides -> controller base attributes -> controller type attributes ->
Ajax 610           //   base action method attributes -> action method attributes 
Ajax 611
Ajax 612Ajax 613           List<ActionFilterAttribute> filters = new List<ActionFilterAttribute>() Ajax 614{
Ajax 615               new ControllerActionFilter(this)
Ajax 616           }; 
Ajax 617
Ajax 618           Stack<MemberInfo> memberChain = new Stack<MemberInfo>();
Ajax 619           Type curType = GetType();
Ajax 620Ajax 621           while (curType != null) Ajax 622{
Ajax 623               memberChain.Push(curType);
Ajax 624               curType = curType.BaseType;
Ajax 625           } 
Ajax 626
Ajax 627           List<ActionFilterAttribute> sortedClassFilters = SortActionFilters(memberChain);
Ajax 628           filters.AddRange(sortedClassFilters);
Ajax 629           List<ActionFilterAttribute> sortedMethodFilters = PrepareMethodActionFilters(methodInfo);
Ajax 630           filters.AddRange(sortedMethodFilters); 
Ajax 631
Ajax 632           FilterContext context = new FilterContext(ControllerContext, methodInfo);
Ajax 633           ActionFilterExecutor executor = new ActionFilterExecutor(filters, context, continuation);
Ajax 634           executor.Execute();
Ajax 635       } 

        private void EnsureViewData() {
            // Get the ViewData for this ViewUserControl, optionally
using the specified ViewDataKey
            if (_viewData != null) {
                return;
            }
            IViewDataContainer vdc = GetViewDataContainer(this);
            if (vdc == null) {
                throw new InvalidOperationException(
                    String.Format(
                        CultureInfo.CurrentUICulture,
                       
MvcResources.ViewUserControl_RequiresViewDataProvider,
                        AppRelativeVirtualPath));
            }
            if (String.IsNullOrEmpty(ViewDataKey)) {
                _viewData = vdc.ViewData;
            }
            else {
                _viewData = DataBinder.Eval(vdc.ViewData,
ViewDataKey);
            }
        }

       
[System.Diagnostics.CodeAnalysis.SuppressMessage(“Microsoft.Design”,
“CA1024:UsePropertiesWhereAppropriate”,
            Justification = “There is already a ViewData property and it
has a slightly different meaning.”)]
        protected internal virtual void SetViewData(object viewData) {
            _viewData = viewData;
        }

namespace System.Web.Mvc {
    using System.Web.UI;

这行代码将 Action 的调用作为一个寄托,连同反射信息传递给
InvokeActionMethodFilters。

Ajax 636Ajax 637protected internal bool InvokeAction(string actionName) Ajax 638{
Ajax 639            return InvokeAction(actionName, new RouteValueDictionary());
Ajax 640        } 
Ajax 641
Ajax 642Ajax 643        protected internal virtual bool InvokeAction(string actionName, RouteValueDictionary values) Ajax 644{
Ajax 645Ajax 646            if (String.IsNullOrEmpty(actionName)) Ajax 647{
Ajax 648                throw new ArgumentException(MvcResources.Common_NullOrEmpty, “actionName”);
Ajax 649            } 
Ajax 650
Ajax 651            // We have to loop through all the methods to make sure there isn’t
Ajax 652            // a conflict. If we stop the loop the first time we find a match
Ajax 653            // we might miss some error cases. 
Ajax 654
Ajax 655            MemberInfo[] membInfos = GetType().GetMember(actionName, MemberTypes.Method,
Ajax 656                BindingFlags.IgnoreCase | BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public);
Ajax 657            MethodInfo foundMatch = null; 
Ajax 658
Ajax 659Ajax 660            foreach (MemberInfo memberInfo in membInfos) Ajax 661{
Ajax 662                MethodInfo mi = (MethodInfo)memberInfo; 
Ajax 663
Ajax 664                // 1) Action methods must not have the non-action attribute in their inheritance chain, and
Ajax 665                // 2) special methods like constructors, property accessors, and event accessors cannot be action methods, and
Ajax 666                // 3) methods originally defined on Object (like ToString) or Controller cannot be action methods.
Ajax 667                if (!mi.IsDefined(typeof(NonActionAttribute), true) &&
Ajax 668                    !mi.IsSpecialName &&
Ajax 669Ajax 670                    mi.DeclaringType.IsSubclassOf(typeof(Controller))) Ajax 671{
Ajax 672Ajax 673                    if (foundMatch != null) Ajax 674{
Ajax 675                        throw new InvalidOperationException(
Ajax 676                            String.Format(CultureInfo.CurrentUICulture, MvcResources.Controller_MoreThanOneAction, actionName, GetType()));
Ajax 677                    }
Ajax 678                    foundMatch = mi;
Ajax 679                }
Ajax 680            } 
Ajax 681
Ajax 682Ajax 683            if (foundMatch != null) Ajax 684{
Ajax 685                InvokeActionMethod(foundMatch, values);
Ajax 686                return true;
Ajax 687            }
Ajax 688            return false;
Ajax 689        } 

Ajax 690             RequestData data2 = new RequestData();
Ajax 691                data2.OriginalPath = context.Request.Path;
Ajax 692                data2.HttpHandler = httpHandler;
Ajax 693                context.Items[_requestDataKey] = data2;
Ajax 694                context.RewritePath(“~/UrlRouting.axd”); 
Ajax 695

        public ViewContext ViewContext {
            get {
                return ViewPage.ViewContext;
            }
        }

   
[AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand,
Level = AspNetHostingPermissionLevel.Minimal)]
   
[AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand,
Level = AspNetHostingPermissionLevel.Minimal)]
    public class ViewPage : Page, IViewDataContainer {
        private string _masterLocation;
        private object _viewData;

        private static IViewDataContainer GetViewDataContainer(Control
control) {
            // Walk up the control hierarchy until we find someone that
implements IViewDataContainer
            while (control != null) {
                control = control.Parent;
                IViewDataContainer vdc = control as
IViewDataContainer;
                if (vdc != null) {
                    return vdc;
                }
            }
            return null;
        }

以直接在 Controller 中 RenderView 一个用户控件(ViewUserControl),asp.net
mvc 会替我们创设了一个 “空白页” (ViewUserControlContainerPage
)来装载这一个控件RenderView(ViewUserControl) 有个限制,就是不可能有
MasterPage。

 

        public TempDataDictionary TempData {
            get {
                return ViewPage.TempData;
            }
        }

 

以此艺术很复杂,有恢宏的代码是参数的演讲 ,唯有最后一行是非同小可的。

咱俩从 UrlRoutingModule 起始,历经
MvcRouteHandler、MvcHandler、Controller、ActionFilterAttribute,直到最终的
ViewEngine、ViewPage.完成了一切ASP.NET MVC的生命周期探索。

接轨看这么些 WebFormViewEngine:

        public HtmlHelper Html {
            get;
            set;
        }

Ajax 696Ajax 697namespace System.Web.Mvc Ajax 698{
Ajax 699    using System;
Ajax 700    using System.Collections.Generic;
Ajax 701    using System.ComponentModel;
Ajax 702    using System.Diagnostics.CodeAnalysis;
Ajax 703    using System.Globalization;
Ajax 704    using System.Reflection;
Ajax 705    using System.Security.Principal;
Ajax 706    using System.Web;
Ajax 707    using System.Web.Mvc.Resources;
Ajax 708    using System.Web.Routing; 
Ajax 709
Ajax 710    [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
Ajax 711    [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
Ajax 712Ajax 713    public class Controller : IController Ajax 714{
Ajax 715        private RouteCollection _routeCollection;
Ajax 716        private IDictionary<string, object> _viewData;
Ajax 717        private IViewEngine _viewEngine; 
Ajax 718
Ajax 719Ajax 720        public ControllerContext ControllerContext Ajax 721{
Ajax 722            get;
Ajax 723            set;
Ajax 724        } 
Ajax 725
Ajax 726Ajax 727        public HttpContextBase HttpContext Ajax 728{
Ajax 729Ajax 730            get Ajax 731{
Ajax 732                return ControllerContext == null ? null : ControllerContext.HttpContext;
Ajax 733            }
Ajax 734        } 
Ajax 735
Ajax 736Ajax 737        public HttpRequestBase Request Ajax 738{
Ajax 739Ajax 740            get Ajax 741{
Ajax 742                return HttpContext == null ? null : HttpContext.Request;
Ajax 743            }
Ajax 744        } 
Ajax 745
Ajax 746Ajax 747        public HttpResponseBase Response Ajax 748{
Ajax 749Ajax 750            get Ajax 751{
Ajax 752                return HttpContext == null ? null : HttpContext.Response;
Ajax 753            }
Ajax 754        } 
Ajax 755
Ajax 756Ajax 757        internal RouteCollection RouteCollection Ajax 758{
Ajax 759Ajax 760            get Ajax 761{
Ajax 762Ajax 763                if (_routeCollection == null) Ajax 764{
Ajax 765                    _routeCollection = RouteTable.Routes;
Ajax 766                }
Ajax 767                return _routeCollection;
Ajax 768            }
Ajax 769Ajax 770            set Ajax 771{
Ajax 772                _routeCollection = value;
Ajax 773            }
Ajax 774        } 
Ajax 775
Ajax 776Ajax 777        public RouteData RouteData Ajax 778{
Ajax 779Ajax 780            get Ajax 781{
Ajax 782                return ControllerContext == null ? null : ControllerContext.RouteData;
Ajax 783            }
Ajax 784        } 
Ajax 785
Ajax 786Ajax 787        public HttpServerUtilityBase Server Ajax 788{
Ajax 789Ajax 790            get Ajax 791{
Ajax 792                return HttpContext == null ? null : HttpContext.Server;
Ajax 793            }
Ajax 794        } 
Ajax 795
Ajax 796        [System.Diagnostics.CodeAnalysis.SuppressMessage(“Microsoft.Usage”, “CA2227:CollectionPropertiesShouldBeReadOnly”,
Ajax 797            Justification = “This property is settable so that unit tests can provide mock implementations.”)]
Ajax 798Ajax 799        public TempDataDictionary TempData Ajax 800{
Ajax 801            get;
Ajax 802            set;
Ajax 803        } 
Ajax 804
Ajax 805Ajax 806        public IPrincipal User Ajax 807{
Ajax 808Ajax 809            get Ajax 810{
Ajax 811                return HttpContext == null ? null : HttpContext.User;
Ajax 812            }
Ajax 813        } 
Ajax 814
Ajax 815Ajax 816        public IDictionary<string, object> ViewData Ajax 817{
Ajax 818Ajax 819            get Ajax 820{
Ajax 821Ajax 822                if (_viewData == null) Ajax 823{
Ajax 824                    _viewData = new Dictionary<string, object>();
Ajax 825                }
Ajax 826                return _viewData;
Ajax 827            }
Ajax 828        } 
Ajax 829
Ajax 830Ajax 831        public IViewEngine ViewEngine Ajax 832{
Ajax 833Ajax 834            get Ajax 835{
Ajax 836                return _viewEngine ?? new WebFormViewEngine();
Ajax 837            }
Ajax 838Ajax 839            set Ajax 840{
Ajax 841Ajax 842                if (value == null) Ajax 843{
Ajax 844                    throw new ArgumentNullException(“value”);
Ajax 845                }
Ajax 846                _viewEngine = value;
Ajax 847            }
Ajax 848        } 
Ajax 849
Ajax 850Ajax 851        private static object ConvertParameterType(object value, Type destinationType, string parameterName, string actionName) Ajax 852{
Ajax 853Ajax 854            if (value == null || value.GetType() == destinationType) Ajax 855{
Ajax 856                return value;
Ajax 857            } 
Ajax 858
Ajax 859            TypeConverter converter = TypeDescriptor.GetConverter(destinationType);
Ajax 860            bool canConvertFrom = converter.CanConvertFrom(value.GetType());
Ajax 861Ajax 862            if (!canConvertFrom) Ajax 863{
Ajax 864                converter = TypeDescriptor.GetConverter(value.GetType());
Ajax 865            }
Ajax 866Ajax 867            if (!(canConvertFrom || converter.CanConvertTo(destinationType))) Ajax 868{
Ajax 869                throw new InvalidOperationException(String.Format(
Ajax 870                    CultureInfo.CurrentUICulture,
Ajax 871                    MvcResources.Controller_CannotConvertParameter,
Ajax 872                    parameterName, actionName, value, destinationType));
Ajax 873            }
Ajax 874Ajax 875            try Ajax 876{
Ajax 877                return canConvertFrom ? converter.ConvertFrom(value) : converter.ConvertTo(value, destinationType);
Ajax 878            }
Ajax 879Ajax 880            catch (Exception ex) Ajax 881{
Ajax 882                throw new InvalidOperationException(String.Format(
Ajax 883                    CultureInfo.CurrentUICulture,
Ajax 884                    MvcResources.Controller_CannotConvertParameter,
Ajax 885                    parameterName, actionName, value, destinationType),
Ajax 886                    ex);
Ajax 887            }
Ajax 888        } 
Ajax 889
Ajax 890Ajax 891        protected internal virtual void Execute(ControllerContext controllerContext) Ajax 892{
Ajax 893Ajax 894            if (controllerContext == null) Ajax 895{
Ajax 896                throw new ArgumentNullException(“controllerContext”);
Ajax 897            } 
Ajax 898
Ajax 899            ControllerContext = controllerContext;
Ajax 900            TempData = new TempDataDictionary(controllerContext.HttpContext); 
Ajax 901
Ajax 902            string actionName = RouteData.GetRequiredString(“action”);
Ajax 903Ajax 904            if (!InvokeAction(actionName)) Ajax 905{
Ajax 906                HandleUnknownAction(actionName);
Ajax 907            }
Ajax 908        } 
Ajax 909
Ajax 910Ajax 911        protected internal virtual void HandleUnknownAction(string actionName) Ajax 912{
Ajax 913            throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, MvcResources.Controller_UnknownAction, actionName));
Ajax 914        } 
Ajax 915
Ajax 916Ajax 917        protected internal bool InvokeAction(string actionName) Ajax 918{
Ajax 919            return InvokeAction(actionName, new RouteValueDictionary());
Ajax 920        } 
Ajax 921
Ajax 922Ajax 923        protected internal virtual bool InvokeAction(string actionName, RouteValueDictionary values) Ajax 924{
Ajax 925Ajax 926            if (String.IsNullOrEmpty(actionName)) Ajax 927{
Ajax 928                throw new ArgumentException(MvcResources.Common_NullOrEmpty, “actionName”);
Ajax 929            } 
Ajax 930
Ajax 931            // We have to loop through all the methods to make sure there isn’t
Ajax 932            // a conflict. If we stop the loop the first time we find a match
Ajax 933            // we might miss some error cases. 
Ajax 934
Ajax 935            MemberInfo[] membInfos = GetType().GetMember(actionName, MemberTypes.Method,
Ajax 936                BindingFlags.IgnoreCase | BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public);
Ajax 937            MethodInfo foundMatch = null; 
Ajax 938
Ajax 939Ajax 940            foreach (MemberInfo memberInfo in membInfos) Ajax 941{
Ajax 942                MethodInfo mi = (MethodInfo)memberInfo; 
Ajax 943
Ajax 944                // 1) Action methods must not have the non-action attribute in their inheritance chain, and
Ajax 945                // 2) special methods like constructors, property accessors, and event accessors cannot be action methods, and
Ajax 946                // 3) methods originally defined on Object (like ToString) or Controller cannot be action methods.
Ajax 947                if (!mi.IsDefined(typeof(NonActionAttribute), true) &&
Ajax 948                    !mi.IsSpecialName &&
Ajax 949Ajax 950                    mi.DeclaringType.IsSubclassOf(typeof(Controller))) Ajax 951{
Ajax 952Ajax 953                    if (foundMatch != null) Ajax 954{
Ajax 955                        throw new InvalidOperationException(
Ajax 956                            String.Format(CultureInfo.CurrentUICulture, MvcResources.Controller_MoreThanOneAction, actionName, GetType()));
Ajax 957                    }
Ajax 958                    foundMatch = mi;
Ajax 959                }
Ajax 960            } 
Ajax 961
Ajax 962Ajax 963            if (foundMatch != null) Ajax 964{
Ajax 965                InvokeActionMethod(foundMatch, values);
Ajax 966                return true;
Ajax 967            }
Ajax 968            return false;
Ajax 969        } 
Ajax 970
Ajax 971        [SuppressMessage(“Microsoft.Design”, “CA1011:ConsiderPassingBaseTypesAsParameters”,
Ajax 972            Justification = “We use MethodInfo since it represents only methods and not constructors.” +
Ajax 973            “This method only makes sense for use with methods.”)]
Ajax 974Ajax 975        protected internal virtual void InvokeActionMethod(MethodInfo methodInfo, RouteValueDictionary values) Ajax 976{
Ajax 977Ajax 978            if (methodInfo == null) Ajax 979{
Ajax 980                throw new ArgumentNullException(“methodInfo”);
Ajax 981            }
Ajax 982Ajax 983            if (values == null) Ajax 984{
Ajax 985                values = new RouteValueDictionary();
Ajax 986            }
Ajax 987Ajax 988            if (methodInfo.ContainsGenericParameters) Ajax 989{
Ajax 990                throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, MvcResources.Controller_ActionCannotBeGeneric, methodInfo.Name));
Ajax 991            } 
Ajax 992
Ajax 993            ParameterInfo[] methodParameters = methodInfo.GetParameters();
Ajax 994            object[] parameterValues = null;
Ajax 995Ajax 996            if (methodParameters.Length > 0) Ajax 997
Ajax 998
Ajax 999                parameterValues = new object[methodParameters.Length];
Ajax 1000Ajax 1001                for (int i = 0; i < methodParameters.Length; i++) Ajax 1002{
Ajax 1003                    ParameterInfo pi = methodParameters[i]; 
Ajax 1004
Ajax 1005Ajax 1006                    if (pi.IsOut || pi.ParameterType.IsByRef) Ajax 1007{
Ajax 1008                        throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, MvcResources.Controller_ReferenceParametersNotSupported, pi.Name, methodInfo.Name));
Ajax 1009                    } 
Ajax 1010
Ajax 1011                    bool valueRequired = true;
Ajax 1012Ajax 1013                    if (pi.ParameterType.IsClass) Ajax 1014{
Ajax 1015                        // Classes (ref types) don’t require values since we can pass in null
Ajax 1016                        valueRequired = false;
Ajax 1017                    }
Ajax 1018Ajax 1019                    else Ajax 1020{
Ajax 1021                        if ((pi.ParameterType.IsGenericType && !pi.ParameterType.IsGenericTypeDefinition) &&
Ajax 1022Ajax 1023                            (pi.ParameterType.GetGenericTypeDefinition() == typeof(Nullable<>))) Ajax 1024{
Ajax 1025                            // Nullable types don’t require values since we can pass in null
Ajax 1026                            valueRequired = false;
Ajax 1027                        }
Ajax 1028                    } 
Ajax 1029
Ajax 1030                    // Try to get a value for the parameter. We use this order of precedence:
Ajax 1031                    // 1. Explicitly-provided extra parameters in the call to InvokeAction()
Ajax 1032                    // 2. Values from the RouteData (could be from the typed-in URL or from the route’s default values)
Ajax 1033                    // 3. Request values (query string, form post data, cookie)
Ajax 1034                    object parameterValue = null;
Ajax 1035Ajax 1036                    if (!values.TryGetValue(methodParameters[i].Name, out parameterValue)) Ajax 1037{
Ajax 1038Ajax 1039                        if (RouteData == null || !RouteData.Values.TryGetValue(methodParameters[i].Name, out parameterValue)) Ajax 1040{
Ajax 1041Ajax 1042                            if (Request != null) Ajax 1043{
Ajax 1044                                parameterValue = Request[methodParameters[i].Name];
Ajax 1045                            }
Ajax 1046                        }
Ajax 1047                    } 
Ajax 1048
Ajax 1049Ajax 1050                    if (parameterValue == null && valueRequired) Ajax 1051{
Ajax 1052                        throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, MvcResources.Controller_MissingParameter, pi.Name, methodInfo.Name));
Ajax 1053                    } 
Ajax 1054
Ajax 1055Ajax 1056                    try Ajax 1057{
Ajax 1058                        parameterValues[i] = ConvertParameterType(parameterValue, methodParameters[i].ParameterType, methodParameters[i].Name, methodInfo.Name);
Ajax 1059                    }
Ajax 1060Ajax 1061                    catch (Exception ex) Ajax 1062{
Ajax 1063                        // Parameter value conversion errors are acceptable unless the value is required
Ajax 1064Ajax 1065                        if (valueRequired) Ajax 1066{
Ajax 1067                            throw new InvalidOperationException(String.Format(CultureInfo.CurrentUICulture, MvcResources.Controller_MissingParameter, pi.Name, methodInfo.Name), ex);
Ajax 1068                        }
Ajax 1069                    }
Ajax 1070                }
Ajax 1071            } 
Ajax 1072
Ajax 1073            InvokeActionMethodFilters(methodInfo, () => methodInfo.Invoke(this, parameterValues));
Ajax 1074        } 
Ajax 1075
Ajax 1076Ajax 1077        private void InvokeActionMethodFilters(MethodInfo methodInfo, Action continuation) Ajax 1078
Ajax 1079
Ajax 1080            // filters should execute in this order:
Ajax 1081            // controller virtual overrides -> controller base attributes -> controller type attributes ->
Ajax 1082            //   base action method attributes -> action method attributes 
Ajax 1083
Ajax 1084Ajax 1085            List<ActionFilterAttribute> filters = new List<ActionFilterAttribute>() Ajax 1086{
Ajax 1087                new ControllerActionFilter(this)
Ajax 1088            }; 
Ajax 1089
Ajax 1090            Stack<MemberInfo> memberChain = new Stack<MemberInfo>();
Ajax 1091            Type curType = GetType();
Ajax 1092Ajax 1093            while (curType != null) Ajax 1094{
Ajax 1095                memberChain.Push(curType);
Ajax 1096                curType = curType.BaseType;
Ajax 1097            } 
Ajax 1098
Ajax 1099            List<ActionFilterAttribute> sortedClassFilters = SortActionFilters(memberChain);
Ajax 1100            filters.AddRange(sortedClassFilters);
Ajax 1101            List<ActionFilterAttribute> sortedMethodFilters = PrepareMethodActionFilters(methodInfo);
Ajax 1102            filters.AddRange(sortedMethodFilters); 
Ajax 1103
Ajax 1104            FilterContext context = new FilterContext(ControllerContext, methodInfo);
Ajax 1105            ActionFilterExecutor executor = new ActionFilterExecutor(filters, context, continuation);
Ajax 1106            executor.Execute();
Ajax 1107        } 
Ajax 1108
Ajax 1109Ajax 1110        protected virtual void OnActionExecuted(FilterExecutedContext filterContext) Ajax 1111{
Ajax 1112        } 
Ajax 1113
Ajax 1114Ajax 1115        protected virtual void OnActionExecuting(FilterExecutingContext filterContext) Ajax 1116{
Ajax 1117        } 
Ajax 1118
Ajax 1119Ajax 1120        internal static List<ActionFilterAttribute> PrepareMethodActionFilters(MethodInfo methodInfo) Ajax 1121
Ajax 1122
Ajax 1123            Stack<MemberInfo> memberChain = new Stack<MemberInfo>();
Ajax 1124            memberChain.Push(methodInfo); 
Ajax 1125
Ajax 1126            MethodInfo baseMethod = methodInfo.GetBaseDefinition();
Ajax 1127            Type curType = methodInfo.DeclaringType.BaseType;
Ajax 1128Ajax 1129            while (true) Ajax 1130{
Ajax 1131                MemberInfo[] membInfos = curType.GetMember(methodInfo.Name, MemberTypes.Method,
Ajax 1132                    BindingFlags.IgnoreCase | BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public);
Ajax 1133                MethodInfo foundMatch = null;
Ajax 1134Ajax 1135                foreach (MemberInfo memberInfo in membInfos) Ajax 1136{
Ajax 1137                    MethodInfo mi = (MethodInfo)memberInfo;
Ajax 1138Ajax 1139                    if (mi.GetBaseDefinition() == baseMethod && mi.DeclaringType == curType) Ajax 1140{
Ajax 1141                        foundMatch = mi;
Ajax 1142                        break;
Ajax 1143                    }
Ajax 1144                }
Ajax 1145Ajax 1146                if (foundMatch == null) Ajax 1147{
Ajax 1148                    break;
Ajax 1149                }
Ajax 1150                memberChain.Push(foundMatch);
Ajax 1151                curType = curType.BaseType;
Ajax 1152            } 
Ajax 1153
Ajax 1154            return SortActionFilters(memberChain);
Ajax 1155        } 
Ajax 1156
Ajax 1157Ajax 1158        protected virtual void RedirectToAction(RouteValueDictionary values) Ajax 1159{
Ajax 1160            VirtualPathData vpd = RouteCollection.GetVirtualPath(ControllerContext, values);
Ajax 1161            string target = null;
Ajax 1162Ajax 1163            if (vpd != null) Ajax 1164{
Ajax 1165                target = vpd.VirtualPath;
Ajax 1166            }
Ajax 1167            HttpContext.Response.Redirect(target);
Ajax 1168        } 
Ajax 1169
Ajax 1170Ajax 1171        protected void RedirectToAction(string actionName) Ajax 1172{
Ajax 1173Ajax 1174            if (String.IsNullOrEmpty(actionName)) Ajax 1175{
Ajax 1176                throw new ArgumentException(MvcResources.Common_NullOrEmpty, “actionName”);
Ajax 1177            }
Ajax 1178            RouteValueDictionary valuesDictionary = new RouteValueDictionary();
Ajax 1179            valuesDictionary.Add(“action”, actionName);
Ajax 1180            RedirectToAction(valuesDictionary);
Ajax 1181        } 
Ajax 1182
Ajax 1183Ajax 1184        protected void RedirectToAction(string actionName, string controllerName) Ajax 1185{
Ajax 1186Ajax 1187            if (String.IsNullOrEmpty(actionName)) Ajax 1188{
Ajax 1189                throw new ArgumentException(MvcResources.Common_NullOrEmpty, “actionName”);
Ajax 1190            }
Ajax 1191Ajax 1192            if (String.IsNullOrEmpty(controllerName)) Ajax 1193{
Ajax 1194                throw new ArgumentException(MvcResources.Common_NullOrEmpty, “controllerName”);
Ajax 1195            }
Ajax 1196            RouteValueDictionary valuesDictionary = new RouteValueDictionary();
Ajax 1197            valuesDictionary.Add(“action”, actionName);
Ajax 1198            valuesDictionary.Add(“controller”, controllerName);
Ajax 1199            RedirectToAction(valuesDictionary);
Ajax 1200        } 
Ajax 1201
Ajax 1202Ajax 1203        protected void RenderView(string viewName) Ajax 1204{
Ajax 1205            RenderView(viewName, String.Empty, ViewData);
Ajax 1206        } 
Ajax 1207
Ajax 1208Ajax 1209        protected void RenderView(string viewName, string masterName) Ajax 1210{
Ajax 1211            RenderView(viewName, masterName, ViewData);
Ajax 1212        } 
Ajax 1213
Ajax 1214Ajax 1215        protected void RenderView(string viewName, object viewData) Ajax 1216{
Ajax 1217            RenderView(viewName, String.Empty, viewData);
Ajax 1218        } 
Ajax 1219
Ajax 1220Ajax 1221        protected virtual void RenderView(string viewName, string masterName, object viewData) Ajax 1222{
Ajax 1223            ViewContext viewContext = new ViewContext(ControllerContext, viewName, masterName, viewData, TempData);
Ajax 1224            ViewEngine.RenderView(viewContext);
Ajax 1225        } 
Ajax 1226
Ajax 1227Ajax 1228        private static List<ActionFilterAttribute> SortActionFilters(Stack<MemberInfo> memberChain) Ajax 1229{
Ajax 1230            List<ActionFilterAttribute> filters = new List<ActionFilterAttribute>(); 
Ajax 1231
Ajax 1232Ajax 1233            foreach (MemberInfo member in memberChain) Ajax 1234{
Ajax 1235Ajax 1236                ActionFilterAttribute[] attrs = (ActionFilterAttribute[])member.GetCustomAttributes(typeof(ActionFilterAttribute), false /**//* inherit */);
Ajax 1237                SortedList<int, ActionFilterAttribute> orderedFilters = new SortedList<int, ActionFilterAttribute>();
Ajax 1238Ajax 1239                foreach (ActionFilterAttribute filter in attrs) Ajax 1240{
Ajax 1241                    // filters are allowed to have the same order only if the order is -1.  in that case,
Ajax 1242                    // they are processed before explicitly ordered filters but in no particular order in
Ajax 1243                    // relation to one another.
Ajax 1244Ajax 1245                    if (filter.Order >= 0) Ajax 1246{
Ajax 1247Ajax 1248                        if (orderedFilters.ContainsKey(filter.Order)) Ajax 1249{
Ajax 1250                            throw new InvalidOperationException(
Ajax 1251                                String.Format(
Ajax 1252                                    CultureInfo.CurrentUICulture,
Ajax 1253                                    MvcResources.ActionFilter_DuplicateOrder,
Ajax 1254                                    member,
Ajax 1255                                    filter.Order));
Ajax 1256                        }
Ajax 1257                        orderedFilters.Add(filter.Order, filter);
Ajax 1258                    }
Ajax 1259Ajax 1260                    else Ajax 1261{
Ajax 1262                        filters.Add(filter);
Ajax 1263                    }
Ajax 1264                }
Ajax 1265                filters.AddRange(orderedFilters.Values);
Ajax 1266            } 
Ajax 1267
Ajax 1268            return filters;
Ajax 1269        } 
Ajax 1270
Ajax 1271Ajax 1272        IController Members#region IController Members
Ajax 1273Ajax 1274        void IController.Execute(ControllerContext controllerContext) Ajax 1275{
Ajax 1276            Execute(controllerContext);
Ajax 1277        }
Ajax 1278        #endregion 
Ajax 1279
Ajax 1280Ajax 1281        private sealed class ControllerActionFilter : ActionFilterAttribute Ajax 1282
Ajax 1283
Ajax 1284            private Controller _controller; 
Ajax 1285
Ajax 1286Ajax 1287            public ControllerActionFilter(Controller controller) Ajax 1288{
Ajax 1289                _controller = controller;
Ajax 1290            } 
Ajax 1291
Ajax 1292Ajax 1293            public override void OnActionExecuted(FilterExecutedContext filterContext) Ajax 1294{
Ajax 1295                _controller.OnActionExecuted(filterContext);
Ajax 1296            } 
Ajax 1297
Ajax 1298Ajax 1299            public override void OnActionExecuting(FilterExecutingContext filterContext) Ajax 1300{
Ajax 1301                _controller.OnActionExecuting(filterContext);
Ajax 1302            } 
Ajax 1303
Ajax 1304        } 
Ajax 1305
Ajax 1306    }
Ajax 1307

 

        public UrlHelper Url {
            get {
                return ViewPage.Url;
            }
        }

代码如下:

里头还定义了一个RequestData,首要就是眼前拍卖的HttpHandler和URL原始路径。来看望ASP.NET
HttpApplication 管线会相继拍卖下边的哀求:

            if (!String.IsNullOrEmpty(MasterLocation)) {
                MasterPageFile = MasterLocation;
            }
        }

Ajax 1308Ajax 1309internal ControllerBuilder ControllerBuilder Ajax 1310{
Ajax 1311Ajax 1312            get Ajax 1313{
Ajax 1314Ajax 1315                if (_controllerBuilder == null) Ajax 1316{
Ajax 1317                    _controllerBuilder = ControllerBuilder.Current;
Ajax 1318                }
Ajax 1319                return _controllerBuilder;
Ajax 1320            }
Ajax 1321Ajax 1322            set Ajax 1323{
Ajax 1324                _controllerBuilder = value;
Ajax 1325            }
Ajax 1326        } 

        public virtual void RenderView(ViewContext viewContext) {
            ViewContext = viewContext;
            Ajax = new AjaxHelper(viewContext);
            Html = new HtmlHelper(viewContext);
            Url = new UrlHelper(viewContext);

namespace System.Web.Mvc {
    using System.ComponentModel;
    using System.Globalization;
    using System.Web.Resources;
    using System.Web.UI;
    using System.Web.Mvc.Resources;

    private sealed class ViewUserControlContainerPage : ViewPage {
           public ViewUserControlContainerPage(ViewUserControl
userControl) {
               Controls.Add(userControl);
           }
       }

        public virtual void RenderView(ViewContext viewContext) {
            // TODO: Remove this hack. Without it, the browser appears
to always load cached output
           
viewContext.HttpContext.Response.Cache.SetExpires(DateTime.Now);
            ViewUserControlContainerPage containerPage = new
ViewUserControlContainerPage(this);
            containerPage.RenderView(viewContext);
        }

        [DefaultValue(“”)]
        public string ViewDataKey {
            get {
                return _viewDataKey ?? String.Empty;
            }
            set {
                _viewDataKey = value;
            }
        }

收获 Action 的名字,然后起头执行
InvokeAction,假诺找不到Action,则调用HandleUnknownAction,这是一个虚拟方法,可以在子类中重写,默认是抛出一个特别InvalidOperationException。

Ajax 1327Ajax 1328          protected internal virtual void Execute(ControllerContext controllerContext) Ajax 1329{
Ajax 1330Ajax 1331            if (controllerContext == null) Ajax 1332{
Ajax 1333                throw new ArgumentNullException(“controllerContext”);
Ajax 1334            } 
Ajax 1335
Ajax 1336            ControllerContext = controllerContext;
Ajax 1337            TempData = new TempDataDictionary(controllerContext.HttpContext); 
Ajax 1338
Ajax 1339            string actionName = RouteData.GetRequiredString(“action”);
Ajax 1340Ajax 1341            if (!InvokeAction(actionName)) Ajax 1342{
Ajax 1343                HandleUnknownAction(actionName);
Ajax 1344            }
Ajax 1345        } 
Ajax 1346

再次来到MvcHandler的 ProcessRequest
,DefaultControllerFactory.CreateController(RequestContext,
requiredString) 来回到 IController
实例。下边看看DefaultControllerFactory的代码:

        public string MasterLocation {
            get {
                return _masterLocation ?? String.Empty;
            }
            set {
                _masterLocation = value;
            }
        }

        private sealed class ViewUserControlContainerPage : ViewPage {
            public ViewUserControlContainerPage(ViewUserControl
userControl) {
                Controls.Add(userControl);
            }
        }
    }
}

Ajax 1347  protected void Application_Start(object sender, EventArgs e)
Ajax 1348Ajax 1349       Ajax 1350{
Ajax 1351           RegisterRoutes(RouteTable.Routes);
Ajax 1352           CreateDefaultUserIfNotExists();
Ajax 1353       } 
Ajax 1354
Ajax 1355       public static void RegisterRoutes(RouteCollection routes)
Ajax 1356Ajax 1357       Ajax 1358{
Ajax 1359           int iisVersion = Convert.ToInt32(ConfigurationManager.AppSettings[“IISVersion”], System.Globalization.CultureInfo.InvariantCulture); 
Ajax 1360
Ajax 1361           if (iisVersion >= 7)
Ajax 1362Ajax 1363           Ajax 1364{
Ajax 1365               RegisterRoutesForNewIIS(routes);
Ajax 1366           }
Ajax 1367           else
Ajax 1368Ajax 1369           Ajax 1370{
Ajax 1371               RegisterRoutesForOldIIS(routes);
Ajax 1372           }
Ajax 1373       } 
Ajax 1374
Ajax 1375      private static void RegisterRoutesForNewIIS(ICollection<RouteBase> routes)
Ajax 1376Ajax 1377       Ajax 1378{
Ajax 1379Ajax 1380           routes.Add(new Route(“User/Login”, new RouteValueDictionary(new Ajax 1381{ controller = “User”, action = “Login” }), new MvcRouteHandler()));
Ajax 1382Ajax 1383           routes.Add(new Route(“User/Logout”, new RouteValueDictionary(new Ajax 1384{ controller = “User”, action = “Logout” }), new MvcRouteHandler()));
Ajax 1385Ajax 1386           routes.Add(new Route(“User/Signup”, new RouteValueDictionary(new Ajax 1387{ controller = “User”, action = “Signup” }), new MvcRouteHandler()));
Ajax 1388Ajax 1389           routes.Add(new Route(“User/SendPassword”, new RouteValueDictionary(new Ajax 1390{ controller = “User”, action = “SendPassword” }), new MvcRouteHandler())); 
Ajax 1391
Ajax 1392Ajax 1393           routes.Add(new Route(“Story/Detail/{id}”, new RouteValueDictionary(new Ajax 1394{ controller = “Story”, action = “Detail” }), new MvcRouteHandler()));
Ajax 1395Ajax 1396           routes.Add(new Route(“Story/Upcoming/{page}”, new RouteValueDictionary(new Ajax 1397{ controller = “Story”, action = “Upcoming” }), new MvcRouteHandler()));
Ajax 1398Ajax 1399           routes.Add(new Route(“Story/Search/{q}/{page}”, new RouteValueDictionary(new Ajax 1400{ controller = “Story”, action = “Search” }), new MvcRouteHandler())); 
Ajax 1401
Ajax 1402           var defaults = new RouteValueDictionary (
Ajax 1403                                                       new
Ajax 1404Ajax 1405                                                       Ajax 1406{
Ajax 1407                                                           controller = “Story”,
Ajax 1408                                                           action = “Category”,
Ajax 1409                                                           name = (string)null,
Ajax 1410                                                           page = (int?)null
Ajax 1411                                                       }
Ajax 1412                                                   ); 
Ajax 1413
Ajax 1414           routes.Add(new Route(“Story/Category/{page}”, defaults, new MvcRouteHandler()));
Ajax 1415           routes.Add(new Route(“Story/{action}/{name}/{page}”, defaults, new MvcRouteHandler()));
Ajax 1416           routes.Add(new Route(“{controller}/{action}/{id}”, defaults, new MvcRouteHandler()));
Ajax 1417           routes.Add(new Route(“Default.aspx”, defaults, new MvcRouteHandler()));
Ajax 1418       } 
Ajax 1419
Ajax 1420       private static void RegisterRoutesForOldIIS(ICollection<RouteBase> routes)
Ajax 1421Ajax 1422       Ajax 1423{
Ajax 1424Ajax 1425           routes.Add(new Route(“User.mvc/Login”, new RouteValueDictionary(new Ajax 1426{ controller = “User”, action = “Login” }), new MvcRouteHandler()));
Ajax 1427Ajax 1428           routes.Add(new Route(“User.mvc/Logout”, new RouteValueDictionary(new Ajax 1429{ controller = “User”, action = “Logout” }), new MvcRouteHandler()));
Ajax 1430Ajax 1431           routes.Add(new Route(“User.mvc/Signup”, new RouteValueDictionary(new Ajax 1432{ controller = “User”, action = “Signup” }), new MvcRouteHandler()));
Ajax 1433Ajax 1434           routes.Add(new Route(“User.mvc/SendPassword”, new RouteValueDictionary(new Ajax 1435{ controller = “User”, action = “SendPassword” }), new MvcRouteHandler())); 
Ajax 1436
Ajax 1437Ajax 1438           routes.Add(new Route(“Story.mvc/Detail/{id}”, new RouteValueDictionary(new Ajax 1439{ controller = “Story”, action = “Detail” }), new MvcRouteHandler()));
Ajax 1440Ajax 1441           routes.Add(new Route(“Story.mvc/Upcoming/{page}”, new RouteValueDictionary(new Ajax 1442{ controller = “Story”, action = “Upcoming” }), new MvcRouteHandler()));
Ajax 1443Ajax 1444           routes.Add(new Route(“Story.mvc/Search/{q}/{page}”, new RouteValueDictionary(new Ajax 1445{ controller = “Story”, action = “Search” }), new MvcRouteHandler())); 
Ajax 1446
Ajax 1447           var defaults = new RouteValueDictionary(
Ajax 1448                                                       new
Ajax 1449Ajax 1450                                                       Ajax 1451{
Ajax 1452                                                           controller = “Story”,
Ajax 1453                                                           action = “Category”,
Ajax 1454                                                           name = (string)null,
Ajax 1455                                                           page = (int?)null
Ajax 1456                                                       }
Ajax 1457                                                   ); 
Ajax 1458
Ajax 1459           routes.Add(new Route(“Story.mvc/Category/{page}”, defaults, new MvcRouteHandler()));
Ajax 1460           routes.Add(new Route(“Story.mvc/{action}/{name}/{page}”, defaults, new MvcRouteHandler()));
Ajax 1461           routes.Add(new Route(“{controller}.mvc/{action}/{id}”, defaults, new MvcRouteHandler()));
Ajax 1462           routes.Add(new Route(“Default.aspx”, defaults, new MvcRouteHandler()));
Ajax 1463       } 
Ajax 1464
Ajax 1465

        public ViewData ViewData {
            get {
                EnsureViewData();
                return new ViewData(_viewData);
            }
        }

Ajax 1466namespace System.Web.Routing
Ajax 1467Ajax 1468Ajax 1469{
Ajax 1470    using System;
Ajax 1471    using System.Globalization;
Ajax 1472    using System.Runtime.CompilerServices;
Ajax 1473    using System.Security.Permissions;
Ajax 1474    using System.Web;
Ajax 1475    using System.Web.Resources; 
Ajax 1476
Ajax 1477    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal), AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
Ajax 1478    public class UrlRoutingModule : IHttpModule
Ajax 1479Ajax 1480    Ajax 1481{
Ajax 1482        private static readonly object _requestDataKey = new object();
Ajax 1483        private System.Web.Routing.RouteCollection _routeCollection; 
Ajax 1484
Ajax 1485        protected virtual void Dispose()
Ajax 1486Ajax 1487        Ajax 1488{
Ajax 1489        } 
Ajax 1490
Ajax 1491        protected virtual void Init(HttpApplication application)
Ajax 1492Ajax 1493        Ajax 1494{
Ajax 1495            application.PostResolveRequestCache += new EventHandler(this.OnApplicationPostResolveRequestCache);
Ajax 1496            application.PostMapRequestHandler += new EventHandler(this.OnApplicationPostMapRequestHandler);
Ajax 1497        } 
Ajax 1498
Ajax 1499        private void OnApplicationPostMapRequestHandler(object sender, EventArgs e)
Ajax 1500Ajax 1501        Ajax 1502{
Ajax 1503            HttpContextBase context = new HttpContextWrapper2(((HttpApplication) sender).Context);
Ajax 1504            this.PostMapRequestHandler(context);
Ajax 1505        } 
Ajax 1506
Ajax 1507        private void OnApplicationPostResolveRequestCache(object sender, EventArgs e)
Ajax 1508Ajax 1509        Ajax 1510{
Ajax 1511            HttpContextBase context = new HttpContextWrapper2(((HttpApplication) sender).Context);
Ajax 1512            this.PostResolveRequestCache(context);
Ajax 1513        } 
Ajax 1514
Ajax 1515        public virtual void PostMapRequestHandler(HttpContextBase context)
Ajax 1516Ajax 1517        Ajax 1518{
Ajax 1519            RequestData data = (RequestData) context.Items[_requestDataKey];
Ajax 1520            if (data != null)
Ajax 1521Ajax 1522            Ajax 1523{
Ajax 1524                context.RewritePath(data.OriginalPath);
Ajax 1525                context.Handler = data.HttpHandler;
Ajax 1526            }
Ajax 1527        } 
Ajax 1528
Ajax 1529        public virtual void PostResolveRequestCache(HttpContextBase context)
Ajax 1530Ajax 1531        Ajax 1532{
Ajax 1533            RouteData routeData = this.RouteCollection.GetRouteData(context);
Ajax 1534            if (routeData != null)
Ajax 1535Ajax 1536            Ajax 1537{
Ajax 1538                IRouteHandler routeHandler = routeData.RouteHandler;
Ajax 1539                if (routeHandler == null)
Ajax 1540Ajax 1541                Ajax 1542{
Ajax 1543                    throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, RoutingResources.UrlRoutingModule_NoRouteHandler, new object[0]));
Ajax 1544                }
Ajax 1545                RequestContext requestContext = new RequestContext(context, routeData);
Ajax 1546                IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext);
Ajax 1547                if (httpHandler == null)
Ajax 1548Ajax 1549                Ajax 1550{
Ajax 1551Ajax 1552                    throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, RoutingResources.UrlRoutingModule_NoHttpHandler, new object[] Ajax 1553{ routeHandler.GetType() }));
Ajax 1554                }
Ajax 1555                RequestData data2 = new RequestData();
Ajax 1556                data2.OriginalPath = context.Request.Path;
Ajax 1557                data2.HttpHandler = httpHandler;
Ajax 1558                context.Items[_requestDataKey] = data2;
Ajax 1559                context.RewritePath(“~/UrlRouting.axd”);
Ajax 1560            }
Ajax 1561        } 
Ajax 1562
Ajax 1563        void IHttpModule.Dispose()
Ajax 1564Ajax 1565        Ajax 1566{
Ajax 1567            this.Dispose();
Ajax 1568        } 
Ajax 1569
Ajax 1570        void IHttpModule.Init(HttpApplication application)
Ajax 1571Ajax 1572        Ajax 1573{
Ajax 1574            this.Init(application);
Ajax 1575        } 
Ajax 1576
Ajax 1577        public System.Web.Routing.RouteCollection RouteCollection
Ajax 1578Ajax 1579        Ajax 1580{
Ajax 1581            get
Ajax 1582Ajax 1583            Ajax 1584{
Ajax 1585                if (this._routeCollection == null)
Ajax 1586Ajax 1587                Ajax 1588{
Ajax 1589                    this._routeCollection = RouteTable.Routes;
Ajax 1590                }
Ajax 1591                return this._routeCollection;
Ajax 1592            }
Ajax 1593            set
Ajax 1594Ajax 1595            Ajax 1596{
Ajax 1597                this._routeCollection = value;
Ajax 1598            }
Ajax 1599        } 
Ajax 1600
Ajax 1601 
Ajax 1602
Ajax 1603}
Ajax 1604
Ajax 1605

       
[System.Diagnostics.CodeAnalysis.SuppressMessage(“Microsoft.Security”,
“CA2109:ReviewVisibleEventHandlers”)]
        protected override void OnPreInit(EventArgs e) {
            base.OnPreInit(e);

相关文章