C# 在ASP.NET WebApi中,为什么RouteData';“s值类型”;“对象”;而不是",;“字符串”;

C# 在ASP.NET WebApi中,为什么RouteData';“s值类型”;“对象”;而不是",;“字符串”;,c#,asp.net,asp.net-web-api,routing,C#,Asp.net,Asp.net Web Api,Routing,在WebApi中,RouteData有一个Values属性,该属性存储路由数据。然而,出于某种原因,它实现了IDictionary,而不是IDictionary。值类型永远不会是字符串吗 上下文是我正在编写一个自定义的IHttpRouteConstraint,以检查整数是否在指定范围内。为此,我必须将值强制转换为string,然后使用int.TryParse。但如果该值实际上是int,则此操作将失败。这会发生吗?如果您看到,您会注意到单元测试中的值不是字符串(例如) 您说您正在编写一个自定义约束

在WebApi中,
RouteData
有一个
Values
属性,该属性存储路由数据。然而,出于某种原因,它实现了
IDictionary
,而不是
IDictionary
。值类型永远不会是字符串吗

上下文是我正在编写一个自定义的
IHttpRouteConstraint
,以检查整数是否在指定范围内。为此,我必须将值强制转换为
string
,然后使用
int.TryParse
。但如果该值实际上是
int
,则此操作将失败。这会发生吗?

如果您看到,您会注意到单元测试中的值不是字符串(例如)

您说您正在编写一个自定义约束,让我们以这个约束为例:

 public class MyConstraint : IHttpRouteConstraint
 {
       public bool Match(HttpRequestMessage request, IHttpRoute route, string parameterName, IDictionary<string, object> values, HttpRouteDirection routeDirection)
       {
            string parameters = string.Join(Environment.NewLine, values.Select(p => p.Value.GetType().FullName).ToArray());
            return true;
       }
  } 
假设您有此控制器:

public class ValuesController : ApiController
{
    public string Get(int id) { return "Value"; }
}
如果向“/api/values/GET/1”发出GET请求,您会注意到这些值的类型是

  • System.String//值
  • System.String//Get
  • System.String//1
但是

如果向“/api/values/1”发出GET请求,您会注意到这些值的类型是

  • System.String//值
  • System.String//1
  • System.Web.Http.RouteParameter
如果你看到

//
///该类可用于指示有关管线参数(文字和占位符)的属性
///位于一个区域的段内)。
///例如,它可用于指示路由参数是可选的。
/// 
公共密封类路由参数
{
public static readonly RouteParameter Optional=新建RouteParameter();
//单例构造函数
专用路由参数(){}
公共重写字符串ToString(){return string.Empty;}
}
因此,当您不提供可选参数时,这不是字符串。

您应该首先检查对象的类型,只有当它是非空字符串时,才尝试解析它

您的路由参数在目标控制器操作中是否为整数?在这种情况下,否。该参数需要与约束匹配,并被丢弃。如果它是控制器目标中的一个整数,我认为这不会影响它,因为模型绑定发生得晚,否?模型绑定发生得晚=>是<代码>但如果该值实际上是int,则此操作将失败。这不应该发生。但为什么它永远不会发生?这就是让我困惑的地方。
public class ValuesController : ApiController
{
    public string Get(int id) { return "Value"; }
}
/// <summary>
/// The <see cref="RouteParameter"/> class can be used to indicate properties about a route parameter (the literals and placeholders 
/// located within segments of a <see cref="M:IHttpRoute.RouteTemplate"/>). 
/// It can for example be used to indicate that a route parameter is optional.
/// </summary>
public sealed class RouteParameter
{
    public static readonly RouteParameter Optional = new RouteParameter();

    // singleton constructor
    private RouteParameter()        {   }

    public override string ToString()   {  return string.Empty;      }
}