c# - 使用哪种方法来模型绑定(bind)自定义类型

标签 c# model-binding typeconverter asp.net-core-5.0 jsonconverter

我的 API Controller 有一个如下所示的端点:

public async Task<IActionResult> Update([FromBody] UpdateCommand command) { /* ... */ }

那个command看起来像这样:

public class UpdateCommand {
  public string Username { get; set; }
  public Id Id { get; set; }               // <--- here's the problem
}

那个Id是一个值对象,看起来像这样:

public class Id : SimpleValueObject<long> {
  // base class has: IComparable, equality, GetHashCode, etc.
  public Id(long value) : base(value) { }
  public Id(string value) : base(Parse(value)) { }
  private static long Parse(string value) { /* ... */ }
}

客户端会发送以下内容:

{
  "username": "foo",
  "id": 1
}

现在我希望模型绑定(bind)能够自动工作。但我很困惑如何做到这一点。

我实现了 IModelBinderIModelBinderProvider ,但这没有帮助。然后我注意到文档 say this :

Typically shouldn't be used to convert a string into a custom type, a TypeConverter is usually a better option.

所以我实现了 TypeConverter ,这也没有帮助。

然后我想实现一个JsonConverter<T> ,但该框架现在使用的不是 Newtonsoft,所以我没有走得太远。

所以我的问题是:我必须做什么才能促进自定义类型的自动绑定(bind)。我只需要知道要走哪条路,剩下的我会弄清楚。

(作为一个附带问题:请帮助我了解何时应该实现模型绑定(bind)器、类型转换器和 json 转换器。)

最佳答案

我仍然不明白何时使用自定义模型绑定(bind)器、自定义类型转换器和自定义 json 转换器。

此场景的解决方案似乎是自定义的 JsonConverter<T> .

这对我有用:

public class IdConverter : JsonConverter<Id> {

  public override Id? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) {
    if (reader.TokenType is not JsonTokenType.String and not JsonTokenType.Number)
      throw new JsonException();
    try {
      if (reader.TokenType is JsonTokenType.String) {
        var value = reader.GetString();
        return new Id(value);
      }
      else {
        var value = reader.GetInt64();
        return new Id(value);
      }
    }
    catch {
      throw new JsonException();
    }
  }

  public override void Write(Utf8JsonWriter writer, Id value, JsonSerializerOptions options) =>
    writer.WriteNumberValue(value.Value);

}

关于c# - 使用哪种方法来模型绑定(bind)自定义类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68282576/

相关文章:

c# - 将列表元素转换为字符串

c# - 使用 C# 从 2 个表更新数据库

c# - ASP.NET MVC 传递 DateTime 来查看

asp.net-mvc-4 - ASP.NET Web API - 模型绑定(bind)器

jquery - 如何扩展并添加到 .NET Core 中的 IFormFile 接口(interface)。提交ajax请求时需要向序列化数组追加数据

c# - 将路由和正文中的多个参数绑定(bind)到 ASP.NET Core 中的模型

c# - 自定义本地化 BooleanConverter

c# - 将 64 位数组转换为 Int64 或 ulong C#

c# - 如何从路由中删除 "api"- Azure Functions v3 - host.json routePrefix 空字符串不起作用

c# - 为什么 minValue 是包含的,而 maxValue 是 Random.Next() 独占的?