上次讲到请求如何激活Controller和Action,这次讲下MVC中路由的使用。
本次两个关注点:

  • 遗留:ModelBinder.BindModel的过程
  • MVC中路由的使用
  • MVC 5中的Action新特性

一、ModelBinder.BindModel的过程

MVCHander –>  ProcessRequest()
xxxxxController\ControllerFactory
IController.Excute();
ControllerBase.Excute().ExcuteCore()
Controller.ExecuteCore()  { . GetActionName  ;  IActionInvoker.InvokeAction() }

IActionInvoker.InvokeAction() {

get methodInfo  //sys

处理参数  // BindModel

methodInfo.invoke();//sys

}

在MVC源码中,ControllerActionInvoker.InvokeAction()
我们看看BindModel做了些什么。

   1:  
class DefaultModelBinder : IModelBinder
   3: {
/// <summary>
/// ControllerContext (控制器上下文,包含Controller 类型实例,和 当前请求上下文RequestContext)
/// MVC Model Bind, 从  ControllerContext 中,为当前参数(确定的类型 和 名称)赋值。
/// </summary>
/// <returns></returns>
string modelName, Type modelType)
  13:     {
// 值类型 或 对象值类型(string),即简单点说:值类型
string) == modelType)
  16:         {
object instance;
//获取值类型的 值实例,并返回
out instance))
  20:             {
return instance;
  22:             };
return Activator.CreateInstance(modelType);
  24:         }
  25:  
//不是值类型,即 对象类型
//使用类型默认构造函数,创建一个实例
object modelInstance = Activator.CreateInstance(modelType);
//下边就是一个循环的过程,查找对象的属性,值类型的就赋值,循环属性直至完成
in modelType.GetProperties())
  31:         {
//忽略了 action参数 的对象类型中“对象类型”的属性
string)))
  34:             {
continue;
  36:             }
object propertyValue;
out propertyValue))
  39:             {
null);
  41:             }
  42:         }
return modelInstance;
  44:     }
  45:  
/// <summary>
/// 为值类型 或 对象值类型(string),(即简单点说:值类型)获取值。
///  结构体(数值,bool,自定义结构体struct),枚举enum,可空类型 
/// </summary>
/// <returns></returns>
value)
  56:     {
//HttpPost 提交,使用窗体变量集合  
  58:         var form = HttpContext.Current.Request.Form;
string key;
//form集合不为空
null != form)
  62:         {
//窗体变量集合 AllKeys 里查找 “modelName” 变量。
true) == 0);
null)
  66:             {
//?结构体
//value =  Convert.ChangeType(form[key]., modelType);
  69:                 var curKeyVal = form[key];
value = Convert.ChangeType(curKeyVal, modelType);
true;
  72:             }
  73:         }
//HttpGet 提交,使用路由值中的 QueryString
  75:         key = controllerContext.RequestContext.RouteData.Values
//更快!
//.Where(item => string.Equals(item.Key, modelName,StringComparison.InvariantCultureIgnoreCase))
true) == 0)
//get提交中,只取当前key的第一个匹配项的值
  80:             .Select(item => item.Key).FirstOrDefault();
null != key)
  82:         {
value = Convert.ChangeType(controllerContext.RequestContext.RouteData.Values[key], modelType);
true;
  85:         }
  86:  
//http://msdn.microsoft.com/zh-cn/library/system.web.routing.routedata.datatokens.aspx
//RouteData.DataTokens 属性
//与RouteData.Values类似的键值对方式,允许按key获取值。
//没试出与 RouteData.Values的区别???
  91:         key = controllerContext.RequestContext.RouteData.DataTokens
true) == 0)
  93:             .Select(item => item.Key).FirstOrDefault();
null != key)
  95:         {
value = Convert.ChangeType(controllerContext.RequestContext.RouteData.DataTokens[key], modelType);
true;
  98:         }
null;
false;
 101:     }
 102: }

相关文章: