在ASP.NET Core 2控制器上编写自定义JsonConverter以从POST反序列化JSON

Jam*_*son 5 c# json metadata deserialization asp.net-core-2.0

我需要在ASP.NET MVC Core 2项目中编写一个自定义JsonConverter,以将jQuery POST主体中的JSON数据反序列化,因为它是默认模型绑定。这里最困难的部分是我需要在其中包含多态类型数组的基本类型数组的对象上使用TypeNameHandling。我可以用

[JsonProperty(ItemTypeNameHandling = TypeNameHandling.Auto)]
Run Code Online (Sandbox Code Playgroud)

但是围绕此问题的安全性问题对于我的项目是不可接受的。我已经编写了一个自定义JSON转换器,并用以下内容标记了我的对象,但是它似乎没有使用我的自定义转换器(未命中断点)。

[JsonConverter(typeof(ApplicationLoggingConverter))]
Run Code Online (Sandbox Code Playgroud)

完整的相关代码如下。我的ApplicationLoggingModel:

public class ApplicationLoggingModel
{
    public Guid ApplicationId { get; set; }

    [JsonConverter(typeof(ApplicationLoggingConverter))]
    public ModelActionBase[] Changes { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

控制器动作:

[HttpPost("Save/{id}")]
    public async Task<ActionResult> Save(Guid id, [FromBody]ApplicationLoggingModel model)
    {
        model.ApplicationId = id;
        //nothing yet implemented
        return Ok();
    }
Run Code Online (Sandbox Code Playgroud)

自定义转换器:

public class ApplicationLoggingConverter : JsonConverter
{
    private readonly Type[] _types;

    public ApplicationLoggingConverter(params Type[] types)
    {
        _types = types;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.StartArray)
        {
            return serializer.Deserialize<ApplicationLoggingModel[]>(reader);
        }
        else
        {
            var myObject = serializer.Deserialize<ApplicationLoggingModel>(reader);
            return new ApplicationLoggingModel[] { myObject };
        }
    }

    public override bool CanConvert(Type objectType)
    {
        return _types.Any(t => t == objectType);
    }
}
Run Code Online (Sandbox Code Playgroud)

在启动时:

services.AddMvc().AddJsonOptions(options => { options.SerializerSettings.Converters.Add(new ApplicationLoggingConverter()); });
Run Code Online (Sandbox Code Playgroud)

...以及我要发布的JSON数据:

"$type": "Project.Web.Areas.Admin.Models.ApplicationLoggingModel, Project.Web",
"Changes": [{
    "$type": "Project.Generation.Common.Actions.EntityAction, Project.Services.Generation.Common",
    "Action": 0,
    "ItemName": "Entity",
    "PropertyName": "Name",
    "OldValue": "",
    "NewValue": "newEntity",
    "Scope": {

    }
}]
Run Code Online (Sandbox Code Playgroud)

我对ASP Core 2模型绑定上的自定义反序列化还很陌生,并且关于它的文档非常少(除非我正在谷歌搜索/研究错误的东西),但看来我在“公共替代对象ReadJson”中的断点至少应该是击中。出于安全原因,我已经更改了JSON中的项目名称,并且当我设置TypeNameHandling.Auto可以工作时,我在做什么错?让我知道您是否需要更多信息/代码。