在 WebAPI ASP.NET 中,为什么 RouteData 的值类型是“对象”而不是“字符串”

本文关键字:字符串 类型 对象 NET ASP WebAPI RouteData 为什么 | 更新日期: 2023-09-27 18:35:11

在WebApi中,RouteData有一个Values属性,它是存储路由数据的位置。但是,出于某种原因,它实现了IDictionary<string, object>而不是IDictionary<string, string>。值类型永远不会是字符串吗?

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

在 WebAPI ASP.NET 中,为什么 RouteData 的值类型是“对象”而不是“字符串”

如果你看到源代码,你会注意到单元测试,其中的值不是字符串(例如BindValuesAsync_RouteData_Values_To_Simple_Types)。

你说你正在编写一个自定义约束,让我们拿这个:

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

您注册它:

 config.Routes.MapHttpRoute("DefaultApi",
                                   "api/{controller}/{action}/{id}",
                                   new { id = RouteParameter.Optional }, 
                                   new { isLocal = new MyConstraint() });

假设您有此控制器:

public class ValuesController : ApiController
{
    public string Get(int id) { return "Value"; }
}

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

  • System.String//values
  • System.String//Get
  • System.String//1

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

  • System.String//values
  • System.String//1
  • System.Web.Http.RouteParameter

如果您看到类的源代码

/// <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;      }
}

因此,这不是字符串的一种情况是当您不提供可选参数时。
你应该首先检查对象的类型,只有当它是一个非空字符串时,才尝试解析它