A path segment that contains more than one section, such as a literal section or a parameter, cannot...

出错的原因是 “*/{*catchall}”有两个星号,但是为了追寻.net抛出异常的路径下面对其进行源码分析。

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            routes.MapRoute(
                "myRoute",
                "{controller}/{aciton}/{id}/*{*catchall}",
                new { controller = "Home", action = "index", id = UrlParameter.Optional },
                new { controller="^H.*",action="Index|Action",httpMethod=new HttpMethodConstraint("GET","POST"),customConstraint=new UserAgentConstraint("IE")}
                );

堆栈信息如下:

System.Web.Routing.RouteParser.Parse(String routeUrl) +2346369

System.Web.Routing.Route..ctor(String url, IRouteHandler routeHandler) +12

System.Web.Mvc.RouteCollectionExtensions.IgnoreRoute(RouteCollection routes, String url, Object constraints) +59

System.Web.Mvc.RouteCollectionExtensions.IgnoreRoute(RouteCollection routes, String url) +6 MVCRouting.MvcApplication.RegisterRoutes(RouteCollection routes) in E:\MVCRouting\MVCRouting\Global.asax.cs:35

MVCRouting.MvcApplication.Application_Start() in E:\MVCRouting\MVCRouting\Global.asax.cs:55

错误在Parse时抛出异常:

RouteParser.Parse(string routeUrl)源码如下:

 
public static ParsedRoute Parse(string routeUrl)
{
    if (routeUrl == null)
    {
        routeUrl = string.Empty;
    }
    if ((routeUrl.StartsWith("~", StringComparison.Ordinal) || routeUrl.StartsWith("/", StringComparison.Ordinal)) || (routeUrl.IndexOf('?') != -1))
    {
        throw new ArgumentException(SR.GetString("Route_InvalidRouteUrl"), "routeUrl");
    }
    IList<string> pathSegments = SplitUrlToPathSegmentStrings(routeUrl);
   
    if (exception != null)
    {
        throw exception;
    }
    return new ParsedRoute(SplitUrlToPathSegments(pathSegments));
}
 
 

根据源码分析可知:以~或者是/,或者包含有?的都会被过滤掉,并抛出一下异常:

Route_InvalidRouteUrl=The route URL cannot start with a '/' or '~' character and it cannot contain a '?' character.

SplitUrlToPathSegmentStrings将URL转换为List<string> 的形式,异常不会在此抛出。所以分析ValidateUrlParts。

分析 ValidateUrlParts源代码:

 private static Exception ValidateUrlParts(IList<string> pathSegments)
    {
      HashSet<string> usedParameterNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
      bool? nullable = null;
      bool flag = false;
      foreach (string str in pathSegments)//在foreach循环里面进行真正的有效性验证
      {
        bool flag2;
        if (flag)
        {
          return new ArgumentException(string.Format(CultureInfo.CurrentUICulture, System.Web.SR.GetString("Route_CatchAllMustBeLast"), new object[0]), "routeUrl");
        }
        if (!nullable.HasValue)
        {
          nullable = new bool?(IsSeparator(str));
          flag2 = nullable.Value;
        }
        else
        {
          flag2 = IsSeparator(str);//判断是否为“/”
          if (flag2 && nullable.Value)
          {
            return new ArgumentException(System.Web.SR.GetString("Route_CannotHaveConsecutiveSeparators"), "routeUrl");
          }
          nullable = new bool?(flag2);
        }
        if (!flag2)
        {
          Exception exception;
          IList<PathSubsegment> pathSubsegments = ParseUrlSegment(str, out exception);
/*
PathSubSegment:有一个空的抽象类
*/
          if (exception != null)
          {
            return exception;
          }
          exception = ValidateUrlSegment(pathSubsegments, usedParameterNames, str);
          if (exception != null)
          {
            return exception;
          }
          flag = Enumerable.Any<PathSubsegment>(pathSubsegments, delegate (PathSubsegment seg) {
            return (seg is ParameterSubsegment) && ((ParameterSubsegment) seg).IsCatchAll;
          });
        }
      }
      return null;
    }

异常应该在ValidateURlSegment里面抛出,所以分析 其源码如下:

private static Exception ValidateUrlSegment(IList<PathSubsegment> pathSubsegments, HashSet<string> usedParameterNames, string pathSegment)
    {
      bool flag = false;
      Type type = null;

//循环遍历pathSubsegments,关于PathSubsegment,ContentPathSegment……,详细信息看以下链接http://www.cnblogs.com/Wind-Eagle/archive/2008/12/05/1348645.html
      foreach (PathSubsegment subsegment in pathSubsegments)
      {
        if ((type != null) && (type == subsegment.GetType()))//
        {
          return new ArgumentException(string.Format(CultureInfo.CurrentUICulture, System.Web.SR.GetString("Route_CannotHaveConsecutiveParameters"), new object[0]), "routeUrl");
        }
        type = subsegment.GetType();
        if (!(subsegment is LiteralSubsegment))
        {
          ParameterSubsegment subsegment3 = subsegment as ParameterSubsegment;
          if (subsegment3 != null)
          {
            string parameterName = subsegment3.ParameterName;
            if (subsegment3.IsCatchAll)
            {
              flag = true;
            }
            if (!IsValidParameterName(parameterName))
            {
              return new ArgumentException(string.Format(CultureInfo.CurrentUICulture, System.Web.SR.GetString("Route_InvalidParameterName"), new object[] { parameterName }), "routeUrl");
            }
            if (usedParameterNames.Contains(parameterName))
            {
              return new ArgumentException(string.Format(CultureInfo.CurrentUICulture, System.Web.SR.GetString("Route_RepeatedParameter"), new object[] { parameterName }), "routeUrl");
            }
            usedParameterNames.Add(parameterName);
          }
        }
      }
      if (flag && (pathSubsegments.Count != 1))//在什么情况下此条件为TRUE呢?

//例如:/*{*catchall},第一个*为一个LiteralSubsegment,而后面紧接着就是一个catchall(判断并不是以catchall文字为标准,而是开头是否为*)占位符.
      {

//这里便是抛出异常的代码行!!!
       return new ArgumentException(string.Format(CultureInfo.CurrentUICulture, System.Web.SR.GetString("Route_CannotHaveCatchAllInMultiSegment"), new object[0]), "routeUrl");
      }
      return null;
    }

最终找到抛出异常的代码行

转载于:https://www.cnblogs.com/symphony2010/archive/2011/11/18/2254299.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值