Web API ModelBinders - 如何以不同方式绑定对象的一个​​属性

2023-11-21

我有以下操作签名

    [ValidateInput(false)]
    public HttpResponseMessage PostParam(Param param)

Param 看起来像这样:

public class Param {
  public int Id { get; set;}
  public string Name { get; set; }
  public string Choices { get; set; }
}

这就是问题所在 - 通过电线传输的内容是这样的

{
  Id: 2,
  Name: "blah",
  Choices: [
    {
      foo: "bar"
    },
    {
      blah: "blo"
      something: 123
    }
  ]
}

我不希望“选择”反序列化 - 我希望将其存储为字符串(是的,我了解安全隐患)。可以理解的是,我收到一个错误,因为默认的活页夹不知道这一点。

现在,使用 Asp Mvc 创建特定的 ModelBinder 将相当简单。 ID

  • 继承DefaultModelBinder
  • 用我自己的重写属性反序列化
  • 将活页夹设置在我的Application_Start using Binders.Add

似乎对于 Web Api 这是一个不同的过程 - System.Web.DefaultModelBinder 没有任何可以覆盖的内容,并且我无法使用Binders.Add。我尝试环顾四周,但找不到太多关于如何真正做我想做的事情的信息。这更加复杂,因为显然 ModelBinders api 相对于 Beta 和 RTM 发生了很大的变化,因此有很多过时的信息。


在 Web API 中你必须区分三个概念 -ModelBinding, Formatters and ParameterBinding。这对于从 MVC 迁移到/习惯于 MVC 的人来说非常令人困惑,我们只讨论ModelBinding.

ModelBinding与 MVC 相反,它只负责从 URI 中提取数据。格式化程序负责读取正文,并且ParameterBinding (HttpParameterBinding) 包含前两个概念。

ParameterBinding仅当您想要彻底改变整个机制时(即允许从正文绑定两个对象,实现 MVC 样式绑定等),真正有用 - 对于更简单的任务,修改绑定器(对于 URI 特定数据)或格式化程序(对于正文数据) )几乎总是绰绰有余。

无论如何,重点是 - 您想要实现的目标可以很容易地通过自定义来完成JSON.NET转换器(JSON.NET 是 Web API JSON 格式化引擎背后的默认序列化库)。

您需要做的就是:

public class Param
{
    public int Id { get; set; }
    public string Name { get; set; }

    [JsonConverter(typeof(CustomArrayConverter))]
    public string Choices { get; set; }
}

然后添加转换器:

internal class CustomArrayConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return true;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
                                    JsonSerializer serializer)
    {
        var array = JArray.Load(reader);
        return JsonConvert.SerializeObject(array);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, JArray.Parse(value as string));
    }
}

在本例中,我们告诉转换器中的 JSON.NET 来存储Choices as string(在 read 方法中),当您返回Param对象与Choices属性给客户端(在 write 方法中)我们采取string并序列化为array这样输出 JSON 看起来与输入完全相同。

您现在可以像这样测试它:

    public Param PostParam(Param param)
    {
        return param;
    }

并验证传入的数据是否如您所愿,并且输出的数据是否与原始 JSON 相同。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Web API ModelBinders - 如何以不同方式绑定对象的一个​​属性 的相关文章

随机推荐

  • 软件包“Tk”的版本冲突:有 8.5.2,需要 8.5.15

    我正在尝试编译一个程序 python2 7 但无论我做什么 我都会收到此错误 C Python27 tcl tk8 5 tk tcl version conflict for package Tk have 8 5 2 need exact
  • 如何从 @Html.EditForModel() 中排除字段,但使用 Html.DisplayForModel() 显示该字段

    我正在阅读 ASP NET MVC 及其所有有趣的用途 我刚刚发现数据模板 为了急于测试这个东西 我将一个更简单的模型转换为使用 Html DisplayForModel and Html EditForModel 它就像一个幸运符 它是
  • 以秒为单位的反应日期选择器时间选择

    我还需要从反应日期选择器中选择秒 我浏览过文档发现了这个 在此解决方案中 我可以从中选择小时 分钟 上午 下午 但没有秒选项 有什么方法可以自定义也从中选择秒 需要帮助 如下例 查找输入时间 我尝试过更改日期格式 dateFormat MM
  • 如何在 Swift 的 Xcode 6 的 Storyboard 中成功添加图像?

    我对 Xcode 非常陌生 2 天 到目前为止我发现它相当令人沮丧 我只是想通过 Storyboard 将图像添加到我的应用程序的 ViewController 但它不会出现在模拟器上 有人可以帮助我吗 如果您正在尝试 XCode 的示例项
  • 彩色输出打破了 readline 的换行

    我正在使用 Ruby 中的 readline 对一些输出进行着色 但我没有运气让换行正常工作 例如 e 01 32mThis prompt is green and bold e 00m gt 期望的结果是 This prompt is g
  • 使用 csv 和 quantmod 加载多个符号

    我正在尝试使用 csv 文件加载多个符号 而不是从雅虎下载 原始代码运行良好并且使用 load packages quantmod tickers spl TLT IWM GLD data lt new env getSymbols tic
  • MySQL - 从多个具有相同结构但不同数据的表中选择数据

    好吧 这是我的困境 我有一个数据库 其中设置了大约 5 个表 所有表都具有完全相同的数据结构 以这种方式分离数据是为了本地化目的 并划分总共约 450 万条记录 大多数时候只需要一张桌子 一切都很好 但是 有时需要来自 2 个或更多表的数据
  • Node.js NODE_PATH 环境变量

    在开发过程中我曾经WebStorm node path 环境变量 我在项目设置的启动中设置了一个变量 现在我想尝试在服务器上运行该项目 但不知道如何在那里设置这个变量 帮忙解决问题 假设它是 UNIX 或 Mac OS X 服务器 请使用e
  • 无法从 Moto 360 读取心率传感器 - Android Wear

    有人成功读取 Moto 360 的心率传感器吗 mSensorManager SensorManager getSystemService SENSOR SERVICE mHeartRateSensor mSensorManager get
  • NSNotificationCenter 和安全多线程

    鉴于即使方法调用正在进行中 对象也可能被释放 link 对象注册并接收将在与其预期释放的线程不同的线程上传递的通知是否安全 作为参考 文档指出 在多线程应用程序中 通知始终在发布通知的线程中传递 该线程可能与观察者注册自身的线程不同 同样重
  • 空间局部性与时间局部性

    我理解这些术语的定义 但我无法将它们的概念应用到代码中 在练习中 我们需要描述以下代码是空间代码还是时间代码 for int i 0 i lt 10 i printf some array i 我觉得这是空间局部性 因为当访问数组的一个索引
  • Spring Boot 2 禁用具有多个数据源的自动提交 Hikari

    我正在尝试关闭 Hikari 上具有多个数据源的自动提交 但我没有任何运气 我正在使用 Spring Boot 2 2 0 3 RELEASE 这是我的配置 应用程序属性 spring datasource primary driver c
  • 如何在 Laravel 中过滤多对多结构

    我有多对多的用户和角色结构 users id name roles id name 角色 用户 user id role id Model User php public function roles return this gt belo
  • jq 是否已安装并在 PATH 上可用?

    我正在尝试读取 gitlab CI 中的 yaml 文件 我安装了jq 1 0 2 and yq 2 10 1 using pip在我的 CI 工作中 我使用 python 3 7 图像 当我尝试读取 yaml 文件时 出现错误 yq Er
  • 如何为 S3 对象创建 java OutputStream 并向其写入值?

    使用 AmazonS3 类中的方法将内容添加到 S3 文件的现有方法有 通过带有输入流的 putObject 创建包含内容的本地文件并将其上传到 S3 有没有办法为现有的 S3 对象创建一个 OutputStream 可以将列表中的值写入其
  • 当 SCREEN_ON 接收器被触发时,如何禁用键盘防护并向用户显示活动?

    当 screen on 激活广播接收器时 如何禁用键盘保护 以便当它发生时用户可以看到我在其后面启动的活动 活动已经开始 我一直在尝试从屏幕关闭触发的广播接收器中执行以下代码 KeyguardManager myKeyGuard Keygu
  • .NET 正则表达式中的 \d 与 [0-9] [重复]

    这个问题在这里已经有答案了 我经常看到 0 9 用于 Stack Overflow 上的 NET 正则表达式答案 而不是 d 我问过为什么 答案往往是 d匹配的不仅仅是 0 9 那么它还匹配什么呢 这张表说它匹配十进制数字 那么呢 p Nd
  • Maven 安装插件:参数文件丢失或无效

    我有一个本地 jar 我想在我的项目中使用它 有很多方法可以做到这一点 只需手动安装到本地存储库中 使用父 pom 中的脚本进行安装 使用系统范围 使用本地存储库声明 我决定使用 Maven Install 插件将 jar 安装到存储库中
  • gcc 编译标志

    谁能解释一下为什么我们在 gcc 中使用 m 标志 我运行 man gcc 命令结果很不清楚 任何人都可以解释一下这个标志在编译中的作用吗 如何使用 m 标记其正确的语法 我需要它 因为我正在通过 make 命令运行自动生成的 makefi
  • Web API ModelBinders - 如何以不同方式绑定对象的一个​​属性

    我有以下操作签名 ValidateInput false public HttpResponseMessage PostParam Param param Param 看起来像这样 public class Param public int