【问题标题】:In ASP.NET WebApi, why is RouteData's value type "object" and not "string"在 ASP.NET WebApi 中,为什么 RouteData 的值类型是“对象”而不是“字符串”
【发布时间】:2016-05-29 21:42:03
【问题描述】:

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

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

【问题讨论】:

  • 你的路由参数是目标控制器动作中的整数吗?
  • 在这种情况下,没有。该参数需要与约束匹配并被丢弃。如果它是控制器目标中的整数,我认为应该不会影响它,因为模型绑定稍后会发生,不是吗?
  • 模型绑定稍后发生 => 是的。 But this will fail if the value is actually an int => 这绝不应该发生。
  • 但是为什么它永远不会发生呢?这就是让我困惑的地方。

标签: c# asp.net asp.net-web-api routing


【解决方案1】:

如果您看到 source code ,您会注意到值不是字符串的单元测试(例如 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 //值
  • System.String //获取
  • System.String //1

但是

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

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

如果你看到source code of the class

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

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

【讨论】:

    猜你喜欢
    • 2012-12-29
    • 1970-01-01
    • 2021-11-19
    • 2021-05-13
    • 2012-08-25
    • 2011-08-15
    • 2020-03-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多