c# - 具有默认 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.Json
,System.Text.Json.Serialization
但没有按预期工作。有人有什么想法吗?
解决方案
感谢 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();
}