300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 004. Asp.Net Routing与MVC 之二: 请求如何激活Controller和Action

004. Asp.Net Routing与MVC 之二: 请求如何激活Controller和Action

时间:2022-11-27 01:40:20

相关推荐

004. Asp.Net Routing与MVC 之二: 请求如何激活Controller和Action

上篇讲到 请求到达 MvcRouteHandler ,并且透过 IRouteHandler.GetHttpHandler 获取到了真正的处理程序 MvcHandler

这次我们看看,MvcHandler是如何依据请求,来激活对应的controller和Action来处理请求的。

一、先看看MvcHandler 的核心内容

1: public class MvcHandler : IHttpAsyncHandler, IHttpHandler, IRequiresSessionState

2: {

3:protected virtual void ProcessRequest(HttpContext httpContext)

4:{

5: //使用HttpContextWrapper对HttpContext进行封装,封装的目的是为了解耦以获得可测试性.然后从RequestContext.RouteData中提取Controller名称.

6: HttpContextBase httpContext2 = new HttpContextWrapper(httpContext);

7: this.ProcessRequest(httpContext2);

8:}

9:

10:protected internal virtual void ProcessRequest(HttpContextBase httpContext)

11:{

12: IController controller;

13: IControllerFactory controllerFactory;

14: this.ProcessRequestInit(httpContext, out controller, out controllerFactory);//获取到Controler和ControllerFactory实例,并赋值给局部变量

15: try

16: {

17: //Action的调用,下一篇介绍

18: //当前Controler对象的Action的创建与执行(执行包括:加载TempData, 创建及执行Action,处理Action返回的ActionResult ,保存TempData数据)

19: controller.Execute(this.RequestContext);

20:

21: }

22: finally

23: {

24: //释放当前Controler对象

25: controllerFactory.ReleaseController(controller);

26: }

27:}

28: }

二、Controller的激活

从上述代码中可以看出,对Controller激活的相关的操作是通过MvcHandler类的 ProcessRequestInit 方法来执行,而执行完成后,将获取到Controller和ControllerFactory实例。

this.ProcessRequestInit(httpContext, out controller, out controllerFactory) ,下面就通过这个方法的内部代码来剖析下Controller的激活的机制

1: private void ProcessRequestInit(HttpContextBase httpContext, out IController controller, out IControllerFactory factory)

2: {

3:

4: // If request validation has already been enabled, make it lazy. This allows attributes like [HttpPost] (which looks

5: // at Request.Form) to work correctly without triggering full validation.

6: // Tolerate null HttpContext for testing.

7: //看不明白

8: HttpContext currentContext = HttpContext.Current;

9: if (currentContext != null)

10: {

11: bool? isRequestValidationEnabled = ValidationUtility.IsValidationEnabled(currentContext);

12: if (isRequestValidationEnabled == true)

13: {

14: ValidationUtility.EnableDynamicValidation(currentContext);

15: }

16: }

17: //为响应添加特定的头标示:MvcVersionHeaderName, MvcVersion

18: AddVersionHeader(httpContext);

19: //从当前请求的路由集合中,移除可选的路由参数

20: RemoveOptionalRoutingParameters();

21:

22: // Get the controller type

23: //从当前请求的路由集合中,检索名为"controller"参数的值

24: string controllerName = RequestContext.RouteData.GetRequiredString("controller");

25:

26: // Instantiate the controller and call Execute

27: //通过 ControllerBuilder 获取 当前的 controllFactory 控制器工厂

28: factory = ControllerBuilder.GetControllerFactory();

29: //通过controllFactory 控制器工厂 ,以及前边获取到的 controllerName,构建一个 controller类型实例。

30: controller = factory.CreateController(RequestContext, controllerName);

31: if (controller == null)

32: {

33: throw new InvalidOperationException(

34: String.Format(

35:CultureInfo.CurrentCulture,

36:MvcResources.ControllerBuilder_FactoryReturnedNull,

37:factory.GetType(),

38:controllerName));

39: }

40: }

41:

由于使用了out关键字,这个方法中的执行过程中所得到的值,即:赋值给ProcessRequest方法中声明的Controller和ControllerFactory

MVCHander –> ProcessRequest()

xxxxxController\ControllerFactory

IController.Excute();

ControllerBase.Excute().ExcuteCore()

Controller.ExecuteCore() { . GetActionName ; IActionInvoker.InvokeAction() }

IActionInvoker.InvokeAction() {

get methodInfo //sys

处理参数 // BindModel

methodInfo.invoke();//sys

}

1.定义Model

2.Model 里注册事件 ,附加 routerHander

3。routerHander 里 返回真正的 hander

4. hander.ProcessRequest( HttpCotent content )

{

get Controller type

get Action(Method) methodinfo

var invokeResult = method.Invoke(controllerContext.Controller, parameters.ToArray())

//as ActionResult;

controllerContext.RequestContext.HttpContext.Response.Write(invokeResult);

}

一、mvc 下 url 的各种玩法

ip/home/index/3

ip/3

二、

// parameters.Add(this.ModelBinder.BindModel(controllerContext, parameter.Name, parameter.ParameterType));

以下是没有搞清楚的内容,如何获取工厂,工厂又如何依据名字,创建一个controller类型实例。

显然,上述的代码中有两行重要代码:

1、factory = this.ControllerBuilder.GetControllerFactory();

this.ControllerBuilder是MvcHandler类的一个属性,属性返回的是MvcHandler类声明的一个 ControllerBuilder类型的字段,属性在返回时会判断当前字段是否为空,如果为空,则调用ControllerBuilder类的静态属性 Current字段,来获取一个ControllerBuilder实例。

接下来再看一下ControllerBuilder类

1: namespace System.Web.Mvc

2: {

3:public class ControllerBuilder

4:{

5: //声明静态字段,执行此类的构造函数

6: private static ControllerBuilder _instance = new ControllerBuilder();

7:

8: private Func<IControllerFactory> _factoryThunk = () => null;

9: private HashSet<string> _namespaces = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

10:

11: //暂且理解为是封装ControllerFactory的一个类,通过该类的Current属性来获取当前封装的ControllerFactory实例

12: private IResolver<IControllerFactory> _serviceResolver;

13:

14: public ControllerBuilder()

15: : this(null) //: this(null)表示执行带一个参数的构造函数,并且传入的参数为Null

16: {

17: }

18:

19: internal ControllerBuilder(IResolver<IControllerFactory> serviceResolver)

20: {

21: //如果传入的参数为null,则实例化一个SingleServiceResolver类并赋值给私有字段_serviceResolver。

22: _serviceResolver = serviceResolver ?? new SingleServiceResolver<IControllerFactory>(

23:() => _factoryThunk(),

24:new DefaultControllerFactory { ControllerBuilder = this },

25:"ControllerBuilder.GetControllerFactory");

26: }

27:

28: public static ControllerBuilder Current

29: {

30: //获取Controller实例

31: get { return _instance; }

32: }

33:

34: public HashSet<string> DefaultNamespaces

35: {

36: get { return _namespaces; }

37: }

38:

39: [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "Calling method multiple times might return different objects.")]

40: public IControllerFactory GetControllerFactory()

41: {

42: //获取ControllerFactory实例

43: return _serviceResolver.Current;

44: }

45:

46: public void SetControllerFactory(IControllerFactory controllerFactory)

47: {

48: if (controllerFactory == null)

49: {

50: throw new ArgumentNullException("controllerFactory");

51: }

52:

53: _factoryThunk = () => controllerFactory;

54: }

55:

56: public void SetControllerFactory(Type controllerFactoryType)

57: {

58: if (controllerFactoryType == null)

59: {

60: throw new ArgumentNullException("controllerFactoryType");

61: }

62: if (!typeof(IControllerFactory).IsAssignableFrom(controllerFactoryType))

63: {

64: throw new ArgumentException(

65: String.Format(

66:CultureInfo.CurrentCulture,

67:MvcResources.ControllerBuilder_MissingIControllerFactory,

68:controllerFactoryType),

69: "controllerFactoryType");

70: }

71:

72: _factoryThunk = delegate

73: {

74: try

75: {

76: return (IControllerFactory)Activator.CreateInstance(controllerFactoryType);

77: }

78: catch (Exception ex)

79: {

80: throw new InvalidOperationException(

81:String.Format(

82: CultureInfo.CurrentCulture,

83: MvcResources.ControllerBuilder_ErrorCreatingControllerFactory,

84: controllerFactoryType),

85:ex);

86: }

87: };

88: }

89:}

90: }

2、controller = factory.CreateController(this.RequestContext, controllername);

此行代码,利用上一句得到一个ControllerFactory实例。将 RequestContext 和Controllername作为参数来调用 ControllerFactory类的CreateController方法,以此创建Controller实例并返回。

至此,我们从请求的 路由数据中,得到 controllerName,又用controllerName,通过 ControllerFactory 获取到了真正的 Controller。

????

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。