MVC source code analysis, mvc source code

Source: Internet
Author: User

MVC source code analysis, mvc source code

The previous chapter parses the search of the Action method and the loading time of the Authorize, Action, Result, and Error filters. I also spent two articles on the use of authorization and error filters. however, the execution time of the Action/Result and the two filters in the Action/Result are not clearly displayed.

1. Action Method execution and filter execution

// System. Web. Mvc. ControllerActionInvokerprotected virtual ActionExecutedContext InvokeActionMethodWithFilters (ControllerContext controllerContext,
IList <IActionFilter> filters, ActionDescriptor actionDescriptor, IDictionary <string, object> parameters) {ActionExecutingContext preContext = new ActionExecutingContext (controllerContext, actionDescriptor, parameters); // a Func delegate is defined here, the returned value is of the ActionExecutedContext type.
// In the returned ActionExecutedContext type instance, the execution method is specified for the Result.
// Actually, the method to be executed is specified here. After it is executed, no method is executed. The following highlighted part is the execution of the Action method.
Func <ActionExecutedContext> seed = () => new ActionExecutedContext (controllerContext, actionDescriptor, false, null)
{Result = this. InvokeActionMethod (controllerContext, actionDescriptor, parameters)}; return filters
// The filters variable is a List <IActionFilter> set of elements headed by the controller. The purpose here is to reverse the set and change it
// IActionFilter-> Controller
. Reverse <IActionFilter> ()
// Aggregate function. next is actually the seed object.
// Filter is an element in IEnumberable <IActionFilter>.
// The effect here is to return the accumulated seed object
. Aggregate <IActionFilter, Func <ActionExecutedContext> (seed,
(Next, filter) => () => InvokeActionMethodFilter (filter, preContext, next ))
(); // Execution method for this step}

The code here is the previous3.4,It's just that I have separated him, so it's easy to understand.

Here is an Aggregate <> (), which may not be so easy to understand. The previous demo should be able to promote understanding.

Var numbers = new int [] {1, 3, 9, 2}; // use the current total value multiplied by the next value to obtain the new total value var product = numbers. aggregate (total, next) => total * next); the final value is: 1X3X9X2 = 54.

The execution process here is as follows:

1 ). when Aggregate () is executed for the first time, the next in the anonymous method (next, filter) is the seed object, and the filter is the ActionFilter object. invokeActionMethodFilter (filter, preContext, next) is used as the return value and as the next parameter in the next execution (filter ).

2) during the second execution (next, filter), the value of the next parameter is InvokeActionMethodFilter (filter, preContext, next), and the filter is Controller.

InvokeActionMethodFilter (filter, preContext, next) returns the most results to the filters variable.

The overall execution expression is: filters = InvokeActionMethodFilter (controller, preContext, InvokeActionMethodFilter (ActionFilter, preContext, seed ));

After the above steps, filters forms a linked list, and the first operation is Controller.

 

1.InvokeActionMethodFilter

Internal static ActionExecutedContext InvokeActionMethodFilter (IActionFilter filter,
ActionExecutingContext preContext, Func <ActionExecutedContext> continuation ){
// This step executes the ActionExecuting filter. OnActionExecuting (preContext); if (preContext. Result! = Null ){
// When the filter fails, return new ActionExecutedContext (preContext, preContext. ActionDescriptor, true, null)
{Result = preContext. Result};} bool flag = false; ActionExecutedContext filterContext = null; try {
// 1. The first execution of this step will jump to InvokeActionFilter (filter, preContext, next) to execute
// 2. The above seed method will be executed when the second operation arrives here
// When the seed method is executed, run the InvokeActionMethod () method filterContext = continuation ();} catch (ThreadAbortException) {filterContext = new ActionExecutedContext (preContext, preContext. actionDescriptor, false, null); filter. onActionExecuted (filterContext); throw;} catch (Exception exception) {flag = true; filterContext = new ActionExecutedContext (preContext, preContext. actionDescriptor, false, exception ); Filter. OnActionExecuted (filterContext); if (! FilterContext. ExceptionHandled) {throw ;}} if (! Flag) {filter. OnActionExecuted (filterContext);} return filterContext ;}

Here, we can see the execution time of the ActionExecuting and ActionExecuted filters.

Based on the above comments, let's take a look at the InvokeActionMethod method.

protected virtual ActionResult InvokeActionMethod(ControllerContext controllerContext,
     ActionDescriptor actionDescriptor, IDictionary<string, object> parameters){ object actionReturnValue = actionDescriptor.Execute(controllerContext, parameters); return this.CreateActionResult(controllerContext, actionDescriptor, actionReturnValue);}

Here, the Execute method returns the ActionResult. Calling CreateActionResult is to convert the returned actionReturnValue to the ActionResult type.

This is actually the Action method to be executed and the execution result is returned.

 

Ii. Result execution and filter execution

//ControllerActionInvokerprotected virtual ResultExecutedContext InvokeActionResultWithFilters(ControllerContext controllerContext,
   IList<IResultFilter> filters, ActionResult actionResult){ ResultExecutingContext preContext = new ResultExecutingContext(controllerContext, actionResult); Func<ResultExecutedContext> seed = delegate { this.InvokeActionResult(controllerContext, actionResult); return new ResultExecutedContext(controllerContext, actionResult, false, null); }; return filters
      .Reverse<IResultFilter>()
      .Aggregate<IResultFilter, Func<ResultExecutedContext>>(seed,
        (next, filter) => () => InvokeActionResultFilter(filter, preContext, next))
      ();}

The structure of the method here is similar to that of the above Action, and the returned value is ResultExecutedContext.

Let's take a look at the InvokeActionResultFilter method.

1. InvokeActionResultFilter

internal static ResultExecutedContext InvokeActionResultFilter(IResultFilter filter,
   ResultExecutingContext preContext, Func<ResultExecutedContext> continuation){ filter.OnResultExecuting(preContext); if (preContext.Cancel) { return new ResultExecutedContext(preContext, preContext.Result, true, null); } bool flag = false; ResultExecutedContext filterContext = null; try { filterContext = continuation(); } catch (ThreadAbortException) { filterContext = new ResultExecutedContext(preContext, preContext.Result, false, null); filter.OnResultExecuted(filterContext); throw; } catch (Exception exception) { flag = true; filterContext = new ResultExecutedContext(preContext, preContext.Result, false, exception); filter.OnResultExecuted(filterContext); if (!filterContext.ExceptionHandled) { throw; } } if (!flag) { filter.OnResultExecuted(filterContext); } return filterContext;}

The execution sequence of internal methods is the same. from this method, we can see that the execution sequence of the Result filter is indeed as mentioned above. executing is Executed first, Result is Executed, and Executed method is Executed finally.

 

2. InvokeActionResult

protected virtual void InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult){    actionResult.ExecuteResult(controllerContext);}

This step is to execute the View. If the specific execution process has a chance, it will be parsed later.

This article mainly verifies whether the execution sequence of the four filters of Action/Result is as described above. of course, the execution time of the Action/Result method is also seen in the process of searching.

There is actually another problem here. From the above perspective, the Controller is sorted to the beginning and executed. What if I registered it in FilterConfig? What are marked on the Action method? What are the labels on the Controller class? What is the order?

Let's take a look at the next article. The order here can also help you understand the content of this article.

Refer:

In-depth analysis of Asp.net Mvc

Directory synchronized

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.