繁体   English   中英

如何为来自正文的模型上的属性提供自定义模型绑定器?

[英]How do I provide a custom model binder for a property on a model from body?

我在为ASP.NET Core 2.1 Web API服务编写自定义模型绑定器时遇到问题。 我有一个像下面这样的动作方法

public async Task<IActionResult> SaveAccountEvents([FromRoute] Guid accountId, IList<AccountEvent> events)
{
}

AccountEvent类有许多属性,包括

[BindProperty(BinderType = typeof(CustomBinding))]
public string EventBody { get; set; }

目的是我希望来自客户端的此属性的值是字符串或JObject(JSON)。 我们的想法是客户端可以在EventBody中发送字符串化的JSON或JSON,模型会将其存储为字符串 - 最终为字符串化的JSON。

bindingContext.ValueProvider.GetValue的问题是在我的自定义绑定中, bindingContext.ValueProvider.GetValue永远不会返回任何内容。 查看属性,它只包含RouteValueProvider 我没有看到任何可以从身体中获取价值的方式。 是否有其他方法可以在ASP.NET Core Web API中自定义JSON反序列化?

更新:

客户端使用此API发送事件数据。 事件数据包含一个信封,其中包含事件名称,发送日期,发起事件的用户等信息。在当前版本中,实际事件数据以字符串化JSON格式发送。 所以现在,请求看起来像(通知事件正文是一个字符串):

{
  "eventDate": "20180909",
  "eventBody": "{
      \"newLastName\": \"bob\",
      \"primaryApplication\": \"bob\"
    }"
}

改变是我希望能够接受事件体作为JSON。 在这种情况下,客户端应该能够发送(注意事件正文是正确的JSON):

{
  "eventDate": "20180909",
  "eventBody": {
    "newLastName": "bob",
    "primaryApplication": "bob"
  }
}

需要支持这两种方案,现有API是字符串版本。 我要做的是配置API,以便如果发送的事件是JSON对象,它将在到达Action的模型中进行字符串化。

感谢Kirk指向解决方案的指针。 我最终完全跳过了模型绑定(是的!)并且能够使用属性上的属性自定义序列化器来实现我所需要的: [JsonConverter(typeof(EventBodyJsonConverter))] 有了这个,我可以在Action中使用[FromBody]来获取内容感知绑定。

public class EventBodyJsonConverter : JsonConverter
{
    private JsonSerializer _jsonSerializer;

    public EventBodyJsonConverter()
    {
        _jsonSerializer = new JsonSerializer();
    }

    public override bool CanConvert(Type objectType) => objectType == typeof(string);

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.StartObject)
        {
            var eventJObject = _jsonSerializer.Deserialize<JObject>(reader);
            return eventJObject.ToString();
        }

        if (reader.TokenType == JsonToken.String)
        {
            return reader.Value.ToString();
        }

        throw new Exception();
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {

    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM