c# - ASP.NET Core Web API 自动 JSON 参数反序列化不起作用
问题描述
我有一个简单的控制器,它从 POST 请求正文中获取一个参数。通常它应该自动将它从 JSON 反序列化为对象类型,但它失败了。当我尝试自己反序列化它时,它可以正常工作。这是一些代码:
控制器(documentCommand 变量为空):
public async Task<IActionResult> Create([FromBody]CreateDocumentCommand documentCommand)
{
if (documentCommand == null)
{
return StatusCode(403); //Deserialization fails, documentCommand is null
}
//we have to reach this :(
return Json(documentCommand.Document.Id);
}
这是我如何序列化它以及我如何测试它是否能够反序列化它:
JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto,
NullValueHandling = NullValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Ignore
};
string serialized = JsonConvert.SerializeObject(item, jsonSerializerSettings);
CreateDocumentCommand deserialized = JsonConvert.DeserializeObject<CreateDocumentCommand>(serialized, jsonSerializerSettings);
在我的 CreateDocumentCommand 类中,我有一个接口属性,当我删除TypeNameHandling = TypeNameHandling.Auto时,它在第二个示例中也失败了。
有没有办法告诉 MVC 反序列化器将TypeNameHandling考虑在内?在我看来,它跳过了它。
编辑 更多代码:
public class CreateDocumentCommand : Command, ICreateDocumentCommand
{
public CreateDocumentCommand()
{
}
public IDocument Document { get; set; }
}
我的解决方案:添加了我在 Babak Naffas 提供的链接中找到的 ConcreteTypeConverter 并进行了一些更改,因为我得到了一些循环引用异常。还在CreateDocumentCommand 类之前 添加了[JsonConverter(typeof(ConcreteTypeConverter))] 。
public class ConcreteTypeConverter<T> : JsonConverter
{
static bool read = false;
public override bool CanConvert(Type objectType)
{
return typeof(T).IsAssignableFrom(objectType);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
serializer.TypeNameHandling = TypeNameHandling.Auto;
serializer.NullValueHandling = NullValueHandling.Ignore;
serializer.MissingMemberHandling = MissingMemberHandling.Ignore;
return serializer.Deserialize<T>(reader);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
public override bool CanWrite
{
get
{
return false;
}
}
public override bool CanRead
{
get
{
read = !read;
return read;
}
}
}
解决方案
如果您想要全局设置,那么您可以使用扩展JsonSerializerSetting
在应用程序级别指定。在这里AddJsonOptions
阅读它。
services.AddMvc()
.AddJsonOptions(opt =>
{
if (opt.SerializerSettings != null)
{
opt.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto,
opt.SerializerSettings.NullValueHandling = NullValueHandling.Ignore,
opt.SerializerSettings.MissingMemberHandling = MissingMemberHandling.Ignore
}
});
AddJsonOptions 在Microsoft.AspNetCore.Mvc.Formatters.Json nuget 包中定义。
推荐阅读
- mysql - 在更新触发器mysql之前拒绝插入语句
- swift - 直接访问类变量(使用点符号)还是通过函数?
- javascript - 如何在其中列出 props.data
- python - (python utf-8) 使用 'à','ç','é','è','ê','ë','î','ô','ù'
- javascript - 是否有一种简写方法可以在 javascript 中包装类的组件对象的属性?
- node.js - 在同一网络上的我的本机应用程序上接收电子应用程序的媒体流
- android - 如何取消注册 CarouselView 的 Image Listener 以避免内存泄漏
- javascript - 启用一键式 S3 文件下载,无需 content-disposition 标头或访问元数据
- guidewire - GuideWire 网络服务
- java - LinkedHashSet 不主插入顺序?