MVC ASP.net流程 源代码分析
AppDomainFactory.cs
1. public Object Create(String appId, String appPath)
public Object Create(String appId, String appPath) {
try {
//
// Fill app a Dictionary with 'binding rules' -- name value string pairs
// for app domain creation
// // if (appPath[] == '.') {
System.IO.FileInfo file = new System.IO.FileInfo(appPath);
appPath = file.FullName;
} if (!StringUtil.StringEndsWith(appPath, '\\')) {
appPath = appPath + "\\";
} // Create new app domain via App Manager
#if FEATURE_PAL // FEATURE_PAL does not enable IIS-based hosting features
throw new NotImplementedException("ROTORTODO");
#else // FEATURE_PAL
//创建应用程序域
ISAPIApplicationHost appHost = new ISAPIApplicationHost(appId, appPath, false /*validatePhysicalPath*/);
//创建ISAPIRuntime
ISAPIRuntime isapiRuntime = (ISAPIRuntime)_appManager.CreateObjectInternal(appId, typeof(ISAPIRuntime), appHost,
false /*failIfExists*/, null /*hostingParameters*/); isapiRuntime.StartProcessing(); return new ObjectHandle(isapiRuntime);
#endif // FEATURE_PAL
}
catch (Exception e) {
Debug.Trace("internal", "AppDomainFactory::Create failed with " + e.GetType().FullName + ": " + e.Message + "\r\n" + e.StackTrace);
throw;
}
}
2.appManager.Create._appManager.CreateObjectInternal
internal IRegisteredObject CreateObjectInternal(
String appId,
Type type,
IApplicationHost appHost,
bool failIfExists,
HostingEnvironmentParameters hostingParameters) { // check that type is as IRegisteredObject
if (!typeof(IRegisteredObject).IsAssignableFrom(type))
throw new ArgumentException(SR.GetString(SR.Not_IRegisteredObject, type.FullName), "type"); // get hosting environment 创建宿主环境
HostingEnvironment env = GetAppDomainWithHostingEnvironment(appId, appHost, hostingParameters); // create the managed object in the worker app domain
// When marshaling Type, the AppDomain must have FileIoPermission to the assembly, which is not
// always the case, so we marshal the assembly qualified name instead
ObjectHandle h = env.CreateWellKnownObjectInstance(type.AssemblyQualifiedName, failIfExists);
return (h != null) ? h.Unwrap() as IRegisteredObject : null;
}
ISAPIRuntime
public int ProcessRequest(IntPtr ecb, int iWRType) {
IntPtr pHttpCompletion = IntPtr.Zero;
if (iWRType == WORKER_REQUEST_TYPE_IN_PROC_VERSION_2) {
pHttpCompletion = ecb;
ecb = UnsafeNativeMethods.GetEcb(pHttpCompletion);
}
ISAPIWorkerRequest wr = null;
try {
bool useOOP = (iWRType == WORKER_REQUEST_TYPE_OOP);
wr = ISAPIWorkerRequest.CreateWorkerRequest(ecb, useOOP);
wr.Initialize(); // check if app path matches (need to restart app domain?)
String wrPath = wr.GetAppPathTranslated();
String adPath = HttpRuntime.AppDomainAppPathInternal; if (adPath == null ||
StringUtil.EqualsIgnoreCase(wrPath, adPath)) { HttpRuntime.ProcessRequestNoDemand(wr);
return ;
}
else {
// need to restart app domain
HttpRuntime.ShutdownAppDomain(ApplicationShutdownReason.PhysicalApplicationPathChanged,
SR.GetString(SR.Hosting_Phys_Path_Changed,
adPath,
wrPath));
return ;
}
}
catch(Exception e) {
try {
WebBaseEvent.RaiseRuntimeError(e, this);
} catch {} // Have we called HSE_REQ_DONE_WITH_SESSION? If so, don't re-throw.
if (wr != null && wr.Ecb == IntPtr.Zero) {
if (pHttpCompletion != IntPtr.Zero) {
UnsafeNativeMethods.SetDoneWithSessionCalled(pHttpCompletion);
}
// if this is a thread abort exception, cancel the abort
if (e is ThreadAbortException) {
Thread.ResetAbort();
}
// IMPORTANT: if this thread is being aborted because of an AppDomain.Unload,
// the CLR will still throw an AppDomainUnloadedException. The native caller
// must special case COR_E_APPDOMAINUNLOADED(0x80131014) and not
// call HSE_REQ_DONE_WITH_SESSION more than once.
return ;
} // re-throw if we have not called HSE_REQ_DONE_WITH_SESSION
throw;
}
}
HttpRuntime
1.ProcessRequestNow().ProcessRequestInternal()
1.创建HttpContext
2.向HttpApplicationFactory类的一个实例申请一个HttpApplication
3.调用HttpApplication的InitalModule
private void ProcessRequestInternal(HttpWorkerRequest wr) {
// Count active requests
Interlocked.Increment(ref _activeRequestCount); if (_disposingHttpRuntime) {
// Dev11 333176: An appdomain is unloaded before all requests are served, resulting in System.AppDomainUnloadedException during isapi completion callback
//
// HttpRuntim.Dispose could have already finished on a different thread when we had no active requests
// In this case we are about to start or already started unloading the appdomain so we will reject the request the safest way possible
try {
wr.SendStatus(, "Server Too Busy");
wr.SendKnownResponseHeader(HttpWorkerRequest.HeaderContentType, "text/html; charset=utf-8");
byte[] body = Encoding.ASCII.GetBytes("<html><body>Server Too Busy</body></html>");
wr.SendResponseFromMemory(body, body.Length);
// this will flush synchronously because of HttpRuntime.ShutdownInProgress
wr.FlushResponse(true);
wr.EndOfRequest();
} finally {
Interlocked.Decrement(ref _activeRequestCount);
}
return;
} // Construct the Context on HttpWorkerRequest, hook everything together
HttpContext context; try {
context = new HttpContext(wr, false /* initResponseWriter */);
}
catch {
try {
// If we fail to create the context for any reason, send back a 400 to make sure
// the request is correctly closed (relates to VSUQFE3962)
wr.SendStatus(, "Bad Request");
wr.SendKnownResponseHeader(HttpWorkerRequest.HeaderContentType, "text/html; charset=utf-8");
byte[] body = Encoding.ASCII.GetBytes("<html><body>Bad Request</body></html>");
wr.SendResponseFromMemory(body, body.Length);
wr.FlushResponse(true);
wr.EndOfRequest();
return;
} finally {
Interlocked.Decrement(ref _activeRequestCount);
}
} wr.SetEndOfSendNotification(_asyncEndOfSendCallback, context); HostingEnvironment.IncrementBusyCount(); try {
// First request initialization
try {
EnsureFirstRequestInit(context);
}
catch {
// If we are handling a DEBUG request, ignore the FirstRequestInit exception.
// This allows the HttpDebugHandler to execute, and lets the debugger attach to
// the process (VSWhidbey 358135)
if (!context.Request.IsDebuggingRequest) {
throw;
}
} // Init response writer (after we have config in first request init)
// no need for impersonation as it is handled in config system
context.Response.InitResponseWriter(); // Get application instance
IHttpHandler app = HttpApplicationFactory.GetApplicationInstance(context); if (app == null)
throw new HttpException(SR.GetString(SR.Unable_create_app_object)); if (EtwTrace.IsTraceEnabled(EtwTraceLevel.Verbose, EtwTraceFlags.Infrastructure)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_START_HANDLER, context.WorkerRequest, app.GetType().FullName, "Start"); if (app is IHttpAsyncHandler) {
// asynchronous handler
IHttpAsyncHandler asyncHandler = (IHttpAsyncHandler)app;
context.AsyncAppHandler = asyncHandler;
asyncHandler.BeginProcessRequest(context, _handlerCompletionCallback, context);
}
else {
// synchronous handler
app.ProcessRequest(context);
FinishRequest(context.WorkerRequest, context, null);
}
}
catch (Exception e) {
context.Response.InitResponseWriter();
FinishRequest(wr, context, e);
}
}
IHttpHandler app = HttpApplicationFactory.GetApplicationInstance(context);
internal static IHttpHandler GetApplicationInstance(HttpContext context) {
if (_customApplication != null)
return _customApplication; // Check to see if it's a debug auto-attach request
if (context.Request.IsDebuggingRequest)
return new HttpDebugHandler(); _theApplicationFactory.EnsureInited(); _theApplicationFactory.EnsureAppStartCalled(context); return _theApplicationFactory.GetNormalApplicationInstance(context);
} private HttpApplication GetNormalApplicationInstance(HttpContext context) {
HttpApplication app = null; lock (_freeList) {
if (_numFreeAppInstances > ) {
app = (HttpApplication)_freeList.Pop();
_numFreeAppInstances--; if (_numFreeAppInstances < _minFreeAppInstances) {
_minFreeAppInstances = _numFreeAppInstances;
}
}
} if (app == null) {
// If ran out of instances, create a new one
app = (HttpApplication)HttpRuntime.CreateNonPublicInstance(_theApplicationType); using (new ApplicationImpersonationContext()) {
app.InitInternal(context, _state, _eventHandlerMethods);
}
} if (AppSettings.UseTaskFriendlySynchronizationContext) {
// When this HttpApplication instance is no longer in use, recycle it.
app.ApplicationInstanceConsumersCounter = new CountdownTask(); // representing required call to HttpApplication.ReleaseAppInstance
app.ApplicationInstanceConsumersCounter.Task.ContinueWith((_, o) => RecycleApplicationInstance((HttpApplication)o), app, TaskContinuationOptions.ExecuteSynchronously);
}
return app;
}
HttpApplication
internal void InitInternal(HttpContext context, HttpApplicationState state, MethodInfo[] handlers) {
Debug.Assert(context != null, "context != null"); // Remember state
_state = state; PerfCounters.IncrementCounter(AppPerfCounter.PIPELINES); try {
try {
// Remember context for config lookups
_initContext = context;
_initContext.ApplicationInstance = this; // Set config path to be application path for the application initialization
context.ConfigurationPath = context.Request.ApplicationPathObject; // keep HttpContext.Current working while running user code
using (new DisposableHttpContextWrapper(context)) { // Build module list from config
if (HttpRuntime.UseIntegratedPipeline) { Debug.Assert(_moduleConfigInfo != null, "_moduleConfigInfo != null");
Debug.Assert(_moduleConfigInfo.Count >= , "_moduleConfigInfo.Count >= 0"); try {
context.HideRequestResponse = true;
_hideRequestResponse = true;
InitIntegratedModules();
}
finally {
context.HideRequestResponse = false;
_hideRequestResponse = false;
}
}
else {
InitModules(); // this is used exclusively for integrated mode
Debug.Assert(null == _moduleContainers, "null == _moduleContainers");
} // Hookup event handlers via reflection
if (handlers != null)
HookupEventHandlersForApplicationAndModules(handlers); // Initialization of the derived class
_context = context;
if (HttpRuntime.UseIntegratedPipeline && _context != null) {
_context.HideRequestResponse = true;
}
_hideRequestResponse = true; try {
Init();
}
catch (Exception e) {
RecordError(e);
}
} if (HttpRuntime.UseIntegratedPipeline && _context != null) {
_context.HideRequestResponse = false;
}
_hideRequestResponse = false;
_context = null;
_resumeStepsWaitCallback= new WaitCallback(this.ResumeStepsWaitCallback); // Construct the execution steps array
if (HttpRuntime.UseIntegratedPipeline) {
_stepManager = new PipelineStepManager(this);
}
else {
_stepManager = new ApplicationStepManager(this);
} _stepManager.BuildSteps(_resumeStepsWaitCallback);
}
finally {
_initInternalCompleted = true; // Reset config path
context.ConfigurationPath = null; // don't hold on to the context
_initContext.ApplicationInstance = null;
_initContext = null;
}
}
catch { // Protect against exception filters
throw;
}
}
private void HookupEventHandlersForApplicationAndModules(MethodInfo[] handlers) {
_currentModuleCollectionKey = HttpApplicationFactory.applicationFileName; if(null == _pipelineEventMasks) {
Dictionary<string, RequestNotification> dict = new Dictionary<string, RequestNotification>();
BuildEventMaskDictionary(dict);
if(null == _pipelineEventMasks) {
_pipelineEventMasks = dict;
}
} for (int i = ; i < handlers.Length; i++) {
MethodInfo appMethod = handlers[i];
String appMethodName = appMethod.Name;
int namePosIndex = appMethodName.IndexOf('_');
String targetName = appMethodName.Substring(, namePosIndex); // Find target for method
Object target = null; if (StringUtil.EqualsIgnoreCase(targetName, "Application"))
target = this;
else if (_moduleCollection != null)
target = _moduleCollection[targetName]; if (target == null)
continue; // Find event on the module type
Type targetType = target.GetType();
EventDescriptorCollection events = TypeDescriptor.GetEvents(targetType);
string eventName = appMethodName.Substring(namePosIndex+); EventDescriptor foundEvent = events.Find(eventName, true);
if (foundEvent == null
&& StringUtil.EqualsIgnoreCase(eventName.Substring(, ), "on")) { eventName = eventName.Substring();
foundEvent = events.Find(eventName, true);
} MethodInfo addMethod = null;
if (foundEvent != null) {
EventInfo reflectionEvent = targetType.GetEvent(foundEvent.Name);
Debug.Assert(reflectionEvent != null);
if (reflectionEvent != null) {
addMethod = reflectionEvent.GetAddMethod();
}
} if (addMethod == null)
continue; ParameterInfo[] addMethodParams = addMethod.GetParameters(); if (addMethodParams.Length != )
continue; // Create the delegate from app method to pass to AddXXX(handler) method Delegate handlerDelegate = null; ParameterInfo[] appMethodParams = appMethod.GetParameters(); if (appMethodParams.Length == ) {
// If the app method doesn't have arguments --
// -- hookup via intermidiate handler // only can do it for EventHandler, not strongly typed
if (addMethodParams[].ParameterType != typeof(System.EventHandler))
continue; ArglessEventHandlerProxy proxy = new ArglessEventHandlerProxy(this, appMethod);
handlerDelegate = proxy.Handler;
}
else {
// Hookup directly to the app methods hoping all types match try {
handlerDelegate = Delegate.CreateDelegate(addMethodParams[].ParameterType, this, appMethodName);
}
catch {
// some type mismatch
continue;
}
} // Call the AddXXX() to hook up the delegate try {
addMethod.Invoke(target, new Object[]{handlerDelegate});
}
catch {
if (HttpRuntime.UseIntegratedPipeline) {
throw;
}
} if (eventName != null) {
if (_pipelineEventMasks.ContainsKey(eventName)) {
if (!StringUtil.StringStartsWith(eventName, "Post")) {
_appRequestNotifications |= _pipelineEventMasks[eventName];
}
else {
_appPostNotifications |= _pipelineEventMasks[eventName];
}
}
}
}
}
private void RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers) {
RequestNotification requestNotifications;
RequestNotification postRequestNotifications; // register an implicit filter module
RegisterIntegratedEvent(appContext,
IMPLICIT_FILTER_MODULE,
RequestNotification.UpdateRequestCache| RequestNotification.LogRequest /*requestNotifications*/,
0 /*postRequestNotifications*/,
String.Empty /*type*/,
String.Empty /*precondition*/,
true /*useHighPriority*/); // integrated pipeline will always use serverModules instead of <httpModules>
_moduleCollection = GetModuleCollection(appContext); if (handlers != null) {
HookupEventHandlersForApplicationAndModules(handlers);
} // 1643363: Breaking Change: ASP.Net v2.0: Application_OnStart is called after Module.Init (Integarted mode)
HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(context, this); // Call Init on HttpApplication derived class ("global.asax")
// and process event subscriptions before processing other modules.
// Doing this now prevents clearing any events that may
// have been added to event handlers during instantiation of this instance.
// NOTE: If "global.asax" has a constructor which hooks up event handlers,
// then they were added to the event handler lists but have not been registered with IIS yet,
// so we MUST call ProcessEventSubscriptions on it first, before the other modules.
_currentModuleCollectionKey = HttpApplicationFactory.applicationFileName; try {
_hideRequestResponse = true;
context.HideRequestResponse = true;
_context = context;
Init();
}
catch (Exception e) {
RecordError(e);
Exception error = context.Error;
if (error != null) {
throw error;
}
}
finally {
_context = null;
context.HideRequestResponse = false;
_hideRequestResponse = false;
} ProcessEventSubscriptions(out requestNotifications, out postRequestNotifications); // Save the notification subscriptions so we can register them with IIS later, after
// we call HookupEventHandlersForApplicationAndModules and process global.asax event handlers.
_appRequestNotifications |= requestNotifications;
_appPostNotifications |= postRequestNotifications; for (int i = 0; i < _moduleCollection.Count; i++) {
_currentModuleCollectionKey = _moduleCollection.GetKey(i);
IHttpModule httpModule = _moduleCollection.Get(i);
ModuleConfigurationInfo moduleInfo = _moduleConfigInfo[i]; #if DBG
Debug.Trace("PipelineRuntime", "RegisterEventSubscriptionsWithIIS: name=" + CurrentModuleCollectionKey
+ ", type=" + httpModule.GetType().FullName + "\n"); // make sure collections are in sync
Debug.Assert(moduleInfo.Name == _currentModuleCollectionKey, "moduleInfo.Name == _currentModuleCollectionKey");
#endif httpModule.Init(this); ProcessEventSubscriptions(out requestNotifications, out postRequestNotifications); // are any events wired up?
if (requestNotifications != 0 || postRequestNotifications != 0) { RegisterIntegratedEvent(appContext,
moduleInfo.Name,
requestNotifications,
postRequestNotifications,
moduleInfo.Type,
moduleInfo.Precondition,
false /*useHighPriority*/);
}
} // WOS 1728067: RewritePath does not remap the handler when rewriting from a non-ASP.NET request
// register a default implicit handler
RegisterIntegratedEvent(appContext,
IMPLICIT_HANDLER,
RequestNotification.ExecuteRequestHandler | RequestNotification.MapRequestHandler /*requestNotifications*/,
RequestNotification.EndRequest /*postRequestNotifications*/,
String.Empty /*type*/,
String.Empty /*precondition*/,
false /*useHighPriority*/);
}
UrlRoutingModule
protected virtual void Init(HttpApplication application) { //////////////////////////////////////////////////////////////////
// Check if this module has been already addded
if (application.Context.Items[_contextKey] != null) {
return; // already added to the pipeline
}
application.Context.Items[_contextKey] = _contextKey; // Ideally we would use the MapRequestHandler event. However, MapRequestHandler is not available
// in II6 or IIS7 ISAPI Mode. Instead, we use PostResolveRequestCache, which is the event immediately
// before MapRequestHandler. This allows use to use one common codepath for all versions of IIS.
application.PostResolveRequestCache += OnApplicationPostResolveRequestCache;
}
public virtual void PostResolveRequestCache(HttpContextBase context) {
// Match the incoming URL against the route table
RouteData routeData = RouteCollection.GetRouteData(context); // Do nothing if no route found
if (routeData == null) {
return;
} // If a route was found, get an IHttpHandler from the route's RouteHandler
IRouteHandler routeHandler = routeData.RouteHandler;
if (routeHandler == null) {
throw new InvalidOperationException(
String.Format(
CultureInfo.CurrentCulture,
SR.GetString(SR.UrlRoutingModule_NoRouteHandler)));
} // This is a special IRouteHandler that tells the routing module to stop processing
// routes and to let the fallback handler handle the request.
if (routeHandler is StopRoutingHandler) {
return;
} RequestContext requestContext = new RequestContext(context, routeData); // Dev10 766875 Adding RouteData to HttpContext
context.Request.RequestContext = requestContext; IHttpHandler httpHandler = routeHandler.GetHttpHandler(requestContext);//创建MVCHandler 并将RequestContext存入
if (httpHandler == null) {
throw new InvalidOperationException(
String.Format(
CultureInfo.CurrentUICulture,
SR.GetString(SR.UrlRoutingModule_NoHttpHandler),
routeHandler.GetType()));
} if (httpHandler is UrlAuthFailureHandler) {
if (FormsAuthenticationModule.FormsAuthRequired) {
UrlAuthorizationModule.ReportUrlAuthorizationFailure(HttpContext.Current, this);
return;
}
else {
throw new HttpException(, SR.GetString(SR.Assess_Denied_Description3));
}
} // Remap IIS7 to our handler
context.RemapHandler(httpHandler);//将MVCHandler存入HttpContext对象
}
RouteData routeData = RouteCollection.GetRouteData(context)
RouteCollection
public RouteData GetRouteData(HttpContextBase httpContext) {
if (httpContext == null) {
throw new ArgumentNullException("httpContext");
}
if (httpContext.Request == null) {
throw new ArgumentException(SR.GetString(SR.RouteTable_ContextMissingRequest), "httpContext");
} // Optimize performance when the route collection is empty. The main improvement is that we avoid taking
// a read lock when the collection is empty. Without this check, the UrlRoutingModule causes a 25%-50%
// regression in HelloWorld RPS due to lock contention. The UrlRoutingModule is now in the root web.config,
// so we need to ensure the module is performant, especially when you are not using routing.
// This check does introduce a slight if (Count == ) {
return null;
} bool isRouteToExistingFile = false;
bool doneRouteCheck = false; // We only want to do the route check once
if (!RouteExistingFiles) {
isRouteToExistingFile = IsRouteToExistingFile(httpContext);
doneRouteCheck = true;
if (isRouteToExistingFile) {
// If we're not routing existing files and the file exists, we stop processing routes
return null;
}
} // Go through all the configured routes and find the first one that returns a match
using (GetReadLock()) {
foreach (RouteBase route in this) {
RouteData routeData = route.GetRouteData(httpContext);
if (routeData != null) {
// If we're not routing existing files on this route and the file exists, we also stop processing routes
if (!route.RouteExistingFiles) {
if (!doneRouteCheck) {
isRouteToExistingFile = IsRouteToExistingFile(httpContext);
doneRouteCheck = true;
}
if (isRouteToExistingFile) {
return null;
}
}
return routeData;
}
}
} return null;
}
RouteData routeData = route.GetRouteData(httpContext);
Route
public override RouteData GetRouteData(HttpContextBase httpContext) {
// Parse incoming URL (we trim off the first two chars since they're always "~/")
string requestPath = httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring() + httpContext.Request.PathInfo; RouteValueDictionary values = _parsedRoute.Match(requestPath, Defaults); if (values == null) {
// If we got back a null value set, that means the URL did not match
return null;
} RouteData routeData = new RouteData(this, RouteHandler); // Validate the values
if (!ProcessConstraints(httpContext, values, RouteDirection.IncomingRequest)) {
return null;
} // Copy the matched values
foreach (var value in values) {
routeData.Values.Add(value.Key, value.Value);
} // Copy the DataTokens from the Route to the RouteData
if (DataTokens != null) {
foreach (var prop in DataTokens) {
routeData.DataTokens[prop.Key] = prop.Value;
}
} return routeData;
}
Controller
protected override void ExecuteCore()
{
this.PossiblyLoadTempData();
try
{
string requiredString = this.RouteData.GetRequiredString("action");
if (this.ActionInvoker.InvokeAction(this.ControllerContext, requiredString))
return;
this.HandleUnknownAction(requiredString);
}
finally
{
this.PossiblySaveTempData();
}
}
ControllerActionInvoker
/// <summary>
/// 使用指定的控制器上下文来调用指定操作。
/// </summary>
///
/// <returns>
/// 执行操作的结果。
/// </returns>
/// <param name="controllerContext">控制器上下文。</param><param name="actionName">要调用的操作的名称。</param><exception cref="T:System.ArgumentNullException"><paramref name="controllerContext"/> 参数为 null。</exception><exception cref="T:System.ArgumentException"><paramref name="actionName"/> 参数为 null 或为空。</exception><exception cref="T:System.Threading.ThreadAbortException">线程在此操作的调用期间已中止。</exception><exception cref="T:System.Exception">在此操作的调用期间出现未指定的错误。</exception>
public virtual bool InvokeAction(ControllerContext controllerContext, string actionName)
{
if (controllerContext == null)
throw new ArgumentNullException("controllerContext");
if (string.IsNullOrEmpty(actionName))
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "actionName");
ControllerDescriptor controllerDescriptor = this.GetControllerDescriptor(controllerContext);
ActionDescriptor action = this.FindAction(controllerContext, controllerDescriptor, actionName);
if (action == null)
return false;
FilterInfo filters = this.GetFilters(controllerContext, action);
try
{
AuthorizationContext authorizationContext = this.InvokeAuthorizationFilters(controllerContext, filters.AuthorizationFilters, action);
if (authorizationContext.Result != null)
{
this.InvokeActionResult(controllerContext, authorizationContext.Result);
}
else
{
if (controllerContext.Controller.ValidateRequest)
ControllerActionInvoker.ValidateRequest(controllerContext);
IDictionary<string, object> parameterValues = this.GetParameterValues(controllerContext, action);
ActionExecutedContext actionExecutedContext = this.InvokeActionMethodWithFilters(controllerContext, filters.ActionFilters, action, parameterValues);
this.InvokeActionResultWithFilters(controllerContext, filters.ResultFilters, actionExecutedContext.Result);
}
}
catch (ThreadAbortException ex)
{
throw;
}
catch (Exception ex)
{
ExceptionContext exceptionContext = this.InvokeExceptionFilters(controllerContext, filters.ExceptionFilters, ex);
if (!exceptionContext.ExceptionHandled)
throw;
else
this.InvokeActionResult(controllerContext, exceptionContext.Result);
}
return true;
}
/// <summary>
/// 创建一个实现 IHttpHandler 接口的对象并向该对象传递请求上下文。
/// </summary>
public class MvcRouteHandler : IRouteHandler
{
private IControllerFactory _controllerFactory; /// <summary>
/// 初始化 <see cref="T:System.Web.Mvc.MvcRouteHandler"/> 类的新实例。
/// </summary>
public MvcRouteHandler()
{
} /// <summary>
/// 使用指定的工厂控制器对象初始化 <see cref="T:System.Web.Mvc.MvcRouteHandler"/> 类的新实例。
/// </summary>
/// <param name="controllerFactory">控制器工厂。</param>
public MvcRouteHandler(IControllerFactory controllerFactory)
{
this._controllerFactory = controllerFactory;
} /// <summary>
/// 使用指定的 HTTP 上下文返回 HTTP 处理程序。
/// </summary>
///
/// <returns>
/// HTTP 处理程序。
/// </returns>
/// <param name="requestContext">请求上下文。</param>
protected virtual IHttpHandler GetHttpHandler(RequestContext requestContext)
{
requestContext.HttpContext.SetSessionStateBehavior(this.GetSessionStateBehavior(requestContext));
return (IHttpHandler) new MvcHandler(requestContext);
}
MVC ASP.net流程 源代码分析的更多相关文章
- Flink on Yarn模式启动流程源代码分析
此文已由作者岳猛授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. Flink on yarn的启动流程可以参见前面的文章 Flink on Yarn启动流程,下面主要是从源码角 ...
- ASP.NET MVC 4源代码分析之怎样定位控制器
利用少有的空余时间.具体的浏览了下ASP.NET MVC 4的源代码.照着之前的步伐继续前进(尽管博客园已经存在非常多大牛对MVC源代码分析的博客,可是从个人出发.还是希望自己可以摸索出这些). 首先 ...
- asp.net MVC 的处理流程
之前把笔记都放在空间日志中隐藏起来,今天看到这句话:作为经常从网上索取免费资料的一员,要有回报的思想,也为了让更多的人少走些弯路,想想自己不能这么自私,所以把空间日志搬到博客园来.闲话不说,直接开始. ...
- Monkey源代码分析之执行流程
在<MonkeyRunner源代码分析之与Android设备通讯方式>中.我们谈及到MonkeyRunner控制目标android设备有多种方法.当中之中的一个就是在目标机器启动一个mon ...
- Spark SQL源代码分析之核心流程
/** Spark SQL源代码分析系列文章*/ 自从去年Spark Submit 2013 Michael Armbrust分享了他的Catalyst,到至今1年多了,Spark SQL的贡献者从几 ...
- HBase源代码分析之HRegion上MemStore的flsuh流程(一)
了解HBase架构的用户应该知道,HBase是一种基于LSM模型的分布式数据库.LSM的全称是Log-Structured Merge-Trees.即日志-结构化合并-树. 相比于Oracle普通索引 ...
- openVswitch(OVS)源代码分析之工作流程(数据包处理)
上篇分析到数据包的收发,这篇开始着手分析数据包的处理问题.在openVswitch中数据包的处理是其核心技术,该技术分为三部分来实现:第一.根据skb数据包提取相关信息封装成key值:第二.根据提取到 ...
- HBase源代码分析之HRegionServer上MemStore的flush处理流程(一)
在<HBase源代码分析之HRegion上MemStore的flsuh流程(一)>.<HBase源代码分析之HRegion上MemStore的flsuh流程(二)>等文中.我们 ...
- HBase源代码分析之HRegionServer上MemStore的flush处理流程(二)
继上篇文章<HBase源代码分析之HRegionServer上MemStore的flush处理流程(一)>遗留的问题之后,本文我们接着研究HRegionServer上MemStore的fl ...
随机推荐
- Makeflow 4.0 发布,工作流引擎
Makeflow 4.0 发布了,主要改进包括: 1. 支持分层次的 workers,带 master-foremen-workers 范式. 2. 一个 worker 可同时处理超过 1 个的任务3 ...
- linux下卸载mysql
卸载mysql rpm -qa|grep -i mysql rpm -ev MySQL-server-4.0.14-0 MySQL-client-4.0.14-0 卸载后/var/lib/mysql中 ...
- Dynamic CRM 2013学习笔记(三十九)流程2 - 业务流程(Business Process Flows)用法详解
业务流程(Business Process Flows)是CRM 2013 里一个新的流程,它提供了可视化的流程表现.业务人员创建有效.流线型的业务流程让最终用户知道当前在哪.下一步要做什么,用户可以 ...
- .Net免费公开课视频+资料+源码+经典牛逼 汇总篇【持续更新】
博主推荐一:WP8.1最经典培训教程 博主点评:经典Windows Phone8.1 Runtime API培训最经典教程,此教程由传智播客蒋坤老师录制的一整套WP8.1入门级视频教程,讲授内容非常广 ...
- HTTP权威指南阅读笔记五:Web服务器
Web服务器会做些什么: 1.建产连接:接受一个客户端连接,或者如果不希望与这个客户端建立连接,就将其关闭. 1)处理新连接 2)客户端主机名识别 3)通过ident确定客户端用户 ident在组织内 ...
- Linux下jvm、tomcat、mysql、log4j优化配置笔记
小菜一直对操作系统心存畏惧,以前也很少接触,这次创业购买了Linux云主机,由于木有人帮忙,只能自己动手优化服务器了.... 小菜的云主机配置大致为:centeos6(32位),4核心cpu,4G内存 ...
- ActiveMQ第一弹:安装与运行
ActiveMQ使用java写的,所以天然跨平台,windows,各种类Unix系统都可运行,只需要下载对应的分发包即可.当前AciveMQ的最新版本是5.9.0.我目前在自己机子上安装的版本是5.8 ...
- .NET Framework各版本汇总以及之间的关系
目录(?)[-] 原文链接:http://blog.csdn.net/kingmax54212008/article/details/25886345 NET Framework 版本关系 获取NET ...
- Memcached常规应用与分布式部署方案
1.Memcached常规应用 $mc = new Memcache(); $mc->conncet('127.0.0.1', 11211); $sql = sprintf("SELE ...
- [推荐]T- SQL性能优化详解
[推荐]T- SQL性能优化详解 博客园上一篇好文,T-sql性能优化的 http://www.cnblogs.com/Shaina/archive/2012/04/22/2464576.html