首页 > 解决方案 > 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;
        }
    }
}

标签: c#asp.netjsonasp.net-web-apiasp.net-core

解决方案


如果您想要全局设置,那么您可以使用扩展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 包中定义。


推荐阅读