【问题标题】:WebAPI: Deserialize URI parameter to poco action parameterWebAPI:将 URI 参数反序列化为 poco 操作参数
【发布时间】:2012-03-21 09:55:55
【问题描述】:

给定这样的路由定义:

        routes.MapHttpRoute(
            name: "Categories",
            routeTemplate: "{controller}/Categories/{entity}/{property}",
            defaults: new { action = "Categories", entity = RouteParameter.Optional, property = "Name" }
        );

还有一个这样声明的控制器动作:

public IEnumerable<Category> Categories(string property);
public IEnumerable<Category> Categories(string entity, string property);

意图是控制器代表一个特定的实体,它可以聚合其他实体。返回的 Categories 包含 groupby 和 count 属性。因此,如果控制器是 UserController 并且用户实体具有 Name 属性,您可以调用 User/Categories/Name 并获得显示不同名称的结果以及每个名称有多少个。

如果一个用户也有一个地址实体,并且它有一个邮政编码,我可以调用User/Categories/Address/ZipCode 并期望结果显示有多少用户住在哪个邮政编码。

这里的问题是string entity 参数是string 类型而不是Type 类型,所以我必须用代码弄脏我的操作,将其转换为表示实体的Type 实例,并抛出 if这是一个不正确的字符串。

我想要的是像这样声明我的第二个动作:

public IEnumerable<Category> Categories(Type entity, string property);

但是我需要使用自定义反序列化器反序列化字符串。我已经有自定义反序列化器又名MediaTypeFormatters,用于处理来自内容主体的内容。我的问题是,在这种情况下,源是 URI 参数而不是内容主体。

这导致了我的问题:

  1. MediaTypeFormatter 是否也适用于 URI 参数?
  2. 如果不是,我必须实现什么构造并连接如何实现我想要的?

【问题讨论】:

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


    【解决方案1】:

    几件事:

    1. 用户/类别/名称不会将“名称”映射到 {property},它会将“名称”匹配到 {entity}。路线从左到右“贪婪地”匹配。

    2. 您可以使用枚举来代替实体字符串

      public enum EntityType
      {
          Address,
          Department
      }
      
      public class UserController : ApiController
      {
          public IEnumerable<Category> Categories(EntityType entity, string property)
          {
          }
      }
      

      您仍然需要代码来处理实体类型,但这似乎比让客户端向您发送随机 CLR 类型名称更安全?然后模型绑定将验证 URI 中的 {entity} 段。因此,如果客户端请求 User/Categories/FavoriteBeer,他们将得到 400,Bad Request。

    3. 媒体类型格式化程序专门用于序列化/反序列化消息正文。 (格式化程序映射到媒体类型,媒体类型描述实体主体。)

      媒体类型的格式化程序确实可以通过 FormatterContext 对象访问请求 URI,但它对这种情况没有帮助,因为没有消息正文的 GET 请求不会调用格式化程序。

    【讨论】:

    • 1.我的印象是,路线不是按顺序映射,而是按参数名称映射,如果我只提供 2 个参数中的 1 个,那么可选的参数当然是不匹配的。 2. 然后我每次添加另一种实体时都必须更新枚举,而不是让它自动只适用于新类型。然后我宁愿接受太多的字符串并在我无法映射类型时给出 400。 3. 是的,我也是这么认为的。所以我不能使用那个构造。但是我可以使用什么构造?
    猜你喜欢
    • 2012-10-21
    • 2013-01-30
    • 2020-07-11
    • 2021-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-31
    • 1970-01-01
    相关资源
    最近更新 更多