路由
- Convert.ChangeType(form[key], modelType)类型转换
- Activator.CreateInstance(modelType)根据反射的类型创建实例
- 路由系统是ASPNet的,不是MVC特有的,URL 路由系统并不是专属于ASP.NETMVC 的,而是直接建立在ASP.NET 上.
- 调用RouteCollection 的MapPageRoute方法在全局路由表中添加的就是这么一个Route对象
可以通过调用它的MapPageRoute 进行路由映射,即注册URL 模板与某个物理文件的匹配关系
/{filename}.{extension}/{pathinfo}
ContentPathSegment
PathSubsegment {} /{}{}/
PathSegment /…/
SeparatorPathSegment "/"
private static IList<PathSegment> SplitUrlToPathSegments(IList<string> urlParts)
{
List<PathSegment> list = new List<PathSegment>();
foreach (string str in urlParts) {
if (IsSeparator(str)) {
list.Add(new SeparatorPathSegment());
} else {
Exception exception;
IList<PathSubsegment> subsegments = ParseUrlSegment(str, out exception);
list.Add(new ContentPathSegment(subsegments));
}
}
return list;
}
- 通过地址解析出来的变量被保存在Values 属性中,而在进行路由注册过程为Route 对象的DataTokens 属性指定的变量被转移到了RouteData 的同名属性中。
- constraint的正则检查
protected virtual bool ProcessConstraint(HttpContextBase httpContext, object constraint, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
object obj2;
IRouteConstraint constraint2 = constraint as IRouteConstraint;
if (constraint2 != null) {
return constraint2.Match(httpContext, this, parameterName, values, routeDirection);
}
string str = constraint as string;
if (str == null) {
throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, System.Web.SR.GetString("Route_ValidationMustBeStringOrCustomConstraint"), new object[] { parameterName, this.Url }));
}
values.TryGetValue(parameterName, out obj2);
string input = Convert.ToString(obj2, CultureInfo.InvariantCulture);
string pattern = "^(" + str + ")$";
return Regex.IsMatch(input, pattern, RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
}
- HttpMethodConstraint
可以通过HttpMethodConstraint 为路由对象设置一个允许的HTTP 方法列表,只有在这个指定的列表中的HTTP 方法名称的HTTP 请求才允许被路由
RouteExistinqFiles是否路由物理文件.路由表和每个路由中都有这个属性设置.
public RouteData GetRouteData(HttpContextBase httpContext)
{
if (httpContext == null) {
throw new ArgumentNullException("httpContext");
}
if (httpContext.Request == null) {
throw new ArgumentException(System.Web.SR.GetString("RouteTable_ContextMissingRequest"), "httpContext");
}
if (base.Count != 0) {
bool flag = false;
bool flag2 = false;
if (!this.RouteExistingFiles) {
flag = this.IsRouteToExistingFile(httpContext);
flag2 = true;
if (flag) {
return null;
}
}
using (this.GetReadLock()) {
foreach (RouteBase base2 in this) {
RouteData routeData = base2.GetRouteData(httpContext);
if (routeData != null) {
if (!base2.RouteExistingFiles) {
if (!flag2) {
flag = this.IsRouteToExistingFile(httpContext);
flag2 = true;
}
if (flag) {
return null;
}
}
return routeData;
}
}
}
}
return null;
}
- 在验证对本地文件的路由规则时,发下在本机的IIS下调试,和在VS的IIS下调试效果不一样.在系统 的IIS下,对物理文件的访问不会通过路由,即使设置RouteExistinqFiles为TRUE.
- ASP.NET MVC基于某个物理文件的路由注册通过调用RouteTable 的静态属性Routes (一个代表全局路由表的RouteCollection 对象〉的MapPageRoute 方法来完成。为了实现针对目标Con位ol1er 和Action 的路由, ASP.NET MVC 针对RouteCollection 类型定义了一系列的扩展方法以实现文件路径无关的路由映射,这些扩展方法定义在System.Web.Mvc.RouteCollectio nExtensions 类型中。
- RouteCollectionExtensions 定义了两组方法,方法IgnoreRoute用于注册不需要进行路由的URL 模板,对应于RouteCollectionExtensions 的Ignore 方法:方法MapRoute 用于进行基于URL 模板的路由注册,对应于RouteCollectionE xtensions 的MapPageRoute 方法。
- 若果没有在路由模板中定义controlller和action的变量,可以在default中定义同名的默认值.因为会从这个default中查找这两个字段值的.default中的值会放到routedata的values中.如果路径包含同名的值,会覆盖掉,就是默认值被覆盖
- UrlParameter. Optional定义的URL参数,只有在实际的URL中包含这个参数时,RouteData的Value中才会包含这个变量.如果没有传递这个参数,那么Value中不会包含这个变量.而使用默认值的方式,肯定包含这个变量.
- BuildManager GetReferencedAssemblies 方法得到的程序集列表
- Predicate<Type> 表示定义一组条件并确定指定对象是否符合这些条件的方法。用于在集合中搜索元素
- Type.EmptyTypes 表示 Type 类型的空数组
- type.GetConstructor(Type.EmptyTypes)
- IsAssignableFrom 确定当前的 Type 的实例是否可以从指定 Type 的实例分配
- HtmlHelper.UrlHelper 实现的对URL 的生成最终还是依赖于前面所说的GetVrrtualPathData 方法。
- URLHelper.Action方法生成的是一个URL,不包含<a>标签,HTMLHelper.ActionLink生成的是一个包含<a>的链接
- Aspnet中Page页面就是httpHandle
- 当针对某个具体AreaRegistration的AreaRegistrationContext 被创建的时候,如果AreaRegistration 类型具有命名空间,在这个命名空间基础上添加" *"后缀生成的字符串会被添加到Namespaces 集合中。换言之,对于多个定义在不同命名空间中的同名Control1 er 类型,会优先选择包含在当前AreaRegistration命名空间下的Controller。
如果调用AreaRegistrationContext 的MapRoute 方法是显式指定了命名空间,或者说对应的AreaRegisration 定义在某个命名空间下,这个名称为"UseNamespaceFallback" 的DataToken 元素的值为False ,反之为True 。进一步来说,如果在调用MapRoute 方法时指定了命名空间列表,那么, AreaRegistration 类型所示在的命名空间会被忽略,也就是说,后者是前者的一个后备,前者具有更高的优先级。AreaRegistration 类型所示在命名空间也不是直接作为最终RouteData 的DataTokens 中的命名空间,而是在此基础上加上" *"后缀。
- AreaRegistrationContext
public Route MapRoute(string name, string url, object defaults, object constraints, string[] namespaces) { if (namespaces == null && Namespaces != null) { namespaces = Namespaces.ToArray(); } Route route = Routes.MapRoute(name, url, defaults, constraints, namespaces); route.DataTokens["area"] = AreaName; // disabling the namespace lookup fallback mechanism keeps this areas from accidentally picking up // controllers belonging to other areas bool useNamespaceFallback = (namespaces == null || namespaces.Length == 0); route.DataTokens["UseNamespaceFallback"] = useNamespaceFallback; return route; }