首页 > 解决方案 > 具有默认 DotNetCore 活页夹的 JsonExtensionData 属性

问题描述

我正在尝试将带有一些动态字段的 JSON 传递给 DotNetCore 3.1 Web API 项目中的控制器操作方法。我在发送有效负载时使用的类如下所示:

public class MyDynamicJsonPayload
{
    public string Id { get; set; }
    [JsonExtensionData]
    public IDictionary<string, object> CustomProps { get; set; }
}

我可以看到该对象已正确序列化,并在 JSON 主体中添加了道具。所以我将它从一项服务发送到另一项服务:

using var response = await _httpClient.PostAsync($"/createpayload", new StringContent(JsonConvert.SerializeObject(payload), Encoding.UTF8, "application/json"));

但是,在接收端,当在控制器操作中使用相同的类时:

public async Task<ActionResult> CreatePayload([FromBody] MyDynamicJsonPayload payload)
{
    var payload = JsonConvert.SerializeObject(payload);

    return Ok(payload);
}

该对象被解析为不同的东西,其中customProps包含我的属性的 JSON 对象的实际字段,加上而不是简单的值,我得到一个 JSON 对象 {"valueKind":"string"} 例如字符串属性。我尝试了两者Newtonsoft.JsonSystem.Text.Json.Serialization但没有按预期工作。有人有什么想法吗?

标签: c#json.net-corejson.netasp.net-core-webapi

解决方案


感谢 dbc 为我指明了正确的方向,问题是 Newtownsoft 与 System.Text.Json 序列化/反序列化。我无法更改 Startup 类中的序列化程序,因为该服务有许多其他方法,而且我不想破坏现有的合同。但是,我设法编写了一个自定义模型绑定器来解决问题:

public class NewtonsoftModelBinder : IModelBinder
{
    public async Task BindModelAsync(ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
            throw new ArgumentNullException(nameof(bindingContext));

        string body = string.Empty;
        using (var reader = new StreamReader(bindingContext.HttpContext.Request.Body))
        {
            body = await reader.ReadToEndAsync();
        }

        var result = JsonConvert.DeserializeObject(body, bindingContext.ModelType);

        bindingContext.Result = ModelBindingResult.Success(result);
    }
}

和用法:

public async Task<ActionResult> CreatePayload([ModelBinder(typeof(NewtonsoftModelBinder))] MyDynamicJsonPayload payload)
{
// Process payload...
    return Ok();
}

推荐阅读