路由

  • 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;

        }
原文地址:https://www.cnblogs.com/zhangliming/p/4564680.html